3

I want to use 2 models. The first is on Index.cshtml page, and the second is on _Layout.cshtml page

In the controller which contains the action public ActionResult Index(){...}, I declare some values and return it to View(). Like this:

public ActionResult Index()
{
   HomePageViewModel model = new HomePageViewModel();
   // do something...
   return View(model);
}

And in MyProjectName.Models, I write some classes to check login account and put it on the page _Layout.cshtml. Like this:

On page _Layout.cshtml:

@using MyProjectName.Models
@model MyProjectName.Models.LoginModel

@if (Model.LoginAccount != null)
{
   foreach(Account acc in Model.LoginAccount)
   {
      @Html.ActionLink(@acc.Email, "SomeAction", "SomeController", null, new { id = "loginEmail" })
      @Html.ActionLink("Logout", "SomeAction", "SomeController", null, new { id = "logout" })
   }
}

The code on page _Layout.cshtml doesn't work. It said that: I have returned a model (HomePageViewModel model), but some values which I want to render is referenced from MyProjectName.Models.LoginModel

Main requirement is: the first model is used to display the content on page Index.cshtml, and the second model is used to check user login (on page _Layout.cshtml).

Can you tell me how to do that? Thank you!

  • For you particular case `Action(controller:login, action:ChildActionShowLinks ...)` would probably encapsulate view better... See http://stackoverflow.com/questions/4154407/asp-net-mvc-razor-pass-model-to-layout for more suggestions / discussion. – Alexei Levenkov Jun 10 '15 at 16:08
  • Create a joined view model that contains both models, and then pass that to your controller? – Bob G Jun 10 '15 at 16:10
  • @DarkBobG I don't think it can fix my problem. Because if you create a `parent model` which contains 2 `child models`, it should work. But what happens if I reference `_Layout.cshtml` from another action? –  Jun 10 '15 at 16:20
  • Like: `public ActionResult AnotherAction() { OtherModel model = new OtherModel(); return View(model); }` –  Jun 10 '15 at 16:22

2 Answers2

0

A better approach would be to use partial views and the ViewBag.

in your controller you would do something similar to this:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Accounts = new AccountsViewModel();
        ViewBag.HomePage = new HomePageViewModel();

        return View();
    }
}

From here you'd pass your model from the ViewBag to a partial view

@{
    AccountViewModel Accounts = (AccountViewModel)ViewBag.Accounts;
}

@Html.Partial("_accountPartial", Accounts)
Marqueone
  • 1,165
  • 2
  • 14
  • 33
  • You mean that: Using ViewBag for login? If you make a new redirect, ViewBag data will be lost. But I will think back for `ViewBag.HomePage`. Thanks. –  Jun 10 '15 at 18:23
  • You shouldn't be putting models in your _Layout.cshtml. You should be putting them into your views or partial views instead as _Layout.cshtml is used by all of your pages. – Marqueone Jun 10 '15 at 18:32
0

In your layout use Html.Action() or Html.RenderAction() to call a ChildActionOnly method that returns a partial view for LoginModel

[ChildActionOnly]
public ActionResult Login()
{
  LoginModel model = // initialize the model you want to display in the Layout
  return PartialView(model);
}

and create a partial view that displays the links, then in the Layout

@ { Html.RenderAction("Login", "yourControllerName") }