0

ASP.NET MVC 4 | C# | .NET 4.5 | 剃刀

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

我想知道这是否是一个好的设置,或者我是否应该将我的网络服务调用放在我的模型中?是否有关于 Web 服务调用的最佳实践指南?是否应该从控制器严格调用它们,还是无关紧要?

提前致谢!

4

2 回答 2

2

除非对性能产生重大影响,否则理想的逻辑设置是在模型中进行。

通常的引用是,“保持你的控制器轻而你的模型重”。(不知道是谁先说的。)

控制器不应填充模型。它应该只获取模型的一个实例并将其提供给视图。最多它应该做一些路由逻辑(确定发送哪个视图,或者用重定向响应等),基本上,控制模型和视图/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不可变的额外好处。由于它从不修改该数据并且只提供它,因此没有理由为控制器可以使用的该属性设置一个设置器。

这里的想法是模型尽可能自包含和自给自足。或者尽可能封装。它本身就代表了业务概念。如果该业务概念的一部分是存在于另一个系统上的数据,则模型会封装它。Widget实际了解 a获取数据的位置不是控制器的责任SomeProperty。它只知道 aWidget公开了该数据。在哪里Widget得到它取决于Widget

于 2013-10-04T23:13:19.480 回答
1

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

您的视图模型可以像这样简单。我宁愿在我的视图模型中没有太多的行为或对服务的调用。

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

我会创建一个简单的扩展方法或帮助类,将我的域数据转换为 DropDownList 视图模型,即 SelectListItem

internal static class ListHelper
{
    internal static MyViewModel ConvertToMyViewModel(this IEnumerable<Customer> customers)
    {
        //Assign customers to CustomerList;
        //MyViewModel.CustomerList
        return new MyViewModel();
    }
}

请注意,您以后可能会发现自己在想要隐蔽时重复类似的代码。您始终可以创建通用版本,因此方法是可重用的。但关键是您的扩展/辅助方法可以帮助您进行转换。它只做转换,但没有别的。

将您的服务注入控制器。如果您使用任何一种,请利用您最喜欢的二元注入框架。您的控制器是可测试的。

public class HomeController : Controller
{
    private readonly IWebService _webServiceInfo;

    public HomeController(IWebService webServiceInfo) {
        _webServiceInfo = webServiceInfo;
    }

    public ActionResult Index() {
        var customers = _webServiceInfo.GetCustomers();
        var viewModel = customers.ConvertToMyViewModel();

        return View(viewModel);
    }
}
于 2013-10-05T00:08:44.253 回答