Reputation: 36753
I'm trying to make a partial view that acts as the following:
When user is not logged on, show a registration form.
When user is logged on, show me that users information.
I have a partial view that acts as both as registration form, and a user information card; depending on whether or not the user is logged in.
Since this partial view has to be visible from anywhere in the website, I wrote it in the _layout area of the MVC3 application:
<body>
<div id="wrapper">
<div id="top">
<p id="onlinecount">7890 Personas Jugando</p>
<p id="logoncontrol">ENTRAR | REGISTRARSE</p>
</div>
<div id="headercontainer">
<img src="../../Content/Images/topheadertemp.png" />
</div>
<div id="middle">
<div id="playerinformation">
@Html.Partial("_RegisterPartial") <!-- HERE! -->
</div>
<div id="centerad">
<img src="../../Content/Images/premio.png" />
</div>
<div id="rightad">
<img src="../../Content/Images/ganadores.png" />
</div>
<div class="clear"></div>
</div>
<div id="bottom">@RenderBody()
</div>
</div>
</body>
Basically, I need to show a form in that partial if the user is not logged on. However if he IS logged on (via cookie or whatever), I should load a model of his information in order to display the data for his account.
Here's where I'm stuck. I don't know how to load the model for this usage. Since this is in the _layout, no controller acts on it if I'm correct, no?
Any suggestions?
Upvotes: 3
Views: 9158
Reputation: 28701
You should look at this previous question, which is similar to yours.
You should have registration and user information in a single model for your page. (So the answer to your question is that your page only has one model. But your model can be made up of other objects -- one for each partial view.)
So as you see in the link, the user had partial views only use those objects in the page model that pertained to it.
I think this should help you out. Hope this helps! Good luck.
UPDATE: Sorry for the delay, but here's an example (lots of code) that may help:
Model: I create an abstract view model that always has reg and user data in it. Every page's model could inherit from this abstract.
public class Registration
{
public string UserName { get; set; }
public string Password { get; set; }
}
public class UserData
{
public string DisplayName { get; set; }
public int Age { get; set; }
}
public abstract class RegModelViewModelBase
{
public string Title { get; set; }
public Registration RegInfo { get; set; }
public UserData UserInfo { get; set; }
}
public class MainPageViewModel : RegModelViewModelBase
{
}
Controller: Here, I just instantiate the concrete view model for this page/view (MainPageViewModel). I set properties (which could come from the database, etc.). I pass the view model to the view.
public class HomeController : Controller
{
public ActionResult Index()
{
MainPageViewModel hpvm = new MainPageViewModel();
hpvm.Title = "Some Cool Page";
hpvm.RegInfo = new Registration() { Password = "blah", UserName = "dhoerster" };
hpvm.UserInfo = new UserData() { DisplayName = "David Hoerster", Age = 125 };
return View(hpvm);
}
}
View -- _Layout.cshtml: Notice that the first line in my model sets the model object for my _layout template. I'm getting this view model from the controller, and I can reference it in _layout (or other template). I don't do much here, except get a partial view (_RegStuff) and pass to it my RegInfo from my model (which was set in the controller):
@model MvcApplication1.Models.RegModelViewModelBase
<!DOCTYPE html>
<html>
<head>
<title>@Model.Title</title>
</head>
<body>
@Html.Partial("_RegStuff", Model.RegInfo)
@RenderBody()
</body>
</html>
View -- _RegInfo.cshtml: Dirt simple, but again I set my model type that this partial view expects to be passed in.
@model MvcApplication1.Models.Registration
<div>User Name = @Model.UserName</div>
View -- Index.cshtml: Again, set the model and use it in my index view.
@model MvcApplication1.Models.MainPageViewModel
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>@Model.Title</h2>
<h3>Display Name = @Model.UserInfo.DisplayName</h3>
So throughout, I can reference the model set in my controller.
I hope this explains what I was trying to get at. If not, I can update this accordingly.
Thanks!
Upvotes: 14
Reputation: 747
I'm going to go against the grain here, and recommend that you don't make this decision in the view. Have two separate views, with their own models, and let the controller determine which view is called, based on whether the user is logged in (authenticated) or not.
It's not that the approach that you're looking at can't be done... you can easily do this by making a ViewModel that is composed of each of the view models that you need. I'd still advise against it though.
Upvotes: 0
Reputation: 69022
You can create a new class "ViewModel" hold both the models,
Or you can put both or one of the Models in the ViewBag
Upvotes: 0
Reputation: 1893
One way you could do this is design a ViewModel like this:
public class ViewModel
{
public PlayerCard playerCard { get; set; }
public RegisterModel registerModel { get; set; }
}
To include both models.
Upvotes: 0