Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC - Custom model binder able to process arrays

I need to implement a functionality to allow users to enter price in any form, i.e. to allow 10 USD, 10$, $10,... as input.

I would like to solve this by implementing a custom model binder for Price class.

 class Price { decimal Value; int ID; } 

The form contains an array or Prices as keys

keys:
"Prices[0].Value"
"Prices[0].ID"
"Prices[1].Value"
"Prices[1].ID"
...

The ViewModel contains a Prices property:

public List<Price> Prices { get; set; }

The default model binder works nicely as long as the user enters a decimal-convertible string into the Value input. I would like to allow inputs like "100 USD".

My ModelBinder for Price type so far:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    Price res = new Price();
    var form = controllerContext.HttpContext.Request.Form;
    string valueInput = ["Prices[0].Value"]; //how to determine which index I am processing?
    res.Value = ParseInput(valueInput) 

    return res;
}

How do I implement a custom model Binder that handles the arrays correctly?

like image 942
Marek Avatar asked Feb 28 '10 09:02

Marek


People also ask

What is custom model binder in MVC?

In the MVC pattern, Model binding maps the HTTP request data to the parameters of a Controllers action method. The parameter can be of a simple type like integers, strings, double etc. or they may be complex types. MVC then binds the request data to the action parameter by using the parameter name.

How does model binding work in MVC?

Model binding is a process in which we bind a model to controller and view. It is a simple way to map posted form values to a . NET Framework type and pass the type to an action method as a parameter. It acts as a converter because it can convert HTTP requests into objects that are passed to an action method.

In which of the following places will the default model binder look in order to build an object passed as a parameter to an MVC 5 controller method?

The MVC runtime uses Default ModelBinder to build the model parameters. This is done automatically by MVC Model Binder. Let us understand by a simple example how model information is passed to the controller by model binding from view in MVC.


1 Answers

Got it: The point is to not try to bind a single Price instance, but rather implement a ModelBinder for List<Price> type:

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        List<Price> res = new List<Price>();
        var form = controllerContext.HttpContext.Request.Form;
        int i = 0;
        while (!string.IsNullOrEmpty(form["Prices[" + i + "].PricingTypeID"]))
        {
            var p = new Price();
            p.Value = Process(form["Prices[" + i + "].Value"]);
            p.PricingTypeID = int.Parse(form["Prices[" + i + "].PricingTypeID"]);
            res.Add(p);
            i++;
        }

        return res;
    }

//register for List<Price>
ModelBinders.Binders[typeof(List<Price>)] = new PriceModelBinder();
like image 51
Marek Avatar answered Oct 10 '22 08:10

Marek