MikeB55
MikeB55

Reputation: 289

MVC Partial Views in Site.Master

I am trying to render a partial view in my Site.Master file but I keep on getting an error (Object reference not set to an instance of an object). If I access the view directly, I get the info that I need, but if I access the Index View from the HomeController, I get an error. The partial view will display the logged in user, department, and role. This is my code.

Controllers Folder -HomeController.cs -UsersController.cs

Models
-Repository Folder
  - UersRepository.cs
-Repository Interface Folder
  - IUsers.cs
-Service Folder
  - UsersService.cs
  - IUserService.cs
-Validation Folder
  - IValidationDictionary
  - ModelStateWrapper

The view that I'm trying to partially render is called LoginInfo.ascx and it's located in the Shared Folder.

LoginInfo.cs Code:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Users>>" %>

<%@ Import Namespace="TimeAttendanceMVC.Models"%>




<table>
    <tr>
        <th>
            UserName
        </th>
        <th>
            Department
        </th>
        <th>
            UserType
        </th>

    </tr>

<% foreach (var item in Model) { %>
    <tr>
        <td>
            <%: Html.DisplayFor(modelItem => item.UserName) %>
        </td>
        <td>
            <%: Html.DisplayFor(modelItem => item.Department) %>
        </td>
        <td>
            <%: Html.DisplayFor(modelItem => item.UserType) %>
        </td>

    </tr>
<% } %>

</table>

Site.Master Code:

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

UserController.cs

 public class UsersController : Controller
    {
        //
        private IUsersService _service;

        //==============================================================================
        //==============================================================================
        public UsersController()
        {
          _service = new UsersService(new ModelStateWrapper(this.ModelState));
         }

        public UsersController(IUsersService service)
        {
            _service = service; 
        }

        //==============================================================================
        //==============================================================================
        // GET: /Employee/
        //==============================================================================
        //==============================================================================
        // GET: /Employee/
        public ActionResult Index()
        {

            var model = _service.Return_UserName_Dept();
            return View("LoginInfo", model);
        }

    }

HomeController.cs

 public ActionResult Index()
        {
            //var model = _service.Return_UserName_Dept();
            //return View(model);
            return View();

        }

With the code above, I get an error. If I un-comment the 2 lines in my HomeController and I pass the model to the View, then it works fine. But my HomeController will need a different model, so how will I pass 2 models to the View?

Any ideas what I'm doing wrong? I'm still learning MVC right now so I'm not that good at this. Any help would be appreciated. Thanks.

Upvotes: 1

Views: 1358

Answers (2)

Phil Klein
Phil Klein

Reputation: 7514

Your Controller is able to pass a single Model to the View for rendering. Rather than attempting to have two models, or to call two Action Methods in a request with RenderAction, have you considered creating a parent ViewModel type?

// This model is passed to your view for rendering
public class MyViewModel
{
    public string Title { get; set; }
    public DateTime Date { get; set; }

    // This property is passed as the model to your partial view
    public UserInfo UserInfo { get; set; }
}

public ActionResult Index()
{
    var model = new MyViewModel(); // _service.GetIndexViewModel();
    model.UserInfo = _service.Return_UserName_Dept();;
    return View(model);
}

Then in your View, you would do something like:

<% Html.RenderPartial("LoginInfo", Model.UserInfo); %>

Upvotes: 0

SLaks
SLaks

Reputation: 887433

Calling RenderPartial renders the view directly, inheriting the parent's model.

You should call RenderAction instead to render a child action so that the action can pass the correct model to the partial view.

Upvotes: 2

Related Questions