asp.net-mvc-3 - 在 POST 上从 RenderPartial 检索 ViewModel 的子集

标签 asp.net-mvc-3 razor

我有一个 ViewModel,其中包含一个子 ViewModel。在父级的强类型 Viewed 中,我想在子级上 RenderPartial,并在 POST 之后保留结果。 但子字段始终为空。

这应该可行,不是吗?我对 MVC 相当陌生,希望我错过了一些简单的东西。希望有人能指点一下!

谢谢!

示例

ViewModel

public class EggBoxViewModel
{
    public string Brand { get; set; }
    public int Price { get; set; }
    public EggViewModel Egg { get; set; }
}

public class EggViewModel
{
    public string Size { get; set; }
    public bool IsBroken { get; set; }
}

Controller

public ActionResult Demo()
{
    EggBoxViewModel eggBox = new EggBoxViewModel();
    eggBox.Brand = "HappyEggs";
    eggBox.Price = 3;

    EggViewModel egg = new EggViewModel();
    egg.Size = "Large";
    egg.IsBroken = false;

    eggBox.Egg = egg;

    return View(eggBox);
}

[HttpPost]
public ActionResult Demo(EggBoxViewModel eggBox)
{

    // here, eggBox.Egg is null
}

观看次数 “演示”

@model MvcApplication1.ViewModels.EggBoxViewModel

@using (Html.BeginForm())
{
    <h2>EggBox:</h2>
    <p>
    @Html.LabelFor(model => model.Brand)
    @Html.EditorFor(model => model.Brand)
    </p>
    <p>
    @Html.LabelFor(model => model.Price)
    @Html.EditorFor(model => model.Price)
    </p>

    <p>
        @{Html.RenderPartial("_Egg", Model.Egg);}
    </p>

    <input type="submit" value="Submit" />
}

“_Egg”(部分)

@model MvcApplication1.ViewModels.EggViewModel

<h2>Egg</h2>
<p>
@Html.LabelFor(model => model.Size)
@Html.EditorFor(model => model.Size)
</p>
<p>
@Html.LabelFor(model => model.IsBroken)
@Html.CheckBoxFor(model => model.IsBroken)
</p>

最佳答案

使用编辑器模板,在大多数情况下,它们更适合渲染子对象或集合。在您的 Views\Shared 文件夹中创建一个名为 EditorTemplates 的新文件夹(如果您还没有)。添加一个名为 EggViewModel 的新分部 View ,并使用与分部 View 中相同的代码。这是正确渲染和命名所有字段的魔法。它还将处理 EggViewModel 的集合,而无需 foreach 循环,因为编辑器模板将自动渲染集合中传递的所有项目:

@model MvcApplication1.ViewModels.EggViewModel

<h2>Egg</h2>
<p>
@Html.LabelFor(model => model.Size)
@Html.EditorFor(model => model.Size)
</p>
<p>
@Html.LabelFor(model => model.IsBroken)
@Html.CheckBoxFor(model => model.IsBroken)
</p>

然后在演示 View 中使用新的编辑器模板而不是部分模板:

<p>
    @Html.EditorFor(x => x.Egg)
</p>

这里是呈现的字段:

Rendered fields

回帖中,您可以看到 EggViewModel 现在是 EggBoxViewModel 的一部分:

此外在 ModelState 中,您可以看到 Egg 字段以 EggBoxViewModel 中使用的属性名称为前缀,这使它们成为 EggBox 的子集。

而且...最棒的是,如果您想在 EggBox 中拥有一组 Eggs,这非常简单...只需将 EggBoxViewModel 上的 Egg 属性设置为一个集合即可:

public class EggBoxViewModel
{
    public string Brand { get; set; }
    public int Price { get; set; }
    public ICollection<EggViewModel> Eggs { get; set; }
}

添加第二个鸡蛋:

public ActionResult Demo()
{
    EggBoxViewModel eggBox = new EggBoxViewModel();
    eggBox.Brand = "HappyEggs";
    eggBox.Price = 3;

    EggViewModel egg = new EggViewModel();
    egg.Size = "Large";
    egg.IsBroken = false;

    EggViewModel egg2 = new EggViewModel();
    egg2.Size = "Medium";
    egg2.IsBroken = false;

    eggBox.Eggs = new List<EggViewModel>();

    eggBox.Eggs.Add(egg);
    eggBox.Eggs.Add(egg2); 

    return View(eggBox);
}

更改您的 View 以渲染 x.Eggs 而不是 x.Egg:

<p>
    @Html.EditorFor(x => x.Eggs)
</p>

然后在回发时您会看到回发了 2 个鸡蛋:

enter image description here

字段名称已自动索引并命名以创建鸡蛋集合:

enter image description here

关于asp.net-mvc-3 - 在 POST 上从 RenderPartial 检索 ViewModel 的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9433799/

相关文章:

asp.net-mvc - 将复选框值绑定(bind)到模型 mvc 中的列表

asp.net-mvc-3 - 在 MVC3 应用程序中获取 TinyMCE 下拉图像列表

c# - 在 blazor 中改变组件属性的正确方法

javascript - 如何检查浏览器是否支持&lt;input type ="time"/>

c# - MVC3 (Razor) 单选按钮检查

asp.net-mvc - 子目录中托管的 mvc3 应用程序的 Url.Action

json - ASP.NET MVC : Specify value provider on a per-action or per-route basis?

javascript - 在 Razor 中,接受不带小数的整数

c# - 在模型中绑定(bind)两个表 - ASP.NET MVC Razor

c# - 将 aspx url 路由到 MVC Controller