Hungry, data updating attributes core cum buckets
Ever found yourself staring at your ASP.NET MVC controller, trying to work out why a value you’re expecting from your Razor view isn’t being passed through?
Or perhaps you’ve found yourself trying different versions of that pesky HTML Helper tag to get the right markup that will submit form values but also render extra attributes like or .
It’s all too easy to lose hours of your life tracking down which part of the puzzle your forgot to implement (ask me how I know!).
ASP.NET Core makes this easier, using something called Tag Helpers.
Enter the HTML Form
The typical way to handle user input is to implement a form in your web application which, when submitted, sends data to your application. Your app can then do whatever it needs to with that information (store it in a database, email it to someone etc.).
If you want to really bring this back to basics, you can just create a form using plain old html.
On first glance, this looks reasonable. We’ve got a single text box (firstName) and the form is going to send its data via an HTTP Post.
Unless we indicate otherwise, this will post back to the same location used to serve the form.
So, using default routing conventions, if we have a controller like this…
Then we’d access this form via an HTTP Get request to .
When you submit the form, it will be posted to the same address () (as an HTTP Post request).
But, we have a fatal flaw in our form! Run this, enter a name, submit the form and all you’ll get is a half-complete sentence.
For the value of the input to be submitted as form data, it needs to have a name attribute.
Add that and test your form again.
ASP.NET MVC spots the incoming “firstName” value (in the sumitted form data) and binds it to the parameter we specified in the (POST) method on our controller.
When you come across issues like this, it isn’t always obvious what’s causing the problem.
This is where the Chrome network tab comes into its own.
Submit your form with the developer tools open (F12) and you’ll see the form post in the network tab.
Click the relevant request and check out the Form Data section.
If you don’t see the values you expect then there’s something wrong with your form.
Enter the Tag Helper
So this brings us to ASP.NET Core and what it offers over and above the simple html form we started with.
You can use a Model and something called Tag Helpers to save you manually adding name attributes to all of your input fields.
First up, create a class to act as the model for our page.
Now we can tweak our view (cshtml page) to use this model by adding a model declaration at the top.
Make sure you specify the correct namespace, where your model exists.
With that in place, we can start using tag helpers to do some of the manual plumbing (e.g. adding name attributes) we’d otherwise have to do ourselves.
We’ve made a few changes here.
First we’ve explicitly defined the action and controller that this form will post back to, using and . This isn’t strictly necessary, but it doesn’t hurt to be explicit, just in case we start moving things around, the form will continue to post to the correct controller action.
Secondly, because this page now knows about its model, we can use on our and elements, specifying the relevant property name from our model.
Here’s the resulting form.
And its rendered markup.
Note how ASP.NET has picked up that the rendered form should make a to and has automatically included the attribute for the input field.
If you’re wondering what the is, this is a neat way to reduce the risk of your application being duped by a cross site request forgery attack.
You can (and should) read more about how ASP.NET prevents cross-site request forgery attacks and it’s good to know if you use ASP.NET Core’s tag helpers for your forms, the anti-forgery token is generated for you automatically.
I’ve got a model and I’m not afraid to use it
Now we’ve got a model we can get rid of that string parameter in the Index POST action and replace it with a parameter.
ASP.NET MVC Core will bind the form data to your model automatically.
This also means we won’t find ourselves constantly updating the action every time we need to handle another value submitted via the form.
Incidentally, I’ve also added the other half of the Request Verification Token check here (the attribute) to make sure this form has been posted from our site (and not a malicious site hosted by someeone else).
A better label
Finally, by default the tag helper on our label has used the name of the property for its value.
We can improve this and be explicit about what the label should say, with an attribute on our model.
Admittedly, this form isn’t going to win any prizes for its design, but at least the label reads a little better!
What about HTML Helpers?
If you’ve used previous versions of MVC, you’re probably familiar with the HTML Helpers from previous versions. They look like this…
One huge benefit of Tag Helpers over HTML Helpers, is that they leave you free to define your markup using standard HTML tags. Rather than have some magic render the entire element for you, the tag helper extends your standard HTML element. This is evident in our example where we are free to add a placeholder attribute to the FirstName input without jumping through extra hoops to bend an HTML Helper to our will.
ASP.NET Core tag helpers make it trivial to wire up your HTML forms to your MVC controllers whilst leaving you free to control your HTML Markup.
photo credit: jasleen_kaur obligation via photopin(license)