Maybe the answer to the following is simple, but I have hard time finding the answer:
When I have a GET method in a controller that is secured with the [Authorize] attribute, and a POST method (defined with [HttpPost]), will the same restrictions apply to it as well? Both methods have the same name, but differ in parameters.
Example code:
[Authorize(Roles = "Administrator")]
public ActionResult Delete()
{
return View();
}
[HttpPost]
public ActionResult Delete(int id)
{
/* the method's logic omitted */
return RedirectToAction("Index");
}
No, the controller considers these two separate actions (since that's what they are), and as such, don't share restrictions.
Related
I understand ActionResult is the base class for RedirectResult class so essentially functionality for the code below is the same.
Is there an advantage to explicitly specify the appropriate result class as a return type as opposed to the base class?
public ActionResult Index()
{
return Redirect("Home/Contact");
}
public RedirectResult Index()
{
return Redirect("Home/Contact");
}
if you need redirect quickly to another action without lost any data and this action is in the same controller , call the action as a method:
public IActionResult Index()
{
return Contact();
}
public IActionResult Contact()
{
....
}
which one from another redirections methods is better is an opinion-based question and is not allowed by SO policy
If I register a global Authorize attribute in FilterConfig.cs so that each action method can only be accessible to authenticated users, and decorate some controllers with [Authorize(Role="Admin")] so that only admin users can access them, does authorization logic run twice on these controllers? What can I do to prevent that?
You can use an ASP.NET MVC "FilterProvider" provider. What this will do is help you to fetch all relevant filters from a specific controller and action.
So you can define your own provider and register that one instead of the default ones. this will give you full control over the asp.net filters and you can remove some filters based on your requirement.
Lets say we have following Controller.
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Whatever()
{
return View();
}
}
I think you are looking a way to do something as follows. concentrate on Index Action
[Authorize]
public class HomeController : Controller
{
[ExcludeFilter(typeof(AuthorizeAttribute))] // Excluding Authorize Important !
public ActionResult Index()
{
return View();
}
public ActionResult Admin() // will follow the declared authorize Attribute
{
return View();
}
}
If thats what you are Looking for then see this Article
I can change the method name but can anyone tell me why this doesn't work? How can i make it working without changing method name. Also I don't want to specify the action name in the view. Is it possible?
[HttpGet]
[Route("AddUpdateCategories/{storeId}")]
public ActionResult AddUpdateStoreCategories(int storeId)
{
return View();
}
[HttpPost]
public ActionResult AddUpdateStoreCategories(int StoreId,int[] ShopCategoryId)
{
return null;
}
Problem is post action is not getting called on submit.
You don't have to change the method name. The problem is that this post action has no route. If you use attribute routing, you have to specify a route for each action. Both of these actions would end up with the same route attribute, but the [HttpPost] attribute is enough for the routing framework to work out which one to use.
[Route("AddUpdateCategories/{storeId}")]
public ActionResult AddUpdateStoreCategories(int storeId)
{
return View();
}
[HttpPost]
[Route("AddUpdateCategories/{storeId}")]
public ActionResult AddUpdateStoreCategories(int StoreId,int[] ShopCategoryId)
{
return null;
}
PUT and POST do a very similar thing in REST. The assumption being a POST means create a new entry and PUT means update an existing entry.
I had always assumed you could only have a single routing attribute on a controller action method, but now I have a situation where I want a method to respond to either HttpPost or HttpPut.
Update:
Tried a few variations and the actions were not hit if more than one routing attribute was applied. Like these:
[HttpPost]
[HttpPut]
public ActionResult Include(int id, int order, int parent)
{
return "...some result";
}
[HttpPost, HttpPut]
public ActionResult Include(int id, int order, int parent)
{
return "...some result";
}
The question now is: How do you respond to both PUT and POST requests in the same controller action?
There's builtin way to do that. Use AcceptVerbsAttribute
[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Put)]
public ActionResult Include()
{
}
I have two actions, one that accepts a ViewModel and one that accepts two parameters a string and an int, when I try to post to the action, it gives me an error telling me that the current request is ambiguous between the two actions.
Is it possible to indicate to the routing system which action is the relevant one, and if it is how is it done?
You can decorate it with HttpGet HttpPost
Look under "Overriding the HTTP Method Verb"
http://www.asp.net/learn/whitepapers/what-is-new-in-aspnet-mvc
You can also use the ActionName attribute. Look under "ActionNameAttribute"
http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx
You can't overload controller actions, though as Raj said, you can differentiate them by allowing them to respond to different requests (get, post, etc).
You might also find this helpful: How a Method Becomes An Action.
This is how it's done
A simplified example:
[HttpGet] // this attribute is't necessary when there are only 2 actions with the same name
public ActionResult Update(int id)
{
return View(new Repository().GetProduct(id));
}
[HttpPost]
public ActionResult Update(int id, Product product)
{
// handle POST data
var repo = new Repository();
repo.UpdateProduct(product);
return RedirectToAction("List");
}
And if you'd need two actions that would have completely same signature (same name and exactly the same number of parameters of the same type) in that case you would have to use another attribute like this:
public ActionResult SomeAction(int id)
{
return View(new Repository().GetSomething(id));
}
[HttpPost]
[ActionName("SomeAction")]
public ActionResult SomeActionPost(int id)
{
// handle POST data
var repo = new Repository();
repo.UpdateTimestamp(id);
return View(repo.GetSomething(id));
}