在哪里放置与视图数据无关的额外视图数据

Where to put extra view data that doesnt relate to view data

所以,让我们看一个例子。我有一个如下所示的客户视图模型:

public class CustomerViewModel {
    public string Name {get; set;}
    public int CustomerTypeId {get; set;}
}

在 UI 上需要有一个客户类型下拉列表。为了填充它,需要进入业务层或数据层并获取此客户类型列表。

在我看来,这个逻辑并不真正属于 CustomerViewModel,因为它不是真正的客户数据;只有 CustomerTypeId 是。所以我的问题是,一般情况下(不一定在 .net MVC 中,但 MVC 视图模型概念的一般做法)人们将此数据访问放在何处?

在视图模型本身中有一个名为 GetCustomerTypes() 的函数是否可以接受?

public class CustomerViewModel {
    public string Name {get; set;}
    public int CustomerTypeId {get; set;}

    public List<CustomerType> GetCustomerTypes() { ... }
}

是否应该在业务层做一个class/method或者helper然后在视图中手动导入代码来访问这个功能?在我看来,这将是使视图混乱且不属于该视图的代码。

@{
    using My.App.CustomerTypeHelper;
    var helper = new CustomerTypeHelper();
    var customerTypes = helper.GetCustomerTypes();
}

...

@Html.DropDownFor(x => x.CustomerTypeId, customerTypes)

全局 Html 帮助程序在 .Net 中稍微缓解了这个问题,但我正在寻找概念上更全局的解决方案,我也可以将其应用于 PHP 代码等。 PHP 没有能力干净利落地拥有一个静态的 class,它可以通过扩展方法分成小的有组织的单元。所以任何全局助手都可能变得又大又丑。

您应该在模型中包含 List<CustomerType> 但不要在模型中实现函数。改为从控制器设置数据。

像这样:

public class CustomerViewModel {
    public string Name {get; set;}
    public int CustomerTypeId {get; set;}

    public List<CustomerType> CustomerTypes { get; set; }
}

从 Controller 向 ViewModel 分配数据:

var model = new CustomerViewModel();
model.CustomerTypes = Customer.GetCustomerTypes();

您可以在具有此类数据的所有定义的模型之间有一个 class,即 'shared'。我会选择诸如:

public static partial class StaticData
{
    public static List<CustomerType> CustomerTypes = new Lisr<CustomerType>
    {
        new CustomerType { Name = "Whatever", Discount = 10, ....... },
        new CustomerType { Name = "Another", Discount = 0, ........}
        // etc
    }
}

请注意,这是部分 class,因此您可以将其拆分到项目中的 files/folders 并具有:

CustomerTypes.cs
SupplierTypes.cs
ProductTypes.cs

以及所有其他作为单独文件的所有内容都构建到一个共享的 StaticData class 中,最终包含您对 drop-downs 的所有定义和任何其他 non-database 信息。

那么,在您看来,您可以使用 StaticData.CustomerTypes 填充 select 选项。

CustomerModel(不是ViewModel,因为MVC中没有ViewModel)不是一个Customer。它是视图 Customer 中使用的模型。如果那个视图需要这个信息,它应该在那个模型中。

我不清楚该视图在您的应用程序中的作用,但它看起来像是某种客户创建表单。仅仅称它为 CustomerModel 并不能很好地解释 class 的意图。您可能想要调用您的模型 CreateModel,用于从 CustomerController 中的 Create() 方法返回的 Create.cshtml。然后向此模型添加 CustomerTypes 是有意义的:如果要创建客户,则需要 CustomerTypes。