从 Web 服务 - 模型与控制器检索下拉列表数据
本文关键字:控制器 检索 下拉列表 数据 模型 Web 服务 | 更新日期: 2023-09-27 18:34:10
ASP.NET MVC 4 |C# | .NET 4.5 |剃刀
我有返回下拉列表数据的 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
变得不可变。 由于它从不修改该数据,并且只提供该数据,因此没有理由为控制器可以使用的该属性设置器。
这里的想法是,该模型尽可能自包含和自给自足。 或尽可能封装。 它本身就代表了业务概念。 如果该业务概念的一部分是存在于另一个系统上的数据,则模型会封装该数据。 控制者不负责实际知道Widget
从何处获取其数据以进行SomeProperty
。 它只知道Widget
公开了该数据。 Widget
从哪里得到取决于Widget
.
您的控制器更精简且可测试,您可以选择任何您喜欢的方法,就很少有方法可以做到。请注意,您还希望确保视图模型简单而愚蠢。您不希望在视图模型中放置太多行为。
您的视图模型可以如此简单。我不希望在我的视图模型中有太多的行为或对服务的调用。
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();
}
}
请注意,您以后可能会发现自己在想要隐蔽时重复类似的代码。您始终可以创建泛型版本,因此方法可重用。但关键是您的扩展/帮助程序方法可帮助您转换。它只进行转换,但不进行其他转换。
将您的服务注入控制器。利用您的 faviourite 双元注入框架(如果您使用任何框架(。您的控制器是可测试的。
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);
}
}