【问题标题】:How to pass a strongly typed model and a list of models to a view simultaneously如何将强类型模型和模型列表同时传递给视图
【发布时间】:2017-10-31 01:18:25
【问题描述】:

我的最终目标是将强类型模型(以填充下拉菜单)和模型列表(基于搜索查询)同时从控制器传递给视图。我将其传递给的视图是“Clear()”视图。目前在我的 HomeController.cs 我有:

public ActionResult Clear()
    {
        var states = GetAllStates();

        var model = new ProjectClearanceApp.Models.Project();

        model.States = GetSelectListItems(states);

        return View(model);
    }

    private IEnumerable<string> GetAllStates()
    {
        return new List<string>
        {
            "AL",
             // ... (you get the point)
            "WY",
        };
    }

    private IEnumerable<SelectListItem> GetSelectListItems(IEnumerable<string> elements)
    {
        var selectList = new List<SelectListItem>();

        foreach (var element in elements)
        {
            selectList.Add(new SelectListItem
            {
                Value = element,
                Text = element
            });
        }

        return selectList;
    }

我在某处读到,这是获取下拉菜单选项列表的最佳方式。现在我还想根据搜索查询将模型列表传递给同一视图(Clear.cshtml)。我正在阅读from this Microsoft tutorial 以通过添加在控制器操作中搜索该视图

public ActionResult Index(string searchString)
{
    var movies = from m in db.Movies
                 select m;

    if (!String.IsNullOrEmpty(searchString))
    {
        movies = movies.Where(s => s.Title.Contains(searchString));
    }

    return View(movies);
}

到控制器。如何将下拉选项列表和适合搜索的模型列表从控制器传递到视图(或者,如何在不从控制器传递两者的情况下实现相同的效果)?

【问题讨论】:

  • 通过另一个封装它们的模型
  • 没有任何理由写from x in y select x
  • @SLaks 这是一个很好的观点。如何重写 select 语句以在选择而不是从数据库中获取完整的电影列表然后搜索时进行搜索?
  • @B.Fitzgerald var movies = db.Movies.AsQueriable();
  • @B.Fitzgerald 你不需要做任何事情。访问db.Movies 在您枚举之前不会加载任何内容。

标签: c# asp.net asp.net-mvc visual-studio razor


【解决方案1】:

为了实现您的最终目标,即通过模型列表,据我所知,viewmodel 将是最佳解决方案。

视图模型上方的一些关键说明:

ViewModel 类,它是视图和模型之间的桥梁。每个 View 类都有一个对应的 ViewModel 类。 ViewModel 从 Model 中检索数据并将其处理为 View 所需的格式。如果模型中的底层数据发生更改,它会通知视图,并更新模型中的数据以响应来自视图的 UI 事件

ViewModel 类确定用户操作是否需要修改模型中的数据,并在需要时对模型进行操作。例如,如果用户按下按钮来更新零件的库存数量,View 会简单地通知 ViewModel 该事件发生。 ViewModel 从 View 中检索新的库存量并更新 Model。这将 View 与 Model 解耦,并将业务逻辑整合到 ViewModel 和可以测试的 Model 中。

官方定义/来源:https://msdn.microsoft.com/en-us/library/ff798384.aspx

Ex: 的其他信息:

http://www.dotnettricks.com/learn/mvc/understanding-viewmodel-in-aspnet-mvc

请让我知道您的想法或反馈

谢谢

卡提克

【讨论】:

    【解决方案2】:

    Model 是一个术语,它真正描述了要绑定到视图的数据,以及当您向视图/从视图发出请求时模型绑定器将处理哪些数据。因为我不完全确定您是如何使用 Index 和 Clear,所以我将一般将它们排除在外。如果我错过了您的问题的重点,请告诉我:

    如果您在将List&lt;Movies&gt; movieModelList&lt;SelectListItem&gt; selectedStates(或任何其他值)传递到视图时遇到问题,这里有两种常见的方法。

    1. ViewModel 方法——创建一个模型类,其中包含您的“主”模型以及您在视图中需要的任何其他属性、列表等。 例如:

      public Class MyViewModelClass
      {
         List<Movie> MoviesList {get;set;}
         List<SelectListItem> StatesList {get;set;}
         //some other properties/methods can go here as well ...
      }
      
      //In Controller
      {
          MyViewModelClass model = new MyViewModelClass();
          model.StatesList = <build your select list>;
          model.MovieList = <build your movie list>;
      
          return View(model);
      }
      

    然后,您将在控制器中创建MyViewModelClass model 的新实例(显然不同的名称),并填充您的电影列表、状态列表和任何其他属性,将它们分配给模型属性,并将整个内容传递为你的return View(model);

    这很好,因为传递给视图的所有数据都可以放在一个地方。

    1. ViewBag 方法 -- 坚持使用单个模型或列表,并在 ViewData 或 ViewBag 中传递与视图相关的数据(例如下拉列表或状态布尔值)。 例如。

      //From Controller
      public ActionResult SomeMethod()
      {
         var states = GetAllStates();
         var model = <enter movies query here>;
         ViewBag.StatesList = GetSelectListItems(states);
         //This will be accessible in the view now
      
         return View(model);
      }
      
      //In View:
      @{
          List<SelectListItem> StatesList =  (List<SelectListItem>)ViewBag.StatesList; // Can now use this variable to bind to DropDownList, etc.
       }
      

    在大多数情况下,我更喜欢使用 ViewModel 来添加我需要的一切。一方面,ViewBag/ViewData 需要一些转换,并且它依赖于“魔术字符串”,因此您没有 Visual Studio 让您知道您是否使用智能感知输入了错误。也就是说,两者都是可行的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-20
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 2022-10-30
      • 1970-01-01
      • 2011-09-10
      相关资源
      最近更新 更多