No HTTP requests for certain controller methods - asp.net-mvc

I'm currently reading a book about ASP.NET MVC3 to learn working with this framework. The concept of partial views is explained and altough it's an easy concept, I have a small question with it.
This razor code is added to the view:
#{ Html.RenderAction("Summary", "Cart"); }
This calls the Summary()-method on the CartController. The problem is: as a user, I can call this method via a HTTP request (GET/POST,...) what shouldn't be possible.
I know there are attributes like [HttpPost] and [HttpGet] to permit only certain sorts of HTTP requests, but is there also an attribute to prevent these? Also, where can I find a list of available attributes?
Thanks

If you have a partial view, you are right that it has to be a public method but it should not be addressable on its own. to achive this you can decorate the action method with the [ChildActionOnly]
See this for details
http://msdn.microsoft.com/en-us/library/system.web.mvc.childactiononlyattribute.aspx
And for a list of similar attributes:
http://msdn.microsoft.com/en-us/library/system.web.mvc.filterattribute.aspx

Related

Why shouldn't I use attribute routing in a traditional (non API) controller?

I've been using attribute based routing in an API controller project:
[HttpGet("products/{productId}")]
public async Task<IActionResult> ProductDetails(int productId) {
...
return Ok(someModelToSerializeAsJson)
}
This works great. I find it much clearer and less error prone than conventional route table based routing. I kept wondering why we can't use attribute based routing for MVC (non API) projects with views. I tried this for a small non public facing web application and it seems to work great. You have to mark the controllers as [ApiController], but you can still return views in the action methods.
[HttpGet("products/{productId}")]
public async Task<IActionResult> ProductDetails(int productId) {
...
return View(someModelForTheView)
}
I would like to make the same choice for our main public facing website, but I'm worried I'm missing a solid reason why I shouldn't.
As an example, I've noticed that API controllers aggressively turn off HTTP caching (e.g. cache-control: no-cache, no-store). That is a quirky issue to work around.
Are there other clear reasons to NOT use attribute based routing with MVC views?
Looks like I was wrong. You can use attribute based routing for regular MVC controllers. I thought you had to use an ApiController, but that is not correct. The trick for me was that the base class for my controller needed to be Controller instead of BaseController. Shout out to #Métoule for that nugget of information.

MVC what are some practical examples when one needs to use ChildActionOnly attribute

I have just started learning MVC and I am aware of the fact that when an action has the [ChildActionOnly] attribute, it cannot be invoked from the browser as a GET request and can only be accessed from a View.
Looking for some practical use cases where [ChildActionOnly] attribute can be used.
Linked to : Using ChildActionOnly in MVC
After reading up on this topic, I could find a good example where [ChildOnlyAction] attribute can be used.
Scenario: When one needs to display a partial view in the header/footer section of the layout page and this partial view needs to be passed a model.
Solution: Call a [ChildActionOnly] from the layout page using "#Html.Action()" which would return the partial view. In this action , one can easily pass on any model that is required by the partial view.

Best way to add filter to URL in .NET MVC

I'll try to make this as concise as possible.
Webpage contains a table that allows for filtering and sorting
Changes to filtering and sorting should be reflected in the URL so the user can bookmark or share filtered views.
The question is: What is an effective convention of allowing all of the sort and filter syntax to be part of the URL and easily interpret/use it on the server without having to write a bunch of custom code that interprets it?
I've been doing some research and I came across the OData URI conventions and I like the way they do things.
http://www.odata.org/developers/protocols/uri-conventions
More research shows the the MVC 4 Web API allows for use of that convention by returning an IQueryable. This looks fantastic except for one part... I'm not implementing a RESTful API at this point and that's all it seems to work with. So how can I use something like OData and still return a View or PartialView? Is there something that will parse the OData URI convention into a C# object?
If anyone has any insights into this problem or suggestions, I'm all ears.
As for the url convention part of your question, I think you have answered your own question with OData. As for getting this data into a C# object I would use the following approach:
Use an action filter to interperet the url parameters and parse them into a c# object.
In your action filter add the url parameters to the route data and the c# object will be available in your action.
ASP.NET MVC Pass object from Custom Action Filter to Action
Take a look at the Telerik MVC grid, they use a GridAction action filter that does pretty much what you are asking.
I would look at custom model binding. A good overview can be found here: http://weblogs.asp.net/nmarun/archive/2010/02/25/asp-net-mvc-model-binding.aspx
It's typically used for POST requests with forms but there's no reason why you can't use it for GET requests too.
Basically, your approach should be to:
Create a new Model class with your filter/sorting parameters as properties:
public class TableParameters {
public string TableFilter { get; set; }
}
In your Controller's Action, add the model as a parameter
public ActionResult TableAction(TableParameters parameters) { /* Action logic */ }
Set your parameters in the URL by saying:
/Controller/TableAction?TableFilter=[your-filter-string]
The parameters object in your action will have the property populated with the value from the query string.

Overloading of public functions in Controller

I am new to MVC. I was going through the asp.net site and found this link where it stated that public methods (actions) cannot be overloaded in controller classes. However in the site it stated that it can be only be possible if i use [AcceptVerbs(HttpVerbs.Post)] with one function.
Can you please explain how does AcceptVerbs helps in overloading the function.What it actually does behind the scene?
And in one of my sample application i am able to overload the function by using [HttpPost] in one function.What else can be used for overloading?
Basically the rule is that you can handle this when it is responding to different types of requests, so Post/Get/Delete. (Any of the items in the HttpVerbs enumeration)
It is due to the way that it does resolution of the method to call in the controller, and specifying the method allows it to handle resolution.
In ASP.NET MVC, incoming request url should match action of controller. In MVC request processing pipeline, first the controller action is selected, and then the parameters for it are inspected and populated. Imagine what happened if controller had two methods with same name but different signature (overloaded).The c# compiler does not complain, as it understands the code, because it can distinguish between methods based on its parameter signature. But ASP.NET MVC request matching mechanism, as mentioned above, cannot - it first does search for action and only after action is selected, it takes look at its parameters. Because of this, "Public actions in controllers cannot be overloaded" - if there're no difference between methods(actions) other than parameters, action selection in MVC will fail to unambiguously select one. This's where ActionMethodSelectorAttribute comes into play. This is the base mechanism for developers to affect the way MVC searches for valid action in specified controller. It has the method IsValidForRequest() that tells MVC wether action can be selected for usage or not. All of [AcceptVerbs], [HttpGet], [HttpPost], [HttpPut], [HttpDelete] and [HttpNonAction] derive from this attribute. And bingo - now the method overloading is possible - although actions have got the same name, one of the attributes above (or your custom attribute derived from ActionMethodSelectorAttribute) can tell MVC wchich action to select and which one to not. And MVC now unambigously knows wchich action is valid for request. Consider example
[HttpGet]
public ActionResult Index()
{
// The above HttpGet.IsValidForRequest() called internally
by mvc will return true only if request is made via HTTP GET
}
[HttpPost]
public ActionResult Index(MyModel model)
{
// The above HttpPost.IsValidForRequest() called internally
by mvc will return true only if request is made via HTTP POST
}
// And so forth with other ActionMethodSelectorAttibute s. As you see, only one action from same named ones is valid for single request when decorated with any of builtin ActionMethodSelectorAttibute

Any way to handle Put and Delete verbs in ASP.Net MVC?

just wondering if anyone knows of a truly restful Put/delete implementation asp.net mvc preview 5 preferably.
Check out the mvccontrib project at http://www.mvccontrib.org.
In the source code a restful implementation has been added and it is current up to Preview 5. Check out the source code here - http://mvccontrib.googlecode.com/svn/trunk/src/MVCContrib/SimplyRestful
Rails uses a "method" parameter in the form and then fakes it, but calls the appropriate method if you designate it.
I understand most clients won't support restful stack, but can asp.net mvc, auto-negotiate these verbs and place them in the appropriately deemed actions?
I've been covering this in my blog http://shouldersofgiants.co.uk/blog/ where I'm looking at an entire RESTful web service based on ASP.Net and MVC
I don't know of one off the top of my head, but you might look into the way that Rails handles it if you don't find anything else, and try porting it over. Rails utilizes POST, GET, PUT, and DELETE, but it apparently has to do some fakery for PUT. Could be worth looking into if you come up dry here.
I think that the new AcceptVerbsAttribute in preview 5 should be capable of directing any type of request to a designated action. Marking a method like below in theory allows handling of all verbs but I haven't explicitly tested put or delete.
[AcceptVerbs("delete")]
public object DoDeleteAction()
With MVC Beta, u can now use an HttpVerbs enumeration.
here's an example...
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{ ... }
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update()
{ ... }
[AcceptVerbs(HttpVerbs.Delete)]
public ActionResult Delete()
{ ... }
you get the idea.
hth :)

Resources