C# 从Web服务检索下拉列表数据-模型vs控制器

C# 从Web服务检索下拉列表数据-模型vs控制器,c#,asp.net-mvc,wcf,asp.net-mvc-4,razor,C#,Asp.net Mvc,Wcf,Asp.net Mvc 4,Razor,ASP.NET MVC 4 | C | |.NET 4.5 | Razor 我有返回下拉列表数据的web服务。这些数据存储在我的模型中,然后由我的视图显示。目前,我正在控制器中进行web服务调用,并在将数据传递到视图之前将其分配给模型 我想知道这是一个好的设置,还是应该在模型中放置web服务调用?有关于web服务调用的最佳实践指南吗?他们应该严格从控制员那里打电话,还是无关紧要 提前谢谢 除非有显著的性能影响,否则理想的逻辑设置是在模型中进行 通常的说法是,“让你的控制器轻,模型重。”(我不知道

ASP.NET MVC 4 | C | |.NET 4.5 | Razor

我有返回下拉列表数据的web服务。这些数据存储在我的模型中,然后由我的视图显示。目前,我正在控制器中进行web服务调用,并在将数据传递到视图之前将其分配给模型

我想知道这是一个好的设置,还是应该在模型中放置web服务调用?有关于web服务调用的最佳实践指南吗?他们应该严格从控制员那里打电话,还是无关紧要


提前谢谢

除非有显著的性能影响,否则理想的逻辑设置是在模型中进行

通常的说法是,“让你的控制器轻,模型重。”(我不知道是谁第一次这么说。)

控制器不应填充模型。它应该只获取模型的一个实例并将其提供给视图。它最多应该执行一些路由逻辑(确定发送哪个视图,或者用重定向响应哪个视图,等等),并且基本上控制模型和视图/UI之间的交互

因此,不要像这样:

public ActionResult Index()
{
    var model = WidgetFactory.Create();
    model.SomeProperty = DataService.GetPropertyInfo();
    return View(model);
}
您应该这样做:

public ActionResult Index()
{
    var model = WidgetFactory.Create();
    return View(model);
}
在模型上使用此选项:

public SomeType SomeProperty
{
    get
    {
        return DataService.GetPropertyInfo();
    }
}
或者,如果在获取数据时存在开销:

private SomeType _someProperty = null;
public SomeType SomeProperty
{
    get
    {
        if (_someProperty == null)
            _someProperty = DataService.GetPropertyInfo();
        return _someProperty;
    }
}
这还有一个额外的好处,
SomeProperty
就模型而言变得不可变。因为它从不修改数据,只提供数据,所以没有理由为控制器可以使用的属性设置一个setter


这里的想法是,模型尽可能自包含和自给自足。或者尽可能地封装。它代表了业务概念本身。如果业务概念的一部分是存在于另一个系统上的数据,那么模型将封装该数据。控制器不负责实际知道
小部件
从何处获取
SomeProperty
的数据。它只知道
小部件
会公开这些数据。如果
小部件
得到它,则取决于
小部件

,除非有显著的性能影响,理想的逻辑设置是在模型中进行

通常的说法是,“让你的控制器轻,模型重。”(我不知道是谁第一次这么说。)

控制器不应填充模型。它应该只获取模型的一个实例并将其提供给视图。它最多应该执行一些路由逻辑(确定发送哪个视图,或者用重定向响应哪个视图,等等),并且基本上控制模型和视图/UI之间的交互

因此,不要像这样:

public ActionResult Index()
{
    var model = WidgetFactory.Create();
    model.SomeProperty = DataService.GetPropertyInfo();
    return View(model);
}
您应该这样做:

public ActionResult Index()
{
    var model = WidgetFactory.Create();
    return View(model);
}
在模型上使用此选项:

public SomeType SomeProperty
{
    get
    {
        return DataService.GetPropertyInfo();
    }
}
或者,如果在获取数据时存在开销:

private SomeType _someProperty = null;
public SomeType SomeProperty
{
    get
    {
        if (_someProperty == null)
            _someProperty = DataService.GetPropertyInfo();
        return _someProperty;
    }
}
这还有一个额外的好处,
SomeProperty
就模型而言变得不可变。因为它从不修改数据,只提供数据,所以没有理由为控制器可以使用的属性设置一个setter


这里的想法是,模型尽可能自包含和自给自足。或者尽可能地封装。它代表了业务概念本身。如果业务概念的一部分是存在于另一个系统上的数据,那么模型将封装该数据。控制器不负责实际知道
小部件
从何处获取
SomeProperty
的数据。它只知道
小部件
会公开这些数据。
小部件
的位置取决于
小部件

只要控制器更精简且可测试,您就可以选择任何您喜欢的方法。请注意,您还希望确保视图模型简单而愚蠢。您不希望在视图模型中放置太多行为

public class MyViewModel
{
    public IEnumerable<SelectListItem> CustomerList { get; set; }
}
视图模型可以如此简单。我不希望在视图模型中有太多的行为或对服务的调用

public class MyViewModel
{
    public IEnumerable<SelectListItem> CustomerList { get; set; }
}

只要您的控制器更精简且可测试,就可以选择任何您喜欢的方法。请注意,您还希望确保视图模型简单而愚蠢。您不希望在视图模型中放置太多行为

public class MyViewModel
{
    public IEnumerable<SelectListItem> CustomerList { get; set; }
}
视图模型可以如此简单。我不希望在视图模型中有太多的行为或对服务的调用

public class MyViewModel
{
    public IEnumerable<SelectListItem> CustomerList { get; set; }
}

方法不错,我也喜欢这个解决方案。但我不明白你所说的“除非对性能有重大影响”是什么意思?@Raj:我现在想不出一个例子,但总的来说,在软件设计的任何地方,系统的物理限制迫使我们在其他良好的逻辑设计选择上妥协。基本上,如果你想不出一个原因,那么你就不需要面对它,也不需要担心它。当出现性能问题时,通常很明显:)有意义。谢谢:)谢谢!这很有道理。我想我要把它放在getter中,就像你在上一个例子中演示的那样。方法不错,我也喜欢这个解决方案。但我不明白你所说的“除非对性能有重大影响”是什么意思?@Raj:我现在想不出一个例子,但总的来说,在软件设计的任何地方,系统的物理限制迫使我们在其他良好的逻辑设计选择上妥协。基本上,如果你想不出一个原因,那么你就不需要面对它,也不需要担心它。当出现性能问题时,通常很明显:)有意义。谢谢:)谢谢!这很有道理。我想我要把它放在getter中,就像你在上一个例子中演示的那样。