17

I'm asking because the partial view I will create is blank, with the purpose of creating a new child entity. I just need a quick, regardless if dirty, way to access the Parent Model from within the partial view. I need the Id of the parent.

Does a partial view automatically have access to the model of the parent?

L_7337
  • 2,650
  • 28
  • 42
AnimaSola
  • 7,146
  • 14
  • 43
  • 62

5 Answers5

18

You cannot access the parent model from a partial view unless you pass some value to this partial as parameters when rendering it. For example in your main view:

@model MyViewModel
...
@Html.Partial("_myPartial", new ViewDataDictionary(new { id = Model.Id }));

and then inside your partial you could access the Id:

<div>@ViewBag.Id</div>

Of course this is a pretty lousy way of passing data to a partial view. The correct way is to use a strongly typed view model.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I wonder if this example is incorrect. I see the main view passing in a ViewDataDictionary, but the partial view retrieving via ViewBag. The ViewBag and ViewData are different, yes? – Michael R Feb 27 '14 at 18:57
  • 4
    No, ViewBag and ViewData are using absolutely the same storage. When you write `ViewBag.FooBar` it's as if you were writing `ViewData["FooBar"]`. And by the way you shouldn't be using any of those. You should be using strongly typed view models instead. – Darin Dimitrov Feb 27 '14 at 21:56
  • Not always. If your main model contains a collection of child models, each one of which is being passed to a partial view, one by one, but you need to reference a property on the parent model back in the main view, this is a way to do it. (simplified... I have a 3 level deep nested model and in a child model passed to a partial view i needed to use a property on the grandparent model) – Mark Worrall Dec 20 '20 at 14:53
3

I know this is an old topic, but I figured I'd just add my solution to the same problem anyway. I think it's a bit cleaner.

Basically add a model to the partial view.

The encapsulating view:

@model whatever
...
@Html.Partial("partialview", anotherwhatever)

The partial view:

@model anotherwhatever
<div>@Model.something</div>
...

In my case I just needed to pass a string into the partial view (just using it to shorten and partition code), so this was much more elegant than the other solution.

I tried the other solution first and actually couldn't get it to work, it just acted as though the value I passed was blank.

Yushatak
  • 741
  • 1
  • 5
  • 15
2

This ended up working for me.

@model MyViewModel
...
@Html.Partial("_myPartial", new ViewDataDictionary { { "id", Model.Id } })

And inside the partial view, used this...

<div>@ViewBag.id</div>
JOpuckman
  • 1,306
  • 9
  • 17
1

You can just pass the model IE:

The encapsulating view:

    @model MyModel
    @Html.Partial("_myPartial", Model)

Partial View:

    @model MyModel
    Id = @Model.Id;
RC Cola
  • 76
  • 5
1

Under normal circumstances you can and should just pass the value down into the partial, but we ran into an edge case where this didn't make sense. If you're absolutely sure that you have to, you can easily access the parent Model or ViewBag as follows:

// Get the parent's model
var model ViewContext.Controller.ViewData.Model as MyType
// Get the parent's ViewBag
var value = ViewContext.Controller.ViewBag.MyVariableName as MyType

The situation we ran into had the following constraints that lead us to making use of this:

  1. Partials are automatically generated, inserted and rendered rather than explicitly called from our Razor Pages (In our case, these are ads inserted into an article at certain word counts by our CMS)
  2. The models we pass into the Partial when they're being automatically rendered are generated based on values saved in a DB, so we only want to have things which definitely won't change in the model (And can't include User-specific information or information which could change without the page being regenerated)
Stephen O
  • 91
  • 8