Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you pass an arbitrary bit of data to a user control in ASP.NET MVC using Html.RenderPartial()?

I have a strongly typed user control ("partial") and I'd like to be able to pass it some additional information from its containing view. For example, I have view that's bound to a product class and i have a partial that also is strongly typed to that same model, but I also need to pass an additional parameter for imageSize to my partial. I'd like to be able to do something like this:

<% Html.RenderPartial("_ProductImage", ViewData.Model, new { imageSize = 100 }); %>

As far as I know there is no way to do this, but I'm hoping that someone smarter than me may have a solution ;)

like image 304
JC Grubbs Avatar asked Dec 15 '08 20:12

JC Grubbs


People also ask

Which is the way to render partial view using ASP NET MVC Razor engine?

RenderPartial function to render Partial View in ASP.Net MVC Razor. The data will be fetched from database using Entity Framework and then the Partial View will be rendered using the @Html. RenderPartial function in ASP.Net MVC Razor.

What is partial view in MVC with example?

A partial view is a Razor markup file ( . cshtml ) without an @page directive that renders HTML output within another markup file's rendered output. The term partial view is used when developing either an MVC app, where markup files are called views, or a Razor Pages app, where markup files are called pages.

What is HTML partial?

Html. Partial. Renders the partial view as an HTML-encoded string. This method result can be stored in a variable, since it returns string type value. Simple to use and no need to create any action.

How do you call a partial view in another view in MVC?

To create a partial view, right-click on view -> shared folder and select Add -> View option. In this way we can add a partial view. It is not mandatory to create a partial view in a shared folder but a partial view is mostly used as a reusable component, it is a good practice to put it in the "shared" folder.


3 Answers

Change the type of the partial model:

class PartialModel 
{
    public int ImageSize { get; set; }
    public ParentModelType ParentModel { get; set; }
}

Now pass it:

<% Html.RenderPartial("_ProductImage", 
    new PartialModel() { ImageSize = 100, ParentModel = ViewData.Model }); %>
like image 121
Craig Stuntz Avatar answered Oct 20 '22 12:10

Craig Stuntz


Not the most beautiful solution

<% ViewData["imageSize"] = 100; %>

<% Html.RenderPartial("_ProductImage"); %>

the ViewData is passed by default

like image 36
Todd Smith Avatar answered Oct 20 '22 14:10

Todd Smith


I use a generic class model - which is similar in concept to the approach suggested by Craig.

I kind of wish MS would create an overload to RenderPartial to give us the same functionality. Just an additional object data parameter would be fine.

Anyway, my approach is to create a PartialModel which uses generics so it can be used for all .ascx controls.

 public class PartialControlModel<T> : ModelBase 
    {
        public T ParentModel { get; set; }
        public object Data { get; set; }

        public PartialControlModel(T parentModel, object data) : base()
        {
            ParentModel = parentModel;
            Data = data;
        }
    }

The .ascx control should inherit from the correct PartialControlModel if you want the view to be strongly typed, which most likely you do if you've got this far.

public partial class ThumbnailPanel : 
                     ViewUserControl<PartialControlModel<GalleryModel>>

Then you render it like this :

<% Html.RenderPartial("ThumbnailPanel", 
new PartialControlModel<GalleryModel>(ViewData.Model, tag)); %>

Of course when you refer to any parent model items you must use this syntax :

ViewData.Model.ParentModel.Images

You can get the data and cast it to the correct type with :

ViewData.Model.Data

If anyone has a suggestion on how to improve the generics I'm using please let me know.

like image 24
Simon_Weaver Avatar answered Oct 20 '22 12:10

Simon_Weaver