2

我正在尝试创建一个基本注册表单,该注册表单从下拉列表中接收带有状态的地址。我似乎无法将下拉列表中的数据提取到包含状态对象的模型中。我尝试创建一个自定义模型绑定器,如下所示。当我调试 ModelState 是有效的,但状态始终为空。

楷模:

public class AccountInfo 
{
    public virtual Guid accoundID { get; set; }
    public virtual string city { get; set; }
    public virtual string email_address { get; set; }
    public virtual string fax_number { get; set; }
    public virtual string first_name { get; set; }
    public virtual string last_name { get; set; }
    public virtual string mailing_address { get; set; }
    public virtual string phone_number { get; set; }
    public virtual State state { get; set; }
    public virtual string zip_code { get; set; }
}
public class State
{
    public virtual int ID { get; set; }
    public virtual string text { get; set; }
    public virtual string value { get; set; }
}

模型粘合剂:

 public class StateModelBinder : IModelBinder
{
    private RepositoryDB Database;
    public object BindModel(
        ControllerContext controllerContext,
        ModelBindingContext bindingContext
        )
    {
        var key = bindingContext.ModelName + ".state";
        var value = bindingContext.ValueProvider.GetValue(key);
        if (value == null)
        {
            return null;
        }
        var result = new State();
        Database = new RepositoryDB(ConfigurationManager.
            ConnectionStrings["ConnectionString"].ConnectionString);

        try
        {
            var query = from s in Database.States
                        where s.value == value.ToString()
                        select new State()
                        {
                            text = s.text,
                            ID = s.ID,
                            value = s.value
                        };
            result = (State)query.ToList().ElementAt(0);        
        }
        catch (Exception ex)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex.Message);
            bindingContext.ModelState.SetModelValue(key, value);
        }


        return result;
    }

控制器:

[HttpPost]
    public ActionResult Index(AccountInfo accountModel)
    {
        try
        {
            if (ModelState.IsValid)
            {
                Database.Account.Add(accountModel);
                Database.SaveChanges();

                return Redirect(Url.Action("Success"));
            }
        }
        catch (Exception ex)
        {
            ModelState.AddModelError(String.Empty, ex);
        }
        // invalid info - return with error message         
        //repop select lists
        GetStates();
        return View(accountModel);
    }
public void GetStates()
    {
        IEnumerable<SelectListItem> states = from s in Database.States
                                                select new SelectListItem
                                                {
                                                    Text = s.text,
                                                    Value = s.value
                                                };

        ViewBag.state = states.ToList();
    }

看法:

@Html.LabelFor(model => model.state, "*State")
@Html.DropDownListFor(model => model.state, (IEnumerable<SelectListItem>)ViewBag.state)
4

1 回答 1

3

这是你的问题:

@Html.DropDownListFor(model => model.state, (IEnumerable<SelectListItem>)ViewBag.state)

绑定到 model.State 不能工作,因为这是一个复杂的类型:

public class State
{
    public virtual int ID { get; set; }
    public virtual string text { get; set; }
    public virtual string value { get; set; }
}

如果您考虑一下,表单要回发的唯一内容是所选下拉项目的值,例如“MN”(明尼苏达州),而不是完整的课程。(您还没有为每个下拉列表项的值序列化“状态”类,希望只是每个状态的主键)您需要根据主键的类型将模型上的状态设置为字符串或整数你的状态是这样的:

public class AccountInfo 
{
    //...
    public virtual string/int State { get; set; }
    //...
}

如果您想从状态的唯一标识符(例如,它应该是作为字符串或 int 回发到服务器的值),您可以从那里重新水合您的 State 对象

于 2012-08-01T16:59:54.670 回答