首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重构fat ASP.NET MVC控制器

重构fat ASP.NET MVC控制器
EN

Code Review用户
提问于 2014-08-04 18:16:19
回答 1查看 1.6K关注 0票数 3

我刚刚开始将一个老项目移植到ASP.NET MVC。最后,我将有许多控制器方法,如下所示,这些方法由页面中的JQGrid对象执行的AJAX请求调用:

AJAX请求:

/UserRole/RolesByUserGridData?userId=2&_search=false&nd=1407171194811&rows=10&page=1&sidx=RoleName&sord=asc

控制器代码:

代码语言:javascript
复制
public ActionResult GetRolesByUserGridData(MvcJqGrid.GridSettings gridSettings, int userId)
    {
        IQueryable<Role> allRoles = _roleRepository.GetAsQueryable(where:null, includeProperties:"");
        IQueryable<UserRole> userRolesByUser = _repository.GetAsQueryable(where: c => c.UserId == userId, includeProperties: "Role");

        var gridItems = from role in allRoles
                        join userRole in userRolesByUser on role.Id equals userRole.RoleId into loj
                        from item in loj.DefaultIfEmpty()   // LEFT OUTER JOIN equivalent 
                        select new UserRoleByUserViewModel
                        {
                            IsRoleAssociatedWithUser = (item.UserId == userId),
                            RoleName = role.Name
                        };

        SortOrder sortOrder = gridSettings.SortOrder != "desc" ? SortOrder.Asc : SortOrder.Desc;

        var pagedOrderedItems = PagingHelper<UserRoleByUserViewModel>.GetAsOrderedPagedList(
            gridItems, sortOrder, gridSettings.SortColumn,
            gridSettings.PageIndex, gridSettings.PageSize);

        var jsonData = new
        {
            total = pagedOrderedItems.TotalItemCount / gridSettings.PageSize + 1,
            page = gridSettings.PageIndex,
            records = pagedOrderedItems.TotalItemCount,
            rows = (
                from c in pagedOrderedItems
                select new
                {
                    id = "",
                    cell = new[]
                    {
                        "Edit", 
                        "Details",
                        c.IsRoleAssociatedWithUser.ToString(),
                        c.RoleName
                    }
                }).ToArray()
        };

        return Json(jsonData, JsonRequestBehavior.AllowGet);
    }

我的目标是从存储库返回IEnumerable,并拥有相当愚蠢的控制器。

你怎么建议重构这个?

理想情况下,我的控制器方法中的代码应该是:

代码语言:javascript
复制
public ActionResult GetRolesByUserGridData(MvcJqGrid.GridSettings gs, int userId)
{
   var json = _userRoleService
      .GetRolesByUser()
      .ToOrderedList(“Id”, “Asc”)
      .ToPagedList(gs.PageIndex, gs.PageSize)
      .ToJsonData(); 
   return Json(jsonData, JsonRequestBehavior.AllowGet);
}

其中ToOrderedList()ToPagedList()ToJsonData()将是IQueryable<>的扩展方法,放置在Web项目之外。

但我仍然不清楚,在这种情况下,ViewModels应该住在哪里:

A.将它们放在服务层中,这是在一个不同的项目中,但是它们会丢失与数据注释相关的所有逻辑,或者我需要在服务层引用MVC,这似乎很奇怪。

把它们放在网络项目中--但是为什么服务不应该知道ViewModel,而只检索ViewModel需要的数据呢?是否真的需要创建一个新的DTO对象才能将数据从服务传递给控制器?

EN

回答 1

Code Review用户

发布于 2014-08-06 11:21:21

我可以从这段代码中看到一些问题。

存储库位于表示层。一个大的不不。这是软件101,不要将数据访问放在表示层,也不太好地将业务逻辑放在表示层。

那些_roleRepository调用需要进入一个RoleRetrievalService或类似的东西。这集中了业务逻辑。

您的存储库应该位于服务层后面,该层处理对DAL的所有调用。您的服务层应该包含业务逻辑和数据转换,从而将这些DAL实体转换为表示层可以使用的模型。

执行左联接的查询应该在服务层中,其中包含执行作为参数传入的查询所需的参数。您也可以传递排序选项。

构建结果(jsonData)的最后一条语句正是服务层应该产生的结果。

这都取决于你有多少时间和你想要承担多少技术债务:)

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/59041

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档