I am very very new to MVC the design-pattern and also the Framework. I am also not extremely well- versed in fundamentals of ASP.NET Forms. However, I do understand the basi
Best Practice - Request handling
It is best practice to only use public methods in your controller which are going to be serviced either with a view or with json. For all public methods in your controller, it is best practice to either mark them with an [HttpGet]
or an [HttpPost]
, or one of the other types which I wont cover as they are more edge case scenario.
These Http
attributes restrict the method to only servicing those specific types of requests. While the default is [HttpGet]
, I have found that not marking [HttpGet]
in all scenarios can at times lead to unexpected behavior when there are naming conflicts.
Best Practice - PRG
Post-Redirect-Get is a design pattern which essentially stipulates that any time you are going to be sending a response which came from a POST request, you should redirect to a get in order to send the response. This protects from a number of scenarios, including not posting again if the back button is used.
The redirect usually comes in the form of the [HttpPost]
ActionResult using return RedirectToAction("MyHttpGetAction");
.
Posting complex models
There are multiple ways which you can send a complex model. The main difference is that if you are using a GET request it is in the url, and if you are using a POST request it is in the request headers. If you use ajax then the difference becomes blurred as you will almost always send it in the body.
The [HttpPost]
attribute tells the routing engine to send any POST requests to that action method to the one method over the other. This is a type of overloading.
Why is this second method adorned with
[HttpPost]
when the first method does not require any attributes?
The default for a method is [HttpGet]
. Because of that, no attribute is needed.
Are there any guidelines on when to use
[Http]
attributes and when not?
Ideally, attributes should be on every method, in order to avoid confusion. As you get more familiar with how things are working, you will often take shortcuts (as with everything else), and omit them when you know that they are not necessary.
Since
MyViewModel
is a complex type, you can not pass it as part of URL. How can you call it?
The data will be turned into the model from the data in the body of the request. This can come either as a JSON object, or as Form data. (There are tricks to get the object initialized from the URL, but they can be a little complicated and advanced.)
Generally, complex objects are passed in the HTTP body with verbs that support it such as POST and PUT. The body content must pass Model Binding validation. That basically means that if it's a POST request with Content-Type: application/json, it must deserialize from JSON into MyViewModel. If the content is XML, it must deserialize as XML.
General convention is to have all the primitive types that can be found in the URL path, query, and headers first, then one complex type from the POST (or PUT) body after that. I believe it's possible to put complex types elsewhere, but then you're getting into type converters and custom attributes which you should probably hold off on if you're a beginner.
Why is this second method adorned with [HttpPost] when the first method does not require any attributes? Are there any guidelines on when to use [Http] attributes and when not?
"[HttpPost]" is telling the routing engine that this method overload is only available via HTTP POST. Attempting to PUT /home/index with a body will fail with 404 Not Found, in this case. The parameter-free version of Index() doesn't require it because it can work with any HTTP verb, including GET, POST, and PUT.