I am programming an WebApp with MVC5 and I will check if a User is in a specified Role.
Therefore I have tried to use User.IsInRole("Role") but it throws an Exception.
I have tried with importing AspNet.Identity and using the User Manager but it can not find the method IsInRoleAsync(userId, role):
#using Microsoft.AspNet;
#if(UserManager.IsInRoleAsync(user.Id, "Role")){
// some code
}
Please notice that I use it in a cshtml file and razor syntax. I hope you can help me.
Thank you in advance
Hi you can easily do in view with the following code:
Ex: view1.cshtml
#if (Request.IsAuthenticated && User.IsInRole("Administrators"))
{
//Any code
}
The code UserManager.IsInRoleAsync does not just work inside a Razor view (cshtml). You would have to instantiate an ApplicationUserManager instance, typically called "UserManager" as well as have a valid ApplicationUser ("user") object.
You are better off to do this work in the controller and pass it to the view with a View Model or other means like ViewBag or ViewData.
Related
I am creating a multipage forms application. I'd like to use Validator interface to validate the content provided by the user.
The question: Is this https://mkyong.com/spring-mvc/spring-mvc-handling-multipage-forms-with-abstractwizardformcontroller/ approach still valid in terms of Spring MVC 5.2.*?
Ofc, we should forget about AbstractWizardFormController for a moment.
And answering on my own question:
You do not have to do it. Normally validator will catch errors before the page was switched. Basically, one needs to implement validator as told here https://docs.spring.io/spring/docs/5.2.6.RELEASE/spring-framework-reference/core.html#validator. Then bind it to the controller with
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.setValidator(<validaotrs_variable_name>);
}
And then use #Validated on #ModelAttribute("myobjectnameintemplate") MyPojo myPojo.
That is it.
If the one wants to validate page at a time, then I think it is necessary to run validation methods separately. For this I found a number of answers on stackoverflow:
One can use #Valid and validation groups (Hibernate)
Simple switch case in validate() based on the current page or something else
Nested objects in one object that is being populated, and multiple validators as described here https://docs.spring.io/spring/docs/5.2.6.RELEASE/spring-framework-reference/core.html#validator
I am trying to change the view that on of my controllers points to however this is not picking up the amendment. The following is the code I am trying to use;
// GET: UserDemographics/Create
public ActionResult Create()
{
return View("Manage");
}
And my views folders look like below:
My understanding is that View tries to check for the same name as the method but I may be wrong. Any help would be appreciated.
Nothing wrong in your code. This should work perfectly
Your URL should be like this,
localhost:[Port Number]/userdemographics/Create
If you already hosted your project in a real domain, then you can replace localhost:[Port Number] with your domain name. For example,
www.example.com/userdemographics/Create
The view name specified within the View() method does not alter the path in the URL when making a request, it simply changes the name of the view that is rendered as a result of the request.
If you want the path to your action to be /UserDemographics/Manage, you would need to change the name of your Action method to Manage.
public class UserDemographics : Controller
{
// Requested by /UserDemographics/Manage in the browser
public ActionResult Manage()
{
// You don't HAVE to specify the view name here, Manage.cshtml will be rendered based on the convention.
// However as mentioned this is best practice to specify the name.
return View("Manage");
}
}
This makes it so that there is no longer a need to specify the View name as it will be automatically selected from the Views folder by convention for that controller.
So somebody asked me the question:
When would I return View() and when would I return PartialView()?
My immdiate reaction was, if it's a patial use PartialView(). Then I realised that I have quite often returned View() for a partial view with no, apparent, detremental effects?! So what's the point in the return PartialView() call?
I found this question What's the difference between “return View()” and “return PartialView()”. This appears to be particular to MVC2. i.e. talks about .aspx and .ascx control extensions. Using Razor all our views are .cshtml whether they are partial or not.
Which got my thinking is the PartialView() just a hangover from MVC2 and not really relevant in MVC3+ (When using Razor anyway)? Or am I missing some crucial feature of PartialView()?
tl;dr: PartialView() does not use a layout for the view being returned.
You can set a default layout file within _ViewStart.cshtml (located in the Views folder) which will then be used by all views. By doing that, you avoid having to set the Layout property within each view. PartialView() will not include that layout file or any other.
If you want to return a partial view, e.g. in a child action called using #Html.Action(action, controller), use PartialView. If you want to return a "full" view including the layout, use View().
MSDN Reference:
If you contrast the MSDN definition for ViewResult() Object with the MSDN definition for PartialViewResult() Object
you find the only difference is that ViewResult has an extra property:
public string MasterName { get; set; }
Otherwise, both Objects inherit from ViewResultBase and seem to inherit all other properties and methods from the base class.
Unfortunately, the implementation of the abstract method ExecuteResult() is not published, but I have no doubt it uses the MasterName field to find and render the Master Layer.
Our shared experience:
Just like you, I have returned partial views =using View(). I don't recommend it. But the apparent difference isn't big.
It does seem a touch wasteful to have an extra object just for MasterName, but the more important difference is probably the implementation of ExecuteResult().
When you choose View() method and create a ViewResult Object rather than using PartialView() to create a PartialViewResult Object, you are being less efficient; your application is doing the extra work of checking if your MasterName field is assigned.
I am new to asp.net mvc4 and there is something i don't understand well.
Why do I have to declare the Model using #model at top of the view, if I already pass an object to the View in the controller.
Taking an example :
Controller:
public ActionResult countryDetails(int id)
{
Country country = db.Country.Find(id);
return View(country);
}
View:
#model MvcApplication2.Models.Country
#{
ViewBag.Title = "countryDetails";
}
...
The controller returns a View with an object as parameter, so the model should be already known. I'm sorry if it is obvious, but I can't figure out why this is not a "double" declaration.
Thanks for you help !
The declaration at the top will do two things for you:
It will allow intellisence to know what type you are using when you type in #Model or use any of the Html helper extensions.
It will also check at runtime that model passed in can be cast to the type the view expects.
Its not necessarily a "double declaration" as it is analogous to specifying a type to a parameter on a method. Like so
Person Someone = new Person();
RenderView(Someone);
...
void RenderView(Person model) { }
By default your view inherits from System.Web.Mvc.WebViewPage<TModel>
You can optionally override this class, it's default ASP.NET inheritance mechanism:
#inherits System.Web.Mvc.WebViewPage<List<CompanyName.MyProduct.MyCategory>>
Or you can just simplify this since MVC3 like this:
#model List<CompanyName.MyProduct.MyCategory>
This sugar syntax was made to simplify code typing.
This declaration give you some things
View automatically cast object to the preferred type
You receive type-defined 'model' property which allows you to access
to your object methods and properties
Just believe that this is a method which accepts object and cast it to the specified type that you provide
The main reason is type-safety, it allows you to work with strongly typed views with the benefit of intellisense, compiler error hints, invalid casting etc.
Also, another reason is for readability - it acts as a reminder to what sort of model it is you are actually dealing with instead of having to keep referring back to the controller.
I'm attempting to create a generic controller, ie:
public class MyController<T> : Controller where T : SomeType
{ ... }
However, when I try to use it, I'm running into this error everywhere...
Controller name must end in 'Controller'
So, my question, Is it possible to make a generic controller in asp.net mvc?
Thanks!
If I understand you properly, what you are trying to do, is route all requests for a given Model through a generic controller of type T.
You would like the T to vary based on the Model requested.
You would like /Product/Index to trigger MyController<Product>.Index()
This can be accomplished by writing your own IControllerFactory and implementing the CreateController method like this:
public IController CreateController(RequestContext requestContext, string controllerName)
{
Type controllerType = Type.GetType("MyController")
.MakeGenericType(Type.GetType(controllerName));
return Activator.CreateInstance(controllerType) as IController;
}
Yes you can, it's fine and I've used them lots myself.
What you need to ensure is that when you inherit from MyController you still end the type name with controller:
public class FooController : MyController<Foo>
{
...
}
The default controller factory uses "convention" around controller names when it's trying to find a controller to dispatch the request to. You could override this lookup functionality if you wanted, which could then allow your generic controller to work.
This MSDN article...
http://msdn.microsoft.com/en-us/magazine/dd695917.aspx
... has a good writeup of what's going on.
This is a duplicate of asp.net mvc generic controller which actually contains the correct answer. Jeff Fritz's answer is absolutely not correct. Creating your own IControllerFactory will not get past the limitation in ExpressionHelper.GetRouteValuesFromExpression which is generating the error you are seeing. Implementing your own IControllerFactory will still leave you with errors whenever you call RedirectToAction, BuildUrlFromExpression, ActionLink, RenderAction, BeginForm, any any methods that call those.
What is interesting to me, is that Microsoft's "restriction by convention" is already enforced by the constraint "where TController : Controller" that is placed upon the type in the ExpressionHelper.GetRouteValuesFromExpression method. No generic will ever satisfy the convention validation:
string controllerName = typeof(TController).Name;
if (!controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) {
throw new ArgumentException(MvcResources.ExpressionHelper_TargetMustEndInController, "action");
}
unless it is inherited by a class ending in "Controller" because typeof(AnyGeneric).Name will never end with "Controller".
If i was you, i'd get the MVC source and create a test MVC project with the source code so you can examine where the exception is generated and see what you can do about your generic idea and the enforced "*controller" naming convention.