Pass Additional ViewData to a Strongly-Typed Partial View
Asked Answered
W

9

189

I have a strongly-typed Partial View that takes a ProductImage and when it is rendered I would also like to provide it with some additional ViewData which I create dynamically in the containing page. How can I pass both my strongly typed object and my custom ViewData to the partial view with the RenderPartial call?

var index = 0;
foreach (var image in Model.Images.OrderBy(p => p.Order))
{
  Html.RenderPartial("ProductImageForm", image); // < Pass 'index' to partial
  index++;
}
Wismar answered 23/7, 2009 at 1:47 Comment(0)
G
267

RenderPartial takes another parameter that is simply a ViewDataDictionary. You're almost there, just call it like this:

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       new ViewDataDictionary { { "index", index } }
); 

Note that this will override the default ViewData that all your other Views have by default. If you are adding anything to ViewData, it will not be in this new dictionary that you're passing to your partial view.

Goodwin answered 23/7, 2009 at 2:22 Comment(3)
I'm trying to do this and it is returning "cannot convert void to object".Tamera
@Tamera Try removing the @ from @Html.RenderPartial(), this fixed that issue for me, but I was calling RenderPartial() on a line within a @ { } code block.Suazo
I recommend checking out ctorx's answer below. He adds additional data to the existing ViewData.Taynatayra
B
182

To extend on what womp posted, you can pass new View Data while retaining the existing View Data if you use the constructor overload of the ViewDataDictionary like so:

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       new ViewDataDictionary(this.ViewData) { { "index", index } }
); 
Baal answered 11/5, 2012 at 22:0 Comment(3)
this can be very useful if you need to retain TemplateInfo.HtmlFieldPrefix in the child control which will be reset otherwiseBorders
This is definitely the better solution. Losing the ViewData means that you lose the ModelState and all validations. +1Inhabitancy
This seems to work only if you do not pass a TemplateInfo.HtmlFieldPrefix in your ViewDataDictionary. I can only pass a variable as ilustrated on the answer, or pass a TemplateInfo.HtmlFieldPrefix but not both.Outcross
A
52
@Html.Partial("_Header", new ViewDataDictionary { { "HeaderName", "User Management" }, { "TitleName", "List Of Users" } })
or
@{Html.RenderPartial("_Header", new ViewDataDictionary { { "HeaderName", "User Management" }, { "TitleName", "List Of Users" } });}

Partial Page(_Header):

<div class="row titleBlock">
    <h1>@ViewData["HeaderName"].ToString()</h1>
    <h5>@ViewData["TitleName"].ToString()</h5>
</div>
Apollinaire answered 12/8, 2014 at 8:27 Comment(1)
This seems like the most complete answer (though the .ToString() is unnecessary).Outride
L
11

I think this should work no?

ViewData["currentIndex"] = index;
Lucylud answered 23/7, 2009 at 1:56 Comment(1)
While this is not a very strong way of doing it, it did help me figure out how to retrieve a view data value from Womp's answer.Deferent
H
7

I know this is an old post but I came across it when faced with a similar issue using core 3.0, hope it helps someone.

@{
Layout = null;
ViewData["SampleString"] = "some string need in the partial";
}

<partial name="_Partial" for="PartialViewModel" view-data="ViewData" />
Hannover answered 18/12, 2019 at 21:8 Comment(0)
A
6

Create another class which contains your strongly typed class.

Add your new stuff to the class and return it in the view.

Then in the view, ensure you inherit your new class and change the bits of code that will now be in error. namely the references to your fields.

Hope this helps. If not then let me know and I'll post specific code.

Aerialist answered 23/7, 2009 at 1:57 Comment(0)
P
4

The easiest way to pass additional data is to add the data to the existing ViewData for the view as @Joel Martinez notes. However, if you don't want to pollute your ViewData, RenderPartial has a method that takes three arguments as well as the two-argument version you show. The third argument is a ViewDataDictionary. You can construct a separate ViewDataDictionary just for your partial containing just the extra data that you want to pass in.

Plus answered 23/7, 2009 at 2:21 Comment(0)
R
3

This should also work.

this.ViewData.Add("index", index);

Html.RenderPartial(
      "ProductImageForm", 
       image, 
       this.ViewData
); 
Resection answered 10/11, 2018 at 7:59 Comment(1)
Thanks! This is really useful when you're extending the ViewData dictionary for child partials etcSobriquet
A
-1

You can use the dynamic variable ViewBag

ViewBag.AnotherValue = valueToView;
Ambuscade answered 2/12, 2015 at 16:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.