我有一个View类(OrderView.aspx),它显示订单的详细信息(帐户名称,订单日期)以及通过Repeater控件的订单行列表。每个订单行由用户控制视图(OrderLineView.ascx)表示,该视图显示订单行的详细信息(项目名称,数量,价格)。我有一个名为Order的模型对象,我将其用作所有这些的数据源,我将其作为视图的模型对象传递。
每个OrderLineView用户控件都有一个“保存”和“删除”按钮。我有Save按钮将OrderLine控件中的表单内容发布到Controller上的Save方法,然后RedirectToAction返回到同一Order页面(这会刷新整个页面,没有关于它的AJAXy)。我有删除按钮链接到Controller上试图删除的方法,然后RedirectToAction链接到同一个Order页面。但是,如果删除失败,我想在页面再次呈现时在删除按钮旁边显示一条小错误消息(请记住,页面上的每个订单行都有一个删除按钮,所以我只想要旁边的消息我点击的那个)。我的问题:
1 - 如何将此数据从Controller方法传递到特定用户控件?我应该以某种方式将其添加到模型中吗?似乎是一个坏主意(因为它确实不是模型的一部分)。
2 - 我是否应该为OrderLine操作配置OrderLineController以及为Order操作设置OrderController?我只是想知道最佳做法是为每个视图设置一个单独的控制器。
3 - 我已经看到有些人可能会使用这样的匿名类型值调用RedirectToAction:
RedirectToAction("ViewOrder", new { Id = 1234, Message = "blabla"});
但这会使Message值显示在URL字符串中。我对此感到满意,但如果可能的话,我希望它不显示。
4 - 另外,为了从视图中访问Model的属性,我发现自己一直这样做:
foo(((someModelType) this.ViewData.Model).SomeProperty);
我不喜欢这个有很多原因,其中一个原因是我不希望我的视图与我的模型类型相结合(这就是我使用ViewPage而不是ViewPage的原因) 。我更愿意接受这样的电话:
foo(ModelEval("SomeProperty"));
有这样的事吗?我已经写了自己的,但如果我没有,我会喜欢它。
答案 0 :(得分:3)
查看ModelState。
ViewData.ModelState.AddModelError("something.Name", "Please enter a valid Name");
ModelState实际上是一个字典,因此您可以基于每个控件识别错误。我不知道这是不是最好的做法,但它可能会奏效。 尝试一下
的内容ViewData.ModelState.AddModelError("something#3.Name", "Please enter a valid Name");
在你看来,你可以把
<%= Html.ValidationMessage(string.format({"something{0}.Name", YourUniqueId))%>
你可以强烈地输入你的视图,所以你不需要那个演员,但如果你担心紧密耦合,这可能会让你失望。但是拥有强类型并没有比使用魔术字符串指向模型的属性更紧密耦合。前者只是为您提供类型安全和智能感知的荣耀。
答案 1 :(得分:1)
由于OrderLine具有唯一ID,因此您可以使用它来构造要放置在ModelState错误容器中的密钥。
public ActionResult Delete(int? Id)
{
ModelState.AddModelError("OrderLine" + Id.Value, "Error deleting OrderLine# " + Id.Value);
...
}
然后使用ValidatinoMessage帮助程序。这将检查ModelState以查看是否存在错误,如果存在错误,则会显示该消息。否则它是空白的。
<%= Html.ValidationMessage ("OrderLine" + Id)%>
在下一个版本的MVC Model中将成为顶级属性,所以下面的
foo(((someModelType) this.ViewData.Model).SomeProperty);
可以写成
foo(Model.SomeProperty);
除非您将公共对象用作属性,否则应该已经键入模型对象?