views:

516

answers:

3

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)%>
...

Thanks!

+1  A: 

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)
    }
}
eu-ge-ne
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.
A: 

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".

A: 

look at this, i think it could help you

http://stackoverflow.com/questions/1361092/asp-net-mvc-viewmodel-pattern

Omu