c# - MVC 3-这将如何运作?

标签 c# asp.net-mvc asp.net-mvc-3 poco

我已经在一年多以前发表了这篇文章,并且我认为更新它是有道理的,因为它获得了很多关注。

我要么错过了一些东西,要么微软真的搞砸了MVC。我从事过Java MVC项目,它们干净整洁。但是,这是一个完全困惑的IMO。在线示例(如NerdDinner)和ASP.Net上讨论的项目太基础了,因此为什么它们“简单”地工作。请问这听起来是否定的,但这是我到目前为止的经验。

我有一个存储库和一个与该存储库相关的服务。 Controller 调用服务。

我的数据层不是持久性独立的,因为这些类是由SQL metal生成的。因此,我有很多不必要的功能。理想情况下,我想拥有POCO,但是我还没有找到实现该目标的好方法。

*更新:当然,微软并没有搞砸任何事情-我做到了。我不完全了解我可以使用的工具。我所做的主要缺陷是,我选择了一种错误的技术来保留实体。 LINQ to SQL在有状态应用程序中效果很好,因为可以轻松跟踪数据上下文。但是,在无状态上下文中不是这种情况。正确的选择是什么?首先使用实体​​框架代码或仅将代码很好地工作,但更重要的是,它无关紧要。 MVC或前端应用程序必须不知道数据如何持久保存。 *

创建实体时,可以使用对象绑定(bind):

[HttpPost]
public ActionResult Create(Customer c)
{
    // Persistance logic and return view
}    

这很棒,MVC在后台进行了一些绑定(bind),一切都“非常好”。

不是“Jolly Good”。客户是一个域模型,更糟糕的是,它依赖于持久性介质,因为它是由SQL金属生成的。我现在要做的是设计域模型,该模型将独立于数据存储或表示层。然后,我将从我的域模型创建 View 模型,并使用它。

我想做一些更复杂的事情,例如-保存链接到客户的订单,似乎一切都中断了:
    [HttpPost]
    public ActionResult Create(Order o)
    {
        // Persistance logic and return view
    }

要保留顺序,我需要Customer或至少CustomerId。 View 中存在CustomerId,但是到创建方法时,它已经失去了CustomerId。我不想花时间调试MVC代码,因为我无法以任何一种方式在托管环境中对其进行更改。

好吧,抱歉。我现在要做的是根据我要实现的目标创建一个称为NewOrder或SaveOrder或EditOrder的 View 模型。这个 View 模型将包含我感兴趣的所有属性。开箱即用的自动绑定(bind),顾名思义,将绑定(bind)提交的值,并且不会丢失任何内容。如果我想要自定义行为,则可以实现自己的“绑定(bind)”,它将完成工作。

替代方法是使用FormCollection:
[HttpPost]
public ActionResult Create(FormCollection collection)
{
   // Here I use the "magic" UpdateModel method which sometimes works and sometimes doesn't, at least for LINQ Entities.               
}

这在书籍和教程中都使用过,但是我看不到有替代方法的要点:TryUpdateModel-如果崩溃或模型无效,它将尝试以任何一种方式进行更新。您如何确定这将起作用?

大多数情况下,使用 View 模型自动绑定(bind)。如果不是,则可以覆盖它。您怎么知道它将一直有效?您对它进行单元测试,就可以睡个好觉。

我尝试过的另一种方法是使用ViewModel-具有验证规则的包装对象。这听起来是个好主意,除了我不想向实体类添加注释。这种方法非常适合显示数据,但是在写数据时您会怎么做?
[HttpPost]
public ActionResult Create(CustomViewWrapper submittedObject)
{
    // Here I'd have to manually iterate through fields in submittedObject, map it to my Entities, and then, eventually, submit it to the service/repository.
}    

**查看模型是前进的好方法。从 View 模型到域模型必须有一些映射代码,然后可以将其传递给相关服务。这不是正确的方法,但这是一种方法。自动映射工具是您最好的 friend ,您应该找到适合您需求的工具,否则您将编写大量的样板代码。**

我错过了什么吗?还是Microsoft MVC3应该这样工作?我看不出这是如何简化事情的,尤其是与Java MVC相比。

很抱歉,这听起来很消极,但这是我到目前为止的经验。我欣赏以下事实:不断改进框架,引入了诸如UpdateModel之类的方法,但是文档在哪里?也许是时候停下来思考一下了吗?我希望我的代码在整个过程中保持一致,但是就目前为止所见,我不相信这是正确的方法。

我喜欢这个框架。有太多的东西要学习,而且没有比以往更令人兴奋的了。应该就网络表单发表另一篇文章。我希望这是有帮助的。

最佳答案

我认为您的问题不是与asp.net MVC有关,而是与您选择一起使用的所有部分有关。

您想要简单而原始吗?

到处使用POCO,并在需要的地方实现存储库。

我没有使用过Java MVC,但是如果您包括如何解决其中的特定问题,那么它会使整个问题看起来不太像是rant。

让我们清除一些误解或误解:

  • 您可以将复杂的对象通过帖子传递到 View 。但是您只想在有意义的情况下这样做,请参阅下一个项目符号
  • 您在此处选择的样本会发出一些警报。接受订单的客户数据或客户ID而不检查授权可能是一个很大的安全漏洞。对于订单,可以说相同的话,具体取决于您接受/允许的内容。无论使用POCO,LINQ,Asp.net MVC还是Java MVC,这都是使用ViewModel的巨大案例。
  • 您可以将未通过帖子显示的简单值传递给 View 。这是通过隐藏字段完成的(asp.net MVC支持该字段非常简单地使用模型值),在某些情况下,它会为您生成隐藏字段。
  • 您绝对不会被迫将linq2sql与Asp.net MVC一起使用。如果发现缺少打算如何使用它,请远离它。注意我喜欢linq2sql,但是它与如何使用asp.net mvc进行处理的 View 联系在一起是很奇怪的。
  • “我从事过Java MVC项目,它们干净整洁”。在项目上进行的工作与您自己设计项目不同。设计技巧确实会影响您从中获得的 yield 。并不是说您的情况,但只是想指出这一点,因为缺少有关Java MVC缺少的细节的信息。
  • “我的数据层不是持久性独立的,因为这些类是由SQL metal生成的。因此,我有很多不必要的功能。理想情况下,我希望拥有POCO,但是我没有找到一种实现的好方法这个呢”。您选择了错误的技术,linq2sql并不适合该要求。在我使用过的项目中,这并不是问题,但所有内容的设计方式都与您的具体要求相比没有什么联系。就是说,只是去别的地方。顺便说一句,您应该已经共享了与Java MVC一起使用的功能。
  • “ View 中存在CustomerId,但是到创建方法时,它已经失去了CustomerId。”如果该属性处于“顺序”状态,则可以打赌您的代码中有错误。现在,这将是一个完全不同的Real问题,为什么它不使用CustomerId/这样的问题将附带:您的Customer类,View,您要传递给View的内容...答案将包括但不仅限于:在浏览器中检查HTML源,以查看您实际在源中发布的值(或者使用 fiddler 进行查看),确保将CustomerId传递给View时确实具有该值。
  • 您说:““魔术” UpdateModel方法有时有效,有时无效”。这不是魔术,您可以看到它的作用,当然也可以找到有关它的信息。您发布的信息有误,我敢打赌,非必填字段或所解析信息的值不正确... View 支持为此添加验证。没有验证,这可能会缺乏。
  • 您在评论中说:“在调用UpdateModel之后,我无法显式设置CustomerId,我将不得不检索一个客户对象,然后将其分配给订单,这似乎是一个开销,因为我需要做的只是CustomerId” ...您接受作为用户输入的CustomerId(即使它是一个隐藏字段),您确实要验证该输入。此外,您自相矛盾,声称只需要CustomerId,但随后又说您需要与订单绑定(bind)相关的完整Customer对象。就是这样,如果仅绑定(bind)CustomerId,则仍然需要获取该Customer并将其分配给属性。除了场景之外,没有魔法...
  • 同样在评论中:“由于我不知道更新模型在LINQ实体中的表现,我现在正在完全避免使用该模型。在 View 模型类中,我创建了将LINQ实体转换为我的 View 模型的构造函数。 Controller 中的代码量减少,但仍然感觉不正确”。使用ViewModel(或EditModel)的原因不是因为它是linq2sql ...而是因为,除其他原因外,您正在暴露一个模型,该模型允许以超出您实际希望允许用户修改的方式进行操作。真正的问题是暴露原始模型(如果它具有不允许用户修改的字段)。
  • 关于c# - MVC 3-这将如何运作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5807669/

    相关文章:

    c# - 规则链的一条消息?

    css - 如何将媒体属性添加到 ASP.NET MVC4 样式包

    .net - MVC3 部分 View 和谷歌分析

    c# - 为什么类型转换很昂贵?

    c# - 从 WRL COM 组件获取托管回调

    c# - 为什么在 WPF 中尝试使用行为时会出现错误?

    asp.net-mvc - MVC 必需的字段验证不起作用

    javascript - 无法在 Kendo 窗口上显示加载微调器

    c# - 水平滚动时 Telerik Grid 样式不正确

    javascript - 正则表达式瑞典字母表和整个单词