.net does not route POST method
Project link here -> https://github.com/crumdev/hqbbq.git
I have a simple 3 page MVC website with 1 controller. For the contact page, I have 3 input forms. Following are the controller methods:
[Route("contact/")]
public IActionResult Contact()
{
return View();
}
[HttpPost]
public IActionResult Contact(string name, string email, string message)
{
ViewBag.Name = name;
ViewBag.Email = email;
ViewBag.Message = message;
return View();
}
When I submit a form with a breakpoint inside the Contact method for the HttpPost, it never breaks, but instead uses the normal method and just returns the view again. I tried to reduce my form to just the name field and only grab that, and this is not part of the POST method. I gave the normal Contact method a [HttpGet] attribute so that it can only be used for GET requests, and when I submit the form it completely bypasses my controller and returns a blank Dev exception page except for "Hello World!" on the screen. I've read the documentation and followed the instructions on teamtreehouse.com for regular ASP.Net but can't figure out why it behaves this way.
Edit: Here is the code for the page sending the POST. I am just using a simple HTML form with a POST method to submit data.
https://github.com/crumdev/hqbbq/blob/master/HQ-BBQ/Views/Home/contact.cshtml
source to share
The POST action must also have a route if it is intended to use attribute routing.
[HttpGet]
[Route("contact")]
public IActionResult Contact() {
return View();
}
[HttpPost]
[Route("contact")]
public IActionResult Contact(string name, string email, string message) {
ViewBag.Name = name;
ViewBag.Email = email;
ViewBag.Message = message;
return View();
}
Note the exclusion of slashes as they are not needed. Make sure the names and IDs of the form input match the parameters of the target action
source to share
It looks like you are missing an attribute Route
in the method [HttpPost]
. Try it.
[HttpPost]
[Route("contact/")]
public IActionResult Contact(string name, string email, string message)
Also update your view code to name
match the tags property <input />
to your controller action arguments.
Remember that MVC uses the name property to bind to arguments in your controller action. MSDN model binding
For example, update your email input to include the name property:
<input name="email" id="email" class="input" type="text" placeholder="Email" value="@ViewBag.Email">
You will also need to update the title of the text area to name="message"
.
source to share
You can use the FromForm annotation for your parameters in the post controller method
[HttpPost]
[Route("contact")]
public IActionResult Contact([FromForm]string name, [FromForm]string email, [FromForm]string message)
I would also recommend using the view model instead of passing all of your form fields as parameters. Imagine you have a form with 10 fields, your method signature will be harder to read
source to share
I could not direct to action because I passed in an object that did not match the model like
public class NewsModel : IActive
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public string NewsName { get; set; }
public string NewsText { get; set; }
public bool Active { get; set; }}
{"id":0,"newsName":"123","newsText":"123","active":""}
active - should be boolean, but I passed in a string. So the first thing to do is remove the parameters in the Post methods.
[HttpPost] public async Task<IActionResult> PostNews( )
If you are now in action, then you have a problem with the model, otherwise, you have a problem with routing.
source to share