【问题标题】:Can I add a view based on a ViewModel and without a controller for the newly added view?我可以添加一个基于 ViewModel 的视图,而无需为新添加的视图添加控制器吗?
【发布时间】:2012-08-08 15:18:56
【问题描述】:

我是 MVC3 的新手,我想知道这是否可能和好的做法?

我有一个工作正常的模型 + 视图 + 控制器。此视图显示人员列表 - 我希望能够单击一个人的姓名并被重定向到一个新视图,该视图将显示该人员的详细信息。这个新视图只有一个 ViewModel,没有控制器,因为我打算在 action 中传入对象。

Person 对象包含我的视图需要显示的所有属性: @Html.ActionLink(item.Person.FirstName, "PersonDetails", item.Person)

这是可能的/好的做法吗??

【问题讨论】:

  • 当您单击该人员详细信息链接时,您必须了解这将创建对 Web 服务的 GET 请求。该 Web 服务将评估您请求的路由并将其与 Area?、Controller 和 Action 匹配,并绑定请求参数(GET 或 POST)。最后,您真正要求的是来自控制器的答案,而不是视图。 CONTROLLER 将请求一个视图,以便他可以渲染一个可爱的页面发送给您,但它仍然是发送它的 CONTROLLER。

标签: asp.net-mvc-3


【解决方案1】:

我相信您对 MVC 的工作方式存在误解。您的 ActionLink 将始终重定向到控制器的相应 ActionMethod。您要做的是在您的控制器中创建一个操作方法,该方法接受必要的参数,然后返回到您的 ViewModel 视图。

这是一个非常简单的示例,可以帮助您入门:

public class HomeController : Controller
{
    public ActionResult List()
    {
        return View();
    }

    public ActionResult DetailById(int i)
    {
        // load person from data source by id = i

        // build PersonDetailViewModel from data returned 

        return View("PersonDetails", PersonDetailViewModel);
    }

    public ActionResult DetailByVals(string FirstName, Person person)
    {
        // build PersonDetailViewModel manually from data passed in
        // you may have to work through some binding issues here with Person
        return View("PersonDetails", PersonDetailViewModel);
    }
}

【讨论】:

  • 感谢您的帮助。我最终不得不在我想点击一个人的名字的视图的控制器中创建一个 Action 方法。然后在该方法中,我将带有对象的操作重定向到要显示此人详细信息的视图控制器中的操作方法。它有效,但这是最好的方法吗?
  • 它可能有效,但要了解 Actions、Views、ViewModels。操作只是“我的应用程序执行的操作”。在您的情况下 1)列出 2)详细信息。这两个动作映射到控制器中独特的动作方法,每个都有自己的视图。 1 个视图查看列表,另一个查看详细信息。列表视图显示网格,并且在网格中的某处有一个指向 Action2 的超链接以显示详细信息。我将传递 Person 的 id 并使用该 id 从数据源中提取信息,而不是传递查询字符串中的所有数据。向每个视图传递一个包含视图所需数据的视图模型。
【解决方案2】:

按照您的意愿(在您的原始帖子中)这样做不是一个好方法。视图应始终具有视图模型。视图模型仅代表您希望在视图上拥有的数据,不多也不少。不要将您的 domail 模型传递给视图,而是使用视图模型。此视图模型可能只包含您的域模型的一部分属性。

在您的列表视图中,您可能有一个网格,并且在每一行旁边您可能有一个详细信息链接,或名称上的链接(如您所见)。单击其中任何一个链接时,您将被定向到详细信息视图。此详细信息视图将拥有自己的视图模型,其中仅包含您需要在详细信息视图上显示的属性。

domail 模型可能类似于:

public class Person
{
     public int Id { get; set; }

     public string FirstName { get; set; }

     public string LastName { get; set; }

     public int Age { get; set; }

     public string ExampleProperty1 { get; set; }

     public string ExampleProperty2 { get; set; }

     public string ExampleProperty3 { get; set; }
}

假设您只想显示此人的 id、名字、姓氏和年龄,那么您的视图模型将如下所示:

public class PersonDetailsViewModel
{
     public int Id { get; set; }

     public string FirstName { get; set; }

     public string LastName { get; set; }

     public int Age { get; set; }
}

您不需要 ExampleProperty1、ExampleProperty2 和 ExampleProperty3,因为它们不是必需的。

您的人员控制器可能如下所示:

public class PersonController : Controller
{
     private readonly IPersonRepository personRepository;

     public PersonController(IPersonRepository personRepository)
     {
          // Check that personRepository is not null

          this.personRepository = personRepository;
     }

     public ActionResult Details(int id)
     {
          // Check that id is not 0 or less than 0

          Person person = personRepository.GetById(id);

          // Now that you have your person, do a mapping from domain model to view model
          // I use AutoMapper for all my mappings

          PersonDetailsViewModel viewModel = Mapper.Map<PersonDetailsViewModel>(person);

          return View(viewModel);
     }
}

我希望这能让事情变得更清楚。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多