ASP.Net MVC传递多个参数到视图

10
在ASP.Net MVC中,我想根据renderview查询字符串参数呈现不同的局部视图。因此,可以为用户提供选择缩略图或详细信息查看产品的功能。虽然我在控制器中可以访问所选参数,但我不知道是否应该将其与产品列表一起传递到视图中,以便视图可以实现决定显示哪个局部视图的逻辑?
public ActionResult Products(string id, int? renderview)
{
    var products = productRepository.GetProducts(id).ToList();
    return View("Products", products);
}



<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<MLBWebRole.Models.Product>>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Products
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Products</h2>

<p>This is the Products page</p>

<p><a href="?renderview=0">thumbnails</a>&nbsp;<a href="?renderview=1">details</a></p>


 <% if (renderview == 1)
     {%>
    <% Html.RenderPartial("ProductsDetailList"); %>
<% }
else
 { %>
<% Html.RenderPartial("ProductsThumbnailList"); %> 
  <% } %>

</asp:Content>
3个回答

6
您的视图应该类似于以下内容:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Models.MyModel>" %>

接下来,在MyModel中:

暴露属性:

public bool RenderDetailView {get;set;}

在您的控制器操作中:
public ActionResult Products(string id, int? renderview)
{
    var products = productRepository.GetProducts(id).ToList();
    return View("Products", new MyModel {RenderDetailView = renderview.HasValue});
}

然后在您的视图中,进行如下检查:

<% if (Model.RenderDetailView)

理想情况下,一个视图需要呈现自身的所有属性、参数或数据都应该是模型的一部分。
希望这有所帮助。

同时,ProductList也将成为MyModel的一部分。 - Nitin Midha
嗨,Nitin,我开始按照你的回答操作,并创建了ViewModel,使用方法public ProductsViewModel(bool renderDetailView, List<Product> productsList){this.RenderDetailView = renderDetailView;this.ProductsList = productsList;},并通过return View("Products", new ProductsViewModel(true, products));将其传递到Products页面,但是由于某种原因,if Model.RenderDetailView行从未被触发-所有页面的其余部分都被呈现,但<% %>中的任何代码都没有被触发。同时我可以逐步查看填充的ProductsViewModel。有什么建议吗? - Nicholas Murray
感谢您的回复!同时,我删除并重新创建了视图,并将视图模型代码更改为可为空类型 public bool? RenderDetailView { get; private set; },现在它运行得很好!我也喜欢Paul的方法,但我认为您的方法在这种情况下最有意义。您觉得呢? - Nicholas Murray
理想情况下,您的代码应该像这样:您有一个页面,比如产品页面。在其中,您有两个以控件形式呈现的部分视图,由同一模型和控制器驱动。然后,在操作中使用任一控件的部分渲染。通过使用Paul的方法,您必须重写两个视图共同具有的功能,我个人不喜欢这种方式。 - Nitin Midha
是的,我想这取决于你对部分视图的理解。不管怎样,我更喜欢你的方式。 - Nicholas Murray
我的方法将问题颠倒过来,您有一个视图和两个部分视图。我会使用2个视图和一个部分视图(用于共同部分)。我不需要renderview参数,我的视图模型是原子化的,我的视图具有单一目的。这是设计问题,并不是说您错了。 - Paul

3

另一种方法是使用Restful Urls来调用适当的控制器操作和视图。

这使得URL反映了您在屏幕上看到的内容,并且使设计更具可扩展性; 如果将来需要添加数据的其他视图(摘要,最新等),则只需添加新视图,无需部分视图,除非视图的主体变得更加复杂并必须拆分为部分视图。

URL将如下所示:

~/product/1/detail

~/product/1/thumbnail

并对应ProductController中的方法:

public ActionResult Detail(String id)
{
    var products = productRepository.GetProducts(id).ToList();
    return View("Detail", products);
}

public ActionResult Thumbnail(string id)
{
    var products = productRepository.GetProducts(id).ToList();
    return View("Thumbnail", products);
}

您可以通过以下路由启用路由功能:

{controller}/{id}/{action}

0

Paul的方法很好,但如果你决定要传递int,你需要创建一个视图模型。

在你的控制器中添加以下内容

public class ProductsFormViewModel
    {
        // Properties
        public Products Products { get; private set; }
        public int? Renderview { get; private set; }

        // Constructor
        public ProductsFormViewModel(Products p_products, int? p_renderView)
        {
            Products = p_products;
            Renderview = renderView;
        }
    }

然后将其传递到视图中

return View(new ProductsFormViewModel(products, renderview);

然后在视图中

Inherits="System.Web.Mvc.ViewPage<YourNamespace.Controllers.ProductsFormViewModel>"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接