【问题标题】:Combining two views in one vs returning two views for same controller action将两个视图合二为一与为相同的控制器操作返回两个视图
【发布时间】:2017-11-26 00:03:17
【问题描述】:

在 ASP.NET MVC 中,我有一个 BooksController,它提供了查看书籍的功能。我希望www.mydomain.com/books 返回我所有书籍的列表(它与“所有书籍”html 页面相关联),而 www.domain.com/books/c-sharp-for-dummies 获取“C# for dummies”书籍的所有信息(同样,它是“单本书” html 页面)。

使用bookName 参数创建Index 方法很简单。

public class BooksController
{
     public ActionResult Index(string bookName)
     {
         if (string.IsNullOrEmpty(bookName)
         {
           //return all books here
         }
         else
         {
            //return single book here 
         }
     }
}

Index 关联了Index.cshtml 视图页面,但是我必须在视图中进行 Razor 检查以确定是加载“所有书籍”HTML/CSS 还是“单本书”HTML/ CSS - 就像视图包含两个页面,我觉得这违反直觉。

对于这种情况,什么是好的(甚至是传统的)方法?我是否只创建两个cshtml 文件,一个用于“所有书籍”,一个用于“单本书”,然后根据是否提供bookName 参数返回适当的视图?

public class BooksController
{
     public ActionResult Index(string bookName)
     {
         if (string.IsNullOrEmpty(bookName)
         {
           //return all books viewmodel and related  view             
         }
         else
         {
            //return single book viewmodel and related view 
         }
     }
}

【问题讨论】:

  • Index 方法通常用于显示与控制器关联的项目集合,而单独的Details(string bookName) 方法用于显示单个项目的详细信息
  • 我会默认使用所有书籍数据的视图,并在选择书籍时异步加载部分视图以覆盖该数据
  • 两个视图(以及可选的两个操作)将是比单个视图更常见的方法。
  • @StephenMuecke 谢谢 - 如果我们假设我不希望 /details/ 作为我的 URL 的一部分(假设 /books 用于所有书籍,/books/{bookId}/{bookName} 用于一本书) - 如何你接近那个?我想不出@Shyju 在他的回答中提出的“更好”的解决方案。
  • Shyju 的回答确实显示了如何做到这一点(使用属性路由,尽管您也可以在 RouteConfig 文件中定义路由)。如果您也想在路由中使用 ID,则只需使用 [Route("books/{bookId}/{bookName}")](但这表明您可能需要按照 this answer 进行 slug 路由

标签: c# asp.net-mvc razor


【解决方案1】:

您应该在控制器中创建 2 个单独的操作方法。一个用于返回包含所有书籍的视图,一个用于返回单个书籍的详细信息。

你可以这样定义路由定义,这样来yourSite/books的请求会被index action处理,yourSite/books/somebookname会被Detailsaction方法处理。以下是使用attribute routing 的方法。

public class BooksController : Controller
{
    [Route("books")]
    public ActionResult Index()
    {
        // to do : Get all the books and pass it to the view.
        return View();
    }
    [Route("books/{bookName}")]
    public ActionResult Details(string bookName)
    {
       // to do : Get single book using the bookName parameter
       // and pass that to the view.
       return View();
    }
}

现在在您的index.cshtml 视图中,您可以显示所有书籍,在Details.cshtml 视图中,您可以显示特定书籍的详细信息。

【讨论】:

  • 感谢@Shyju,这是否意味着我必须在每种方法之上定义Route?改用RouteConfig能达到类似的效果吗?
  • 是的。您也可以通过传统路由实现相同的效果(检查相同的链接)。但是恕我直言,属性路由更具可读性
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-16
相关资源
最近更新 更多