【问题标题】:Best practice for passing extra data along model to view?将额外数据沿模型传递以查看的最佳实践?
【发布时间】:2017-08-03 03:03:45
【问题描述】:

有时您需要向视图传递一些额外的数据。例如添加新闻页面中的新闻组,应该从数据库中检索。

我知道在视图中创建 Db-context 实例并不是这样做的好习惯。相反,我们可以向视图模型添加一些属性并将这些数据传递给视图或使用 View-Bag 并对其进行类型转换,但在这些情况下,您可能需要在 HttpGet 和 HttpPost 中编写一些代码,当您需要在 Get 和 Post 方法中返回相同的视图。

进行此类操作的最佳做​​法是什么?有没有别的办法写一次?

【问题讨论】:

  • 感谢您的回答,正如我所说,我知道如何在 View-Model 中传递这些额外的数据,什么是 View-Model,我们应该如何以及为什么要使用这个 View-Model 来分离业务逻辑和 UI 逻辑。
  • 我想知道是否有另一种方法可以更好地匹配这些情况。保持 View-Model 简单的任何其他想法?

标签: asp.net-mvc


【解决方案1】:

据我了解,您似乎对自己需要做的事情有所了解,但不喜欢 get 和 post 操作之间的代码重复。为此,只需将公共代码分解为控制器上两个操作都可以调用的受保护或私有方法。例如,假设您需要一个 Foo 项目的选择列表:

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

然后:

public class MyController : Controller
{
    ...

    private void PopulateFooOptions(MyViewModel model)
    {
        var foos = db.Foos.ToList();
        model.FooOptions = foos.Select(f => new SelectListItem { Value = f.Id.ToString(), f.Name });
    }

    public ActionResult Create()
    {
        var model = new MyViewModel();
        PopulateFooOptions(model);
        return View(model);
    }

    [HttpPost]
    public ActionResult Create(MyViewModel model)
    {
        if (ModelState.IsValid)
        {
            // do stuff
        }

        PopulateFooOptions(model);
        return View(model);
    }
}

【讨论】:

    【解决方案2】:

    要编写一次组件并在不同的视图中重用它,请将组件打包到自己的操作中,并使用自己的ViewModelPartial View

    如果无法从外部单独调用此操作,请将其标记为[ChildActionOnly]。数据库访问应该发生在这个子操作中,数据应该使用 ViewModel 传递给 View。

    在需要时使用 @Html.Action("{actionName}", "{controllerName}") 渲染由此操作生成的 HTML。

    例如:

    NewsController 包含子操作:

    [ChildActionOnly]
    public PartialViewResult ShowNewsGroups(long userId) {
    
        var data = // ... read from DB using userId parameter
        var vm = new ShowNewsGroupsViewModel {
               GroupInfos = data
        };
    
        return PartialView("_ShowNewsGroups", vm);
    }
    

    部分视图 _ShowNewsGroups.cshtml 呈现新闻组:

    @model ShowNewsGroupsViewModel 
    @for(var i = 0; i < Model.GroupInfos.Count(); i++) {
        @Html.DisplayFor(m => m.GroupInfos[i])
    }
    

    主视图调用子动作并传递所需参数:

    @Html.Action("ShowNewsGroups", "News", new { userId = Model.UserId }))
    

    【讨论】:

      【解决方案3】:

      出于这个特定原因,我们使用 ViewModel 概念 它只是一个需要属性的模型

      例如,假设您有一个名为 test 的模型,现在您想传递一些附加属性,例如 isValid 的布尔值和创建的日期时间 所以

      您的视图 =model 将是

      public class YourViewMode
      {
      public test mainModel{get;set;}
      public bool isValid {get;set;}
      public datetime Created {get;set;}
      }
      

      现在只需将此模型初始化为您的视图,这就是视图模型的基本工作方式

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-22
        • 2014-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-27
        相关资源
        最近更新 更多