【问题标题】:Should View Models in ASP.Net MVC be all strings?ASP.Net MVC 中的视图模型应该都是字符串吗?
【发布时间】:2026-01-11 21:30:02
【问题描述】:

我的意思是(无意中)我觉得在某些部分我在视图 (.aspx) 本身内做的太多了,太多的格式,连接,在一个地方有点正则表达式替换。

我开始研究一个新部分并尝试改进我的方法。然后我突然想到为什么我不制作我所有的视图模型(在 /Models/ .Web 项目中)字符串或列表字符串一推。注意:我不是指我的模型/域,而是专门指我的 ViewModel。

public class FinanceQuoteView
{
    public string Provider; 
    public string Broker; // rather than Broker == null ? "N/A" : Broker.ToUpperCase();
    public string Monthly; // rather than Monthly.ToString("C")
    public string PaymentTerm; // rather than "1+" + PaymentTerm.ToString();
    public string FreeInsurance; // rather than insuranceIncluded ? "Yes" : "No";
    public string[] Restrictions;
}

对于表单提交(添加编辑),我使用单独的视图模型来提供控制器操作(如果您将在 /Models/Form 中使用表单模型)。所以 FinanceQuoteForm 确实包含双打等...通过活页夹构建。

大家对这种方法有什么看法?在从域到视图模型的映射中执行 .ToString("C") 太多了吗?

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    您的模型应该生成正确的数据,然后由视图以它需要的格式生成数据。如果您在模型之上构建了另一个视图,您可能想要对数据进行不同的操作,因此我建议 NOT 从模型中将它们作为字符串返回。

    【讨论】:

    • 他不是在谈论领域模型——他是在谈论视图模型。
    • 马克。正确的。我不是指我的模型。我特别指的是我的控制器操作生成的视图模型(手动、自动映射器或其他任何东西 - 小的 impl 细节)并发送到视图进行渲染。
    • 我同意ck,视图模型是“格式化”数据的模型。通过仅传递字符串,您将失去视图模型格式化数据的机会。我可以举一个简单的例子,如果您将“日期”作为字符串传递给视图模型,那么您需要在控制器中进一步操作以将内容提供给美国访问者或英国访问者。
    • xandy,有趣的一点,但我认为本地化应该在控制器级别考虑额外的逻辑或映射代码的一部分。正如 Mark 在下面建议的那样,这样您可以轻松测试,我看不出您将如何保存将其推送到视图的任何代码(实际上您可能会有重复)
    • 与组件的可重用性相比,代码节省不应成为任何问题。我认为 ck 指出一个非常重要的问题是,您应该能够在同一个控制器之上构建另一个视图。以日期为例(再次!),映射和本地化逻辑可以在控制器级别执行是对的,但是长日期和短日期问题呢?考虑一个场景,我只会在移动平台上给出短日期,但在桌面平台上给出长日期字符串。在字符串中创建日期只是让控制器过多地参与格式化。
    【解决方案2】:

    对于我设计的视图模型,我自己倾向于非常依赖字符串。毕竟,View 中显示的大部分数据都是以字符串的形式出现的。每当我要在视图 (.aspx/.ascx) 中执行数据操作时,我都会认真考虑将该逻辑下推到我的视图模型中,以便我可以对其进行单元测试。毕竟,可测试性是您从 MVC 中获得的主要好处,那么为什么不使用它呢?

    在 WPF 中(只是绕道而行),许多控件本身就可以理解其他类型的数据(例如数字、布尔值等),但是在像 HTML 这样固有地与字符串绑定的平台上,它使将大部分输出视为文本对我来说很有意义。

    无论如何,所有数据都必须在服务器和浏览器之间来回传输,编码为字符串,因此通常情况下,您只需明确说明即可。

    我绝对不认为它太多 - 我只是认为你可以做得太少:)

    【讨论】:

    • “每当我要在视图 (.aspx/.ascx) 中执行数据操作时,我都会认真考虑将该逻辑下推到我的视图模型中,以便我可以对其进行单元测试。”你能详细说明那部分吗?我打算路由一个单独的视图模型进行编辑,但我对你的方法很感兴趣
    • 我认为我们在谈论同一件事,但我可能表达得不太清楚。对于数据操作,我只是在考虑诸如货币格式、字符串连接等小事——你知道:在数据流向输出流的过程中对其进行操作。让一个视图模型用于显示和另一个用于编辑对我来说听起来很合理。在 HTTP 的无状态世界中,一个是输出,另一个是输入。它们是非常不同的东西,不应混淆。将它们建模为不同的模型可以非常清楚地捕捉到这种区别。
    【解决方案3】:

    基本上同意。对于传统的编辑表单,我更喜欢为“后模型”(传递给控制器​​)​​和视图/编辑“视图模型”(传递给视图)设置单独的模型。

    后模型属性都是字符串。这使我可以确定帖子中是否包含某个字段,有些则没有,这对我的应用程序非常重要。

    后模型提供给我的控制器操作,然后确定要执行的命令(如果有)。

    从那里,如果控制器操作导致查看视图/编辑页面,那么我相应地构建视图模型,并将其提供给视图。

    因此,我可以将视图模型的属性设置为任何我想要的类型。它们不必与帖子模型的类型相匹配。

    超级干净,让我可以完全控制一切。

    【讨论】:

      【解决方案4】:

      您的情况在某种程度上非常特殊和有限:您的 ViewModel 要么用于编辑,要么用于显示。大多数视图两者兼而有之:它们有很多显示内容和一些编辑内容。让我们说这个页面:

      显示问题、答案和注释。编辑:回答。

      我不想区分 2。它会以重复很多显示字段而告终。

      我宁愿有一个可能有 2 个属性的视图:一个用于显示,一个用于表单值。

      【讨论】:

        最近更新 更多