3

I am trying to reuse some code and a partial view seems to be the best way to do this when using MVC.

I have created a partial view (see below) which inherits from IEnumerable.

@model IEnumerable<Models.facility>

<div class="display-field">
    @foreach (var facility in Model)
    {
        <li>
            @facility.name
        </li>
    }
</div>

The view that embeds this view does it like so:

<div class="display-field">
    <div> @{Html.RenderPartial("FacilityPartial");} </div>
</div>

So now the problem.

I am getting a null reference error and I can see that the Model variable is null.

Error:

Object reference not set to an instance of an object.

Can somebody advise me whether I am doing the correct thing and where I am going wrong other than the fact it is null?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Yos
  • 383
  • 1
  • 6
  • 24
  • 2
    Have you instantiated an instance of the model in the parent view? – Simon Feb 01 '13 at 08:39
  • No. How can I do that and where? If I add more than one @model to the top of the view I get a run time error: Only one 'model' statement is allowed in a file. – Yos Feb 01 '13 at 09:02
  • @Joe have a base model that encapsulates all of your model objects and then use that – DGibbs Feb 01 '13 at 09:05

3 Answers3

3

Use Html.Partial. Consider this example.

Index View (Home)

 @{
        ViewBag.Title = "Home Page";
        //Test model to be passed to the partial view
        var products = new List<Product> { new Product{ProductName="Test product 1", ProductId=1234}};
    }
@Html.Partial("_TestPV", products)

_TestPV (Partial View)

@model IEnumerable<Product>
<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            ProductName
        </th>
    </tr>
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.ProductName)
        </td>
    </tr>
}
</table>

Output:

enter image description here

Jobert Enamno
  • 4,403
  • 8
  • 41
  • 63
  • This now runs without error, however I want the model that I'm passing through to simply be a model containing all of the records in the database table for that view, i.e. my partial view is modelled on the facility model which is modelled on the facility table. How would I pass through something that I can use containing all of the records in the facility table? Then I can simply loop through all of the db records for that table and display this in my view. Thanks! – Yos Feb 01 '13 at 09:17
  • from your controller call the db to get the list of facilities then store them in ViewBag.Facilities then pass that as @Html.Partial("FacilityPartial", ViewBag.Facilities as List) – Jobert Enamno Feb 01 '13 at 09:22
2

You forgot to pass a parameter to your partial view, thus the null reference. Should be:

@{Html.RenderPartial("FacilityPartial", someIEnumerableVariableHere);} 
Artless
  • 4,522
  • 1
  • 25
  • 40
  • You are wrong. You will get compiler error if you use Html.RenderPartial and pass model parameter since this is a void type. – Jobert Enamno Feb 01 '13 at 09:11
0

When you're invoking @{Html.RenderPartial("FacilityPartial");} you provided the name of the partial view but you forgot to include the model as a parameter. This is why you're getting the null reference error because when the view is being rendered it is trying to access the model which you have declared in the view as:

@model IEnumerable<Models.facility>

If you change the invoking line to @{Html.RenderPartial("FacilityPartial", model);} it should work. The view can now act on the model which is being passed into it.


As a side note, the accepted answer by @Jobbert Enamno, uses @Html.Partial as opposed to @Html.RenderPartial which you have used in your question. the difference between these may be confusing you or anyone else viewing this question:

@Html.Partial returns the rendered view as a MvcHtmlString, so you could store this in a variable if you wanted.

@Html.RenderPartial does not return anything i.e. void, and thus outputs straight to the Response stream.

Performance-wise it is generally better to use the latter. See this question for more detailed answers.

Community
  • 1
  • 1
Force444
  • 3,321
  • 9
  • 39
  • 77