10

In ASP.Net MVC I would like to render a different partial view depending on the renderview query string parameter.

Therefore providing the facility for the user to choose to view products by thumbnail or by details.

I have access to the chosen parameter in the controller but I do not know how to or, if I should be passing this to the view along with the products list so the view can implement the logic for deciding which partial view to display?

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 Answers 3

6

Your View Should be something like:

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

Then in MyModel

Expose Property:

public bool RenderDetailView {get;set;}

In your controller action:

public ActionResult Products(string id, int? renderview)
{
    var products = productRepository.GetProducts(id).ToList();
    return View("Products", new MyModel {RenderDetailView = renderview.HasValue});
}

Then in your view, make check like:

<% if (Model.RenderDetailView)

Ideally, all the properties or parameters or data which a View needs in order to present itself should be part of Model.

I hope it helps.

Sign up to request clarification or add additional context in comments.

6 Comments

ALso ProductList will also be the part of MyModel.
Hi Nitin, I started to follow your answer and I have created the ViewModel utalising the method public ProductsViewModel(bool renderDetailView, List<Product> productsList){this.RenderDetailView = renderDetailView;this.ProductsList = productsList;} and pass it to the Products page with return View("Products", new ProductsViewModel(true, products)); but for some reason the if Model.RenderDetailView line is never hit - all the rest of the page is rendered but any code within <% %> are not being hit. Aso I can step through and see the ProductsViewModel being populated. Any suggestions?
Thanks for your response! Meantime I deleted and recreated the view and also changed the view model code to be a nullable type to public bool? RenderDetailView { get; private set; } and now it works a treat! I like Paul's way as well but I think your way makes the most sense in this scenerio. What do you think?
Well Ideally Your code should be like: You have a Page let us say product page. In that you have two partial views in the form of controls, driven by same Model and Controller. Then on Action use Partial Rendering of Either of the Control. By using Paul way you have to rewrite the functionality which is common to both the views, which i personally don't prefer.
Yes, I suppose it depends on your interpretation of what a partial view is for. Anyhow, I prefer your way.
|
3

An alternative approach would be to use Restful Urls to invoke the appropriate controller action and view.

This makes the urls reflect what you are seeing on the screen and makes the design more extensible; should you need to add other views of the data in the future (summary, latest, etc) you add the new view, no need for partials unless the main body of the view gets more complicated and has to be factored out to a partial view.

The URLs would look like:

~/product/1/detail

~/product/1/thumbnail

And correspond to ProductController methods:

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);
}

You enable the routing with a route like:

{controller}/{id}/{action}

Comments

0

Paul's method is good, but if you decide you want to pass the int, you need to create a view model.

In your controller add this

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;
        }
    }

Then pass this into the view

return View(new ProductsFormViewModel(products, renderview);

And then in the view

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.