c# - MVC - 具有多个选择列表的 Controller

标签 c# asp.net-mvc

当 Controller 的模型依赖于大量选择列表时,有什么好的方法可以让 Controller 变得更简单吗?我尝试让大部分 Controller 操作尽可能简单(希望不超过 10 行左右),但在需要大量下拉列表的页面上,我的操作通常会超出此范围:

public class Model
{
    public IEnumerable<SelectListItem> AllLocations { get; set; }
    public IEnumerable<SelectListItem> TopLocations { get; set; }
    public IEnumerable<SelectListItem> AllTemplates { get; set; }
    public IEnumerable<SelectListItem> TopTemplates { get; set; }
    // ...
}

[HttpGet]
public ActionResult Index(int id)
{
    var domain = Repository.Get(id);
    var model = Mapper.Map<Domain, ViewModel>(item);

    // any way to abstract this type of code?
    model.AllLocations = new SelectList(repository.GetAllLocations(), "Value", "Text");
    model.TopLocations = new SelectList(repository.GetTopLocations(), "Value", "Text");
    model.AllTemplates = new SelectList(repository.GetAllTemplates(), "Value", "Text");
    model.TopTemplates = new SelectList(repository.GetTopTemplates(), "Value", "Text");
    // etc. etc.

    return View(model);
}

[HttpPost]
public ActionResult Index(ViewModel model)
{
    // any way to abstract this type of code?
    model.AllLocations = new SelectList(repository.GetAllLocations(), "Value", "Text");
    model.TopLocations = new SelectList(repository.GetTopLocations(), "Value", "Text");
    model.AllTemplates = new SelectList(repository.GetAllTemplates(), "Value", "Text");
    model.TopTemplates = new SelectList(repository.GetTopTemplates(), "Value", "Text");
    // etc. etc.

    return View(model);
}

最佳答案

正如你所说,保持 Controller Action 较小是很好的。正如吉米·博加德所说 put your controllers on a diet !

我将 IModelEnricher 与 Automapper 结合使用。我使用特定的 ActionResult 返回一个实体等,然后将我的实体自动映射到 ViewModel 并丰富选择列表所需的数据(以及所需的任何其他数据)。这种方法使您的代码保持干燥,并且 Controller 像 super 模型一样瘦:-)!此外,将选择列表数据保留为 ViewModel 的一部分可以使 Controller 、模型和 View 职责保持清晰。

定义 ViewModel ernicer 意味着在使用 ViewModel 的任何地方都可以使用相同的丰富器来获取其属性。因此,您可以在多个位置返回 ViewModel,它只会填充正确的数据。

就我而言, Controller 中看起来像这样:

public virtual ActionResult Edit(int id)
{
    return AutoMappedEnrichedView<PersonEditModel>(_personRepository.Find(id));
}

[HttpPost]
public virtual ActionResult Edit(PersonEditModel person)
{
     if (ModelState.IsValid){
            //This is simplified (probably don't use Automapper to go VM-->Entity)
            var insertPerson = Mapper.Map<PersonEditModel , Person>(person);
            _personRepository.InsertOrUpdate(insertPerson);
            _requirementRepository.Save();
            return RedirectToAction(Actions.Index());
      }
     return EnrichedView(person);
 }

这种 ViewModel:

public class PersonEditModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
    public int FavouriteTeam { get; set; }
    public IEnumerable<SelectListItem> Teams= new List<SelectListItem>();
}

使用这种丰富器:

public  class PersonEditModelEnricher :
IModelEnricher<PersonEditModel>
{
    private readonly ISelectListService _selectListService;

    public PersonEditModelEnricher(ISelectListService selectListService)
    {
        _selectListService = selectListService;
    }

    public PersonEditModelEnrich(PersonEditModel model)
    {
        model.Teams = new SelectList(_selectListService.AllTeams(), "Value", "Text")
        return model;
    }
} 

另一种选择是使用属性来装饰 ViewModel,这些属性定义如何定位数据以填充选择列表。喜欢:

  public class PersonEditModel
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public int FavouriteTeam { get; set; }
        [LoadSelectListData("Teams")]
        public IEnumerable<SelectListItem> Teams= new List<SelectListItem>();
    }

现在,您可以使用以下属性在选择的服务中装饰适当的方法:

   [ProvideSelectData("Teams")]
   public IEnumerable Teams()
   {
        return _teamRepository.All.ToSelectList(a => a.Name, a => a.TeamId);
   }

对于没有复杂丰富的简单模型,只需通用的丰富过程就可以处理它。如果您想做任何更复杂的事情,您可以定义一个丰富器,如果存在,就会使用它。

查看此question 。还有这个blog postthis 。还有这个question在 Automapper 论坛上

关于c# - MVC - 具有多个选择列表的 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9136091/

相关文章:

c# - Xamarin 表单 : how to implement platform specific code

c# - 将 n 个数据表组合成一个数据表

c# - 如何使用 Expression 构建匿名类型?

c# - ASP.Net MVC 添加寻呼机但找不到路由

c# - ASP.NET MVC AsyncController 和 IO 绑定(bind)请求

c# - 如何在Linq to SQL中区分大小写相等的两个字符串?

c# - 如何使用 C# 模拟 CTRL+V 击键(粘贴)

c# - 从 Entity Framework 中自动生成的类继承

javascript - ASP.NET MVC : Javascript error logging in production environement

asp.net-mvc - 使用 "RedirectToAction"从 Controller 重定向到哈希值