Mihai Tibrea
Mihai Tibrea

Reputation: 641

Render a partial view with an IEnumerable as a model

I want to render a partial view with a list of news received from a rss feed. I have the following controller :

RssFeedPartial

public ActionResult HealthCareNews()
{
// get the news add them to a list.
return PartialView("_HealthCareNews",rssList);
}

i want to render this partial view in the About, News, etc pages.

Home Controller

public ActionResult About()
{
    return View();
}

About page

<div id="rightColumn">
@Html.Partial("_HealthCareNews")
 </div>

_HealthCareNews page

@model IEnumerable<MDISS.ViewModel.RSS>
@foreach(var item in Model)
{
//display list
}

When i try to open the About Page, I get the following error :

Object reference not set to an instance of an object.

Upvotes: 1

Views: 2905

Answers (2)

Wouter de Kort
Wouter de Kort

Reputation: 39898

@Html.Partial("_HealthCareNews") directly renders your partial view. Since you are not passing it any data, the Model property will be null. This gives the Object reference not set to an instance of an object error.

Instead you want to call the HealthCareNews action on your controller. You can do this by using Html.Action like this:

@Html.Action("HealthCareNews") 

Directly rendering a partial view (with Html.Partial) can be used when you pass the data directly from your view or when the partial view only contains static data.

When your partial view depends on data that's not part of the model of the view your rendering it from, you can use Html.Action. That way, you execute the action method on your controller. The action method can build the model that's required for your partial view.

Update

An action method in MVC returns an ActionResult. ActionResult is an abstract base class for all the different types of ActionResults that exist in MVC like ViewResult, JsonResult and PartialViewResult. Some developers prefer to have ActionResult as the return type for all their methods. Others try to declare the most specific return type. I prefer to use the latter. Especially when unit testing this makes the code easier to use because you can work with the result directly.

The difference between ViewResult and PartialViewResult has to do with using a Layout page. Since a PartialView is used for returning a single piece of HTML that can be embedded in another page, you don't want to use a layout page. A ViewResult returns a complete view with options to use a layout page.

Upvotes: 3

Oliver
Oliver

Reputation: 9002

You're seeing the error because you are not passing the expected IEnumerable<MDISS.ViewModel.RSS> model to the "_HealthCareNews" partial view:

<div id="rightColumn">
    @Html.Partial("_HealthCareNews" /*Model required here*/)
</div>

You could use one of the following:

@Html.RenderAction("HealthCareNews")

@Html.Action("HealthCareNews")

These methods will call the HealthCareNews controller action that you have created, which correctly loads the "_HealthCareNews" partial view with the appropriate rssList model.

However

I personally prefer calling partials from within my razor view, passing in any required model from my view model. Using your example this might look like:

ViewModel

public class AboutPageViewModel
{
    public IEnumerable<MDISS.ViewModel.RSS> RssList { get; set; }
}

Controller

public ActionResult About()
{ 
    return View(new AboutPageViewModel { RssList = rssList });
}

Razor View

@model AboutPageViewModel

<div id="rightColumn">
    @Html.Partial("_HealthCareNews", Model.RssList)
</div>

Upvotes: 3

Related Questions