使用时,下拉值为null,viewmodel& asp.net mvc中的modelbinder

时间:2009-07-20 18:16:40

标签: asp.net-mvc modelbinders

我正在使用asp.net的modelbinder功能,在从视图发布时将表单值绑定到我的实体。

html在初始视图中使用正确的选项和值项正确呈现。

完成表单和发布后,除下拉列表中的值外,所有值都会正确填充到实体中。不确定我做错了什么。

下面的代码:

客户实体:

 public class Customer : EntityBase
    {
        public virtual string Name { get; set; }
        public virtual string Email { get; set; }
        public virtual string Mobile { get; set; }
        public virtual Store LocalStore { get; set; }
        public virtual DateTime? DateOfBirth { get; set; }

        public Customer(){}

        public Customer(string name, string email, string mobile, Store localStore):this(name, email, mobile, localStore, null)
        {
        }

        public Customer(string name, string email, string mobile, Store localStore, DateTime? dateOfBirth)
        {
            Name = name;
            Email = email;
            Mobile = mobile;
            LocalStore = localStore;
            DateOfBirth = dateOfBirth;
        }
    }

视图模型:

 public class CustomerViewModel {

        // Properties
       private IStoreRepository _StoreRepository;
       public Customer Customer { get; private set; }
       public SelectList Stores { get; private set; }

        // Constructor
        public CustomerViewModel(IStoreRepository storeRepository, Customer customer)
        {
            _StoreRepository = storeRepository;
            Customer = customer;
                Stores = new SelectList(_StoreRepository.GetAllStores(), "Id", "Name", Customer.LocalStore.Id);

        }
    }

控制器:

 [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([Bind(Prefix="")]Customer customer)
        {
            return View(new CustomerViewModel(_StoreRepository, customer));
        }

查看:

<%@ Import Namespace="BlackDiamond.Buzz.MVCWeb.Controllers"%>
<%@ Import Namespace="BlackDiamond.Buzz.Core"%>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CustomerViewModel>" %>
<%
    Customer customer = ViewData.Model.Customer;
    using (Html.BeginForm())
    {
    %>    
    <table>
        <tr>
            <td>Local Store:</td>
            <td><%= Html.DropDownList("LocalStore", ViewData.Model.Stores)%></td>
         </tr>
         <tr>
            <td>Name:</td><td><%= Html.TextBox("Name", customer.Name)%></td>
         </tr>
         <tr>
            <td>Email:</td><td><%= Html.TextBox("Email", customer.Email)%></td>
        </tr>
        <tr>
            <td>Mobile:</td><td><%= Html.TextBox("Mobile", customer.Mobile)%></td>
        </tr>
    </table>
    <input type="submit" value="Create" />
<%}%>

2 个答案:

答案 0 :(得分:1)

也许是因为你将LocalStore声明为Store类型?

public virtual Store LocalStore { get; set; }

我认为它应该是int(如果“id”属性是int)或字符串。但不确定。

public virtual int LocalStore { get; set; }

答案 1 :(得分:1)

必须根据下拉列表中的guid创建自定义模型绑定器以检索Store实体:

    public class CustomerModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType == typeof(Customer))
        {
            // get values
            string name = bindingContext.ValueProvider["Name"].AttemptedValue;
            string email = bindingContext.ValueProvider["Email"].AttemptedValue;
            string mobile = bindingContext.ValueProvider["Mobile"].AttemptedValue;
            Guid storeId = new Guid(bindingContext.ValueProvider["LocalStore"].AttemptedValue);
            Store localStore = IoC.Container.Resolve<IStoreRepository>().GetStore(storeId);

            // hydrate
            return new Customer(name, email, mobile, localStore);
        }
        else
        {
            return null;
        }
    }
}