模型绑定与ASP.NET MVC的内部嵌套模型
问题描述:
我试图创建一个基本的注册表单,从一个下拉列表中接受一个状态的地址。我似乎无法从下拉菜单中将数据提取到包含状态对象的模型中。我试过创建一个自定义模型绑定器,如下所示。当我调试ModelState是有效的,但状态始终为空。模型绑定与ASP.NET MVC的内部嵌套模型
型号:
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)
答
这是你的问题:
@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”(明尼苏达州)而不是全班。 (你没有为每个下拉列表项的值序列化一个“State”类,只是希望每个状态的主键)你需要让你的模型的状态是一个字符串或int,这取决于主键的类型是什么你的状态,像这样:
public class AccountInfo
{
//...
public virtual string/int State { get; set; }
//...
}
从那里,你可以重新滋润你的状态对象,如果你从一个国家的唯一标识符(这应该是被回发到服务器作为值喜欢字符串或int例如)
+0
好的,谢谢。 – 2012-08-01 17:33:06
你在做什么?为什么要定制模型绑定为什么选择ViewBag?为什么不查看模型? – 2012-08-01 16:30:09
我试图在AccountInfo类中存储“State”(如在邮件地址中)作为对象。我使用来自具有各种可能状态的数据库上的简单表的linq查询填充下拉列表。你能否演示如何使用视图模型而不是我的实现? – 2012-08-01 17:25:13