2

I'm a bit of an MVC newbie, so you'll have to forgive what I imagine is an elementary question.

I created a custom viewmodel in order to have a multiselect list in my form:

public class CustomerFormViewModel
{
    public Customer Customer { get; private set; }
    public MultiSelectList CustomerType { get; private set; }

    public CustomerFormViewModel(Customer customer)
    {
        Customer = customer
        // this returns a MultiSelectList:
        CustomerType = CustomerOptions.Get_CustomerTypes(null);
    }
}

I found that my first attempt only captured the first value of the multiselect, and I guessed that this is because my create actions looked like this:

    // GET: /Buyer/Create
    public ActionResult Create() { ... }

    // POST: /Buyer/Create
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(Customer customer) { ... }

So, I decided to change it to this:

    // GET: /Buyer/Create
    public ActionResult Create() { ... }

    // POST: /Buyer/Create
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(CustomerFormViewModel model) { ... }

So that I can get the full output from the MultiSelectList and parse it accordingly. Trouble is, this complains that there's no parameterless constructor for the viewmodel (and there isn't) - and I'm not sure the right way to go about fixing this. Nothing I've tried has worked and I really need some help!

In case it helps, my view looks like this:

<%@  Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MySite.Controllers.CustomerFormViewModel>" %>
...
<% using (Html.BeginForm())
    <%= Html.ListBox("CustomerType", Model.CustomerType)%>
...

2 Answers 2

1

Have you tried a custom ModelBinder. Not sure I'm understanding your code clearly but this could be your starting point:

public class CustomerFormViewModelBinder : DefaultModelBinder
{
    protected virtual object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        var model = new CustomerFormViewModel(customer)
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Have been doing some research and concluded that - as you say - a custom Model Binder is exactly what I need. Now I just need to figure out how to write one! Thanks for your comment - I'll take your suggestion and see if I can make it work.
1

I believe I got it:

public class CustomerModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var form = controllerContext.HttpContext.Request.Form;

        Customer customer = base.BindModel(controllerContext, bindingContext) as Customer;

        if (customer!= null)
        {
            customer.CustomerType= form["CustomerType"];
        }

        return customer;
    }
}

Along with an entry in the global.asax file's Application_Start():

        ModelBinders.Binders.Add(typeof(Customer), new CustomerModelBinder());

which puts the comma separated list of listbox selections in the field. e.g. "1,3,4".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.