Asp.net mvc 3 从后期渲染部分检索ViewModel的子集

Asp.net mvc 3 从后期渲染部分检索ViewModel的子集,asp.net-mvc-3,razor,Asp.net Mvc 3,Razor,我有一个ViewModel,其中包含一个子ViewModel。在父对象的强类型视图中,我希望在子对象上呈现部分,并在发布后保留结果。 但是子字段总是空的 这应该行得通,不是吗?我是MVC的新手,希望我错过了一些简单的东西。希望有人能指出这一点 谢谢 例子 视图模型 public class EggBoxViewModel { public string Brand { get; set; } public int Price { get; set; } public Eg

我有一个ViewModel,其中包含一个子ViewModel。在父对象的强类型视图中,我希望在子对象上呈现部分,并在发布后保留结果。 但是子字段总是空的

这应该行得通,不是吗?我是MVC的新手,希望我错过了一些简单的东西。希望有人能指出这一点

谢谢

例子 视图模型

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; }
}
控制器

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 mvcapapplication1.ViewModels.EggBoxViewModel
@使用(Html.BeginForm())
{
蛋盒:

@LabelFor(model=>model.Brand)
@EditorFor(model=>model.Brand)

@LabelFor(model=>model.Price) @EditorFor(model=>model.Price)

@{Html.RenderPartial(“_Egg”,Model.Egg);}

}
“鸡蛋”(部分)

@model mvcapapplication1.ViewModels.EggViewModel
鸡蛋

@LabelFor(model=>model.Size)
@EditorFor(model=>model.Size)

@LabelFor(model=>model.isbreak) @CheckBoxFor(model=>model.isbreak)


您必须将局部视图模型更改为
EggBoxViewModel
,以便将
Egg
对象显示在视图上。i、 e:

@model MvcApplication1.ViewModels.EggBoxViewModel
<h2>
    Egg</h2>
<p>
    @Html.LabelFor(model => model.Egg.Size)
    @Html.EditorFor(model => model.Egg.Size)
</p>
<p>
    @Html.LabelFor(model => model.Egg.IsBroken)
    @Html.CheckBoxFor(model => model.Egg.IsBroken)
</p>
现在,您应该看到模型中的
Egg
对象在
HttpPost
操作中返回

[更新方法2]

好的,真的很快编辑!!您可以保持一切与最初相同,并在您的部分中尝试这一点(我不是100%确定这会起作用):

@model mvcapapplication1.ViewModels.EggViewModel
鸡蛋

@LabelFor(model=>model.Size)
@编辑器(“Egg.Size”,Model.Size)

@LabelFor(model=>model.isbreak) @复选框(“Egg.isbreak”,Model.isbreak)


在这里,我只使用
@Html.Editor()
并输入所需的模型名,而不是
@Html.EditorFor()
。好的,戈拉·达什。。。列车到“缓存”;-)

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

@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>
public class EggBoxViewModel
{
    public string Brand { get; set; }
    public int Price { get; set; }
    public ICollection<EggViewModel> Eggs { get; set; }
}
@model mvcapapplication1.ViewModels.EggViewModel
鸡蛋

@LabelFor(model=>model.Size)
@EditorFor(model=>model.Size)

@LabelFor(model=>model.isbreak) @CheckBoxFor(model=>model.isbreak)

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

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

@EditorFor(x=>x.Egg)

这里是渲染的字段:

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

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

…最棒的是,如果你想在你的蛋盒中收集鸡蛋,这真的很容易…只需在EggBoxViewModel上创建鸡蛋属性集合:

@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>
public class EggBoxViewModel
{
    public string Brand { get; set; }
    public int Price { get; set; }
    public ICollection<EggViewModel> Eggs { get; set; }
}
公共类EggBoxViewModel
{
公共字符串品牌{get;set;}
公共整数价格{get;set;}
公共i集合{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);
}
public ActionResult Demo()
{
EggBoxViewModel eggBox=新的EggBoxViewModel();
egggbox.Brand=“HappyEggs”;
蛋盒价格=3;
EggViewModel egg=新的EggViewModel();
egg.Size=“大”;
egg.isbreak=false;
EggViewModel egg2=新的EggViewModel();
egg2.Size=“中等”;
egg2.isbreak=false;
egggbox.Eggs=新列表();
鸡蛋盒。鸡蛋。加入(鸡蛋);
鸡蛋盒。鸡蛋。加入(鸡蛋2);
返回视图(蛋盒);
}
更改视图以渲染x.Egg而不是x.Egg:

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

@EditorFor(x=>x.Eggs)

然后在回帖上,您将看到回帖中有两个鸡蛋:

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


谢谢,吉姆,这确实有效。但是,将其他“鸡蛋盒”字段传递到“鸡蛋部分”视图中似乎不太正确。我会认为,整个要点是让部分只关注鸡蛋?然后我可以以类似的方式从其他地方重复使用它。kezmondo-实际上,让我添加另一个替代方案(虽然这可能要等到我现在离开的时候),它允许模型仍然以纯粹的
Egg
的形式通过“Update method 2”传递,这些值最初不会出现在视图中(字段为空)。当我输入一些内容并提交时,这些值确实会返回到控制器。
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);
}
<p>
    @Html.EditorFor(x => x.Eggs)
</p>