Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.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 3 在同一父视图上多次使用一个局部视图_Asp.net Mvc 3_Model Binding - Fatal编程技术网

Asp.net mvc 3 在同一父视图上多次使用一个局部视图

Asp.net mvc 3 在同一父视图上多次使用一个局部视图,asp.net-mvc-3,model-binding,Asp.net Mvc 3,Model Binding,我正在使用MVC3剃须刀。我有一个场景,我必须在同一父视图上多次使用局部视图。我遇到的问题是,当父视图被渲染时,它会在这些局部视图中生成输入控件的相同名称和ID。由于我的局部视图绑定到不同的模型,因此当视图返回“保存”时,它会崩溃。知道如何使控件id/名称唯一吗?可能知道如何给它们加前缀 等待 Nabeel就个人而言,我更喜欢使用编辑器模板,因为它们会处理这个问题。例如,可以使用以下视图模型: public class MyViewModel { public ChildViewMode

我正在使用MVC3剃须刀。我有一个场景,我必须在同一父视图上多次使用局部视图。我遇到的问题是,当父视图被渲染时,它会在这些局部视图中生成输入控件的相同名称和ID。由于我的局部视图绑定到不同的模型,因此当视图返回“保存”时,它会崩溃。知道如何使控件id/名称唯一吗?可能知道如何给它们加前缀

等待


Nabeel

就个人而言,我更喜欢使用编辑器模板,因为它们会处理这个问题。例如,可以使用以下视图模型:

public class MyViewModel
{
    public ChildViewModel Child1 { get; set; }
    public ChildViewModel Child2 { get; set; }
}

public class ChildViewModel
{
    public string Foo { get; set; }
}
以及以下控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Child1 = new ChildViewModel(),
            Child2 = new ChildViewModel(),
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}
Index.cshtml
视图中:

@model MyViewModel
@using (Html.BeginForm())
{
    <h3>Child1</h3>
    @Html.EditorFor(x => x.Child1)

    <h3>Child2</h3>
    @Html.EditorFor(x => x.Child2)
    <input type="submit" value="OK" />
}

使用编辑器for可以为主视图模型的不同属性包含模板,并将生成正确的名称/ID。除此之外,您还可以在后期操作中正确填充视图模型。

还有一种替代方法:

  • 向PartialView添加前缀
  • 绑定模型,删除前缀
  • 对于1,在视图中设置前缀:

    ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "prefix";
    
    对于2,您可以使用
    UpdateModel
    恢复数据,如下所示:

    UpdateModel(producto, "prefix");
    
    这不是很明智,因为您的操作不会将数据作为参数接收,而是在稍后更新模型。这有几个不便之处:1)通过查看其签名不清楚您的操作需要什么2)为操作提供输入以进行单元测试并不容易3)操作易受溢出参数的影响(用户提供的参数不应该存在,并且映射到模型)

    但是,对于2,有一种替代方法:注册一个自定义模型绑定器,允许您删除前缀。自定义模型绑定器必须知道这一点

    一个很好的解决方案是这样的,所以Q&A:但它有一个小缺陷:如果在局部视图中添加一个名为“\uu prefix”的隐藏字段,并多次将其作为局部视图呈现,则该ID将在页面中的多个不同元素中重复,这是不允许的,并且可能会引发一些问题。提供前缀的最重要原因之一是,对于一个实体的多个实例,呈现与局部视图相同的“编辑”视图。也就是说,这会发生在像gmail这样的页面上,你可以一次编辑多封电子邮件

    这个问题有几种可能的解决方案

    其中之一是将前缀作为查询字符串或routedata值提供,而不是作为表单字段提供,这样可以避免Id冲突,并且可以由模型绑定器找到。(它可以始终具有相同的名称)

    另一种解决方案是使用具有固定图案的隐藏字段,但对于每个渲染视图都不同。前缀可以遵循此模式以实现唯一性:“PP$ActionControllerId”类似于“PP$EditProduct23”,它对于每个渲染视图都是唯一的,并且可以很容易地在请求参数之间找到,以查找以“PP$”开头的参数

    最终的解决方案是只在视图中创建前缀,而不在任何类型的请求参数中提供前缀。模型绑定器必须通过检查请求参数的名称来查找前缀,直到找到前缀符合模式的前缀

    当然,自定义ModelBinder必须适应所选约定

    UpdateModel(producto, "prefix");