background preloader

ModelBinding

Facebook Twitter

Model Binding Decimal Values. I’m in the beautiful country of Brazil right now (I’ll hopefully blog more about that later) proctoring for the hands-on labs that’s part of the Web Camps agenda. However, the folks here are keeping me on my toes asking me to give impromptu and deeply advanced demos. It almost feels like a form of performance art as I create brand new demos on the fly. Smile During this time, several people reported issues binding to a decimal value that prompted me to write a new demo and this blog post.

Let’s look at the scenario. Suppose you have the following class (Jogadoris a soccer player in Portugese): public class Jogador { public int ID { get; set; } public string Name { get; set; } public decimal Salary { get; set; }} And you have two controller actions, one that renders a form used to create a Jogador and another action method that receives the POST request. When you type in a value such as 1234567.55 into the Salary field and try to post it, it works fine. WARNING: This is sample code! Asp.net mvc 3 - .NET MVC 3 Custom Decimal? Model Binder. Custom Model Binders in MVC 3 with IModelBinder » BuildStarted.com. Update: Apparently this works in MVC 1 and 2 - Thanks, Mike! One of the things you’ll find yourself doing quite often is loading an object from a database or other source given an id from a url.

Something along the lines of and then loading the User model with the username of “john”. public ActionResult Details(string username) { var user = db.Users.Single(u => u.Username == username); return View(user);} There’s nothing really wrong with this. It just leads to a lot of code repetition as you’ll probably have something similar for and Edit method, Edit with HttpPost and possibly several other actions. Wouldn’t it be great if you could just automagically load the User without having to call this code? Implementing IModelBinder It turns out you can. The first line of code in the BindModel method just grabs the id from the Request. Our Action method in our controller would change from the above to the following IoC (Inversion of Control) and Model Binders. Asp.net mvc - Asp MVC - "The Id field is required" validation message on Create; Id not set to [Required] Custom Model Binder Attribute. Splitting DateTime - Unit Testing ASP.NET MVC Custom Model Binders.

C# - ASP.NET MVC 3 Model-binding and form fields. MVC ViewData.Eval() method - IBloggable - implemented. While digging deeper into MVC Views, I stumbled on this method – ViewData.Eval(). Found it interesting and researched and played with some code around this method. This method gives the user a way to search through the ViewData’s object graph. So in order to get the data, you can either do 1: <%= ViewData["Message"] %> or 1: <%= ViewData.Eval("Message") %> Either line gives the same answer. You can walk through the graph using the ‘.’ 1: ViewData["employee"] = new Employee{ Name = "ScottGu"}; 3: <%= ViewData.Eval("Employee.Name") %> MVC recursively loops through the graph looking for the whole key first and then removing one token at a time. It first checks in the ViewData’s dictionary and then tries to find it in the ViewData.Model’s properties. 1: public class Software 3: public string Name { get; set; } 4: public string Version { get; set; } 5: public string Company { get; set; } In the HomeController’s Index action, I added: 1: ViewData["software"] = new Software 3: Name = "MVC", 5: if (vdd !

ASP.NET Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries. Model Binding To A List. Download the sample project to play with the code as you read this blog post. Using the DefaultModelBinder in ASP.NET MVC, you can bind submitted form values to arguments of an action method. But what if that argument is a collection? Can you bind a posted form to an ICollection<T>?

Sure thing! Public ActionResult UpdateInts(ICollection<int> ints) { return View(ints);} You can bind to that by simply submitting a bunch of form fields each having the same name. If you were to take fiddler and look at what data actually gets posted when clicking the submit button, you’d see the following. ints=1&ints=4&ints=2&ints=8 The default model binder sees all these name/value pairs with the same name and converts that to a collection with the key ints, which is then matched up with the ints parameter to your action method.

Where it gets trickier is when you want to post a list of complex types. You might think we could simply post the following to that action method: Non-Sequential Indices. ASP.NET MVC Model Binders. In the last section of my MVC Templates post, I discussed how to use the Html.EditorFor() helper with complex types. Whilst this showed how you can use Html.EditorFor() and templates to produce a user interface for complex types, it didn’t show you how to bind the result when the user has posted to a controllers action. In this post I will extend the employee example, so that it displays the offices the the user selected. Download the code for this example Default Model Binders The concept of Model Binders was introduced in MVC Preview 5, before Model Binders in a controllers action we would either get values directly from the Request Context, for example Request["Foo"] or bind directly to the Action’s parameters, for example public ActionResult Foo(string Bar).

Before I discuss Model Binders, lets examine what happens if we select Offices using the DefaultModelBinder. DefaultBinder I Thought the DefaultBinder Supported Collections? Custom Model Binders Add Model Binder Class Details. A better Model Binder. One of the more interesting extension points in ASP.NET MVC are the Model Binders. Model Binders are tasked with transforming the HTTP Form and Querystring information and coercing real .NET types out of them. A normal POST is merely a set of string key-value pairs, which isn’t that fun to work with. Back in the ASP 3.0 days, where I cut my teeth, we did a lot of “Request.Form(“CustFirstName”)” action, and just dealing with the mapping from HTTP to strong types manually. That wasn’t very fun. ASP.NET MVC supplies the DefaultModelBinder, which is able to translate HTTP request information into complex models, including nested types and arrays.

It does this through a naming convention, which is supported at both the HTML generation (HTML helpers) and the consumption side (model binders). Reconstituting complex model objects works great, especially in form posting scenarios. Quick glance at custom model binders The custom binders are bound by destination type. But we can do better. 6 Tips for ASP.NET MVC Model Binding. Here are some tips on how to take advantage of model binding in your MVC projects. Tip #1: Prefer Binding Over Request.Form If you are writing your actions like this .. [AcceptVerbs(HttpVerbs.Post)] public ActionResult Create() { Recipe recipe = new Recipe(); recipe.Name = Request.Form["Name"]; // ... return View(); } .. then you are doing it all wrong. The model binder can save you from using the Request and HttpContext properties – those properties make the action harder to read and harder to test.

One step up would be to use a FormCollection parameter instead: public ActionResult Create(FormCollection values) { Recipe recipe = new Recipe(); recipe.Name = values["Name"]; // ... return View(); } With the FormCollection you don’t have to dig into the Request object, and sometimes you need this low level of control. [AcceptVerbs(HttpVerbs.Post)] public ActionResult Create(Recipe newRecipe) { // ... return View(); } Tip #2: Custom model binders Tip #3: Custom Model Binding via Inheritance.