Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 从传递到局部视图的嵌套复杂对象获取值_Asp.net Mvc_Model_Partial Views - Fatal编程技术网

Asp.net mvc 从传递到局部视图的嵌套复杂对象获取值

Asp.net mvc 从传递到局部视图的嵌套复杂对象获取值,asp.net-mvc,model,partial-views,Asp.net Mvc,Model,Partial Views,我有一个ViewModel,它的一个成员是一个复杂的对象。复杂对象有4个属性(所有字符串)。我试图创建一个可重用的局部视图,在这个视图中,我可以传入复杂对象,并让它使用html帮助器为其属性生成html。一切都很好。但是,当我提交表单时,模型绑定器没有将值映射回ViewModel的成员,因此我无法从服务器端获得任何信息。如何将用户键入的值读入复杂对象的html帮助程序中 视图模型 public class MyViewModel { public string SomeProperty

我有一个ViewModel,它的一个成员是一个复杂的对象。复杂对象有4个属性(所有字符串)。我试图创建一个可重用的局部视图,在这个视图中,我可以传入复杂对象,并让它使用html帮助器为其属性生成html。一切都很好。但是,当我提交表单时,模型绑定器没有将值映射回ViewModel的成员,因此我无法从服务器端获得任何信息。如何将用户键入的值读入复杂对象的html帮助程序中

视图模型

public class MyViewModel
{
     public string SomeProperty { get; set; }
     public MyComplexModel ComplexModel { get; set; }
}
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);
     }
}
看法

局部视图

@model my.path.to.namespace.MyComplexModel
@Html.TextBoxFor(m => m.Name)
...
如何在表单提交时绑定此数据,以便父模型包含从局部视图在web表单上输入的数据

谢谢

编辑:我发现我需要在局部视图(文本框)中的所有控件名称前加上“ComplexModel.”,以便它映射到嵌套对象,但我无法将ViewModel类型传递到局部视图以获得额外的层,因为它需要是通用的,才能接受多个ViewModel类型。我可以用javascript重写name属性,但这对我来说似乎过于贫民化了。我还能怎么做


编辑2:我可以使用新的{name=“ComplexModel.name”}静态地设置name属性,因此我认为我是在做生意,除非有人有更好的方法?

您可以尝试将ViewModel传递给partial

@model my.path.to.namespace.MyViewModel
@Html.TextBoxFor(m => m.ComplexModel.Name)
编辑

您可以创建基础模型并将复杂模型推送到其中,然后将基础模型传递给局部模型

public class MyViewModel :BaseModel
{
    public string SomeProperty { get; set; }
}

 public class MyViewModel2 :BaseModel
{
    public string SomeProperty2 { get; set; }
}

public class BaseModel
{
    public MyComplexModel ComplexModel { get; set; }
}
public class MyComplexModel
{
    public int id { get; set; }
    public string Name { get; set; }
    ...
}
然后,您的部分内容将如下所示:

@model my.path.to.namespace.BaseModel
@Html.TextBoxFor(m => m.ComplexModel.Name)

如果这不是一个可接受的解决方案,您可能必须考虑覆盖模型绑定器。您可以阅读相关内容。

您可以使用

@Html.Partial("MyPartialView", Model.ComplexModel, 
    new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ComplexModel" }})
这将使前缀与控件
name
属性垂直,这样
将成为
,并正确绑定到回发时的
MyViewModel
类型

编辑

为了使它更简单,您可以将其封装在html帮助程序中

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);
}

我遇到了同样的情况,在这些信息性帖子的帮助下,我将部分代码更改为在由partial view生成的输入元素中生成前缀on

我使用了Html.partial帮助程序,为Html.partial的构造函数提供partialview名称和ModelType对象,以及带有Html字段前缀的ViewDataDictionary对象实例

@model my.path.to.namespace.MyViewModel
@Html.TextBoxFor(m => m.ComplexModel.Name)
这将导致“主视图”的“xyz url”的GET请求,并使用前缀生成的输入元素呈现其中的部分视图,例如,早期的Name=“Title”现在在相应的HTML元素中变为Name=“MySubType.Title”,其余的表单输入元素也是如此

当对“xyz url”发出POST请求时出现问题,希望填写的表单保存到我的数据库中。但是MVCModelbinder没有用填写的表单值绑定我发布的模型数据,而且ModelState也丢失了。viewdata中的模型也将变为空

最后,我尝试使用TryUppdateModel方法更新发布表单中的模型数据,该方法使用模型实例和html前缀,该前缀在前面传递给部分视图,现在可以看到模型与值绑定,并且模型状态也存在


请让我知道这个方法是好的还是有点多样化

如果使用标记帮助器,
partial
标记帮助器接受一个
for
属性,该属性满足您的期望

<partial name="MyPartialView" for="ComplexModel" />


使用
for
属性,而不是典型的
model
属性,将导致分部中的所有表单字段都使用
ComplexModel.
前缀命名。

我不能这样做,因为它需要是泛型的。将有几个具有自己类型的父视图模型需要传入…请参阅OP中我的第一次编辑。这看起来非常有希望。我已经离开办公室一天了,但明天回来后我会试一试,如果对我有用的话,我会把答案记下来。谢谢。呸……我不能高估它,因为它说我必须有15个名声+对于你来说,只要我得到15个rep:)@BlairHolmes,就添加了一个html帮助程序方法,使这有点复杂easier@Christian,在某种程度上已经是这样,因为正确的方法是对嵌套模型(以及
EditorFor()使用自定义的
EditorTemplate
)使用
EditorFor()
方法根据上面的代码传递
HtmlFieldPrefix
)。Partials并不是真正设计用来在这个场景中使用的,这就是为什么我认为MVC团队没有包括它)EditorFor的使用是“过于传统的”(严格的命名转换,文件夹结构),最终改变了输出html。第二种解决方案是传递父模型,这也是一种错误的方法,因为它不再是可重用的。
<partial name="MyPartialView" for="ComplexModel" />