从传递给局部视图的嵌套复杂对象中获取值
我有一个 ViewModel,它有一个复杂的对象作为其成员之一.复杂对象有 4 个属性(所有字符串).我正在尝试创建一个可重用的部分视图,我可以在其中传入复杂对象并让它生成带有 html 帮助程序的 html 为其属性.这一切都很好.但是,当我提交表单时,模型绑定器不会将值映射回 ViewModel 的成员,因此我在服务器端没有得到任何东西.如何将用户键入的值读取到复杂对象的 html 帮助程序中.
I have a ViewModel that has a complex object as one of its members. The complex object has 4 properties (all strings). I'm trying to create a re-usable partial view where I can pass in the complex object and have it generate the html with html helpers for its properties. That's all working great. However, when I submit the form, the model binder isn't mapping the values back to the ViewModel's member so I don't get anything back on the server side. How can I read the values a user types into the html helpers for the complex object.
视图模型
public class MyViewModel
{
public string SomeProperty { get; set; }
public MyComplexModel ComplexModel { get; set; }
}
MyComplexModel
MyComplexModel
public class MyComplexModel
{
public int id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
....
}
控制器
public class MyController : Controller
{
public ActionResult Index()
{
MyViewModel model = new MyViewModel();
model.ComplexModel = new MyComplexModel();
model.ComplexModel.id = 15;
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
// model here never has my nested model populated in the partial view
return View(model);
}
}
查看
@using(Html.BeginForm("Index", "MyController", FormMethod.Post))
{
....
@Html.Partial("MyPartialView", Model.ComplexModel)
}
部分视图
@model my.path.to.namespace.MyComplexModel
@Html.TextBoxFor(m => m.Name)
...
如何在表单提交时绑定此数据,以便父模型包含从局部视图在 Web 表单上输入的数据?
how can I bind this data on form submission so that the parent model contains the data entered on the web form from the partial view?
谢谢
我发现我需要在前面加上ComplexModel".到我在局部视图(文本框)中的所有控件名称,以便它映射到嵌套对象,但我无法将 ViewModel 类型传递给局部视图以获取额外的层,因为它需要通用才能接受多个 ViewModel类型.我可以用 javascript 重写 name 属性,但这对我来说似乎过于贫民窟.我还能怎么做?
I've figured out that I need to prepend "ComplexModel." to all of my control's names in the partial view (textboxes) so that it maps to the nested object, but I can't pass the ViewModel type to the partial view to get that extra layer because it needs to be generic to accept several ViewModel types. I could just rewrite the name attribute with javascript, but that seems overly ghetto to me. How else can I do this?
编辑 2:我可以使用 new { Name="ComplexModel.Name" } 静态设置 name 属性,所以我认为我在做生意,除非有人有更好的方法?
EDIT 2: I can statically set the name attribute with new { Name="ComplexModel.Name" } so I think I'm in business unless someone has a better method?
您可以使用
@Html.Partial("MyPartialView", Model.ComplexModel,
new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ComplexModel" }})
将前缀附加到您控制 name
属性,以便 <input name="Name" ../>
将成为 <inputname="ComplexModel.Name" ../>
并在回发时正确绑定到 typeof MyViewModel
which will perpend the prefix to you controls name
attribute so that <input name="Name" ../>
will become <input name="ComplexModel.Name" ../>
and correctly bind to typeof MyViewModel
on post back
编辑
为了方便一点,你可以把它封装在一个 html helper 中
To make it a little easier, you can encapsulate this in a html helper
public static MvcHtmlString PartialFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string partialViewName)
{
string name = ExpressionHelper.GetExpressionText(expression);
object model = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).Model;
var viewData = new ViewDataDictionary(helper.ViewData)
{
TemplateInfo = new System.Web.Mvc.TemplateInfo
{
HtmlFieldPrefix = string.IsNullOrEmpty(helper.ViewData.TemplateInfo.HtmlFieldPrefix) ?
name : $"{helper.ViewData.TemplateInfo.HtmlFieldPrefix}.{name}"
}
};
return helper.Partial(partialViewName, model, viewData);
}
并将其用作
@Html.PartialFor(m => m.ComplexModel, "MyPartialView")