How to access a property of a model in _layout.cshtml - asp.net-mvc

Well I am generating email templates using cshtml.
And I have one of the template like this.
#model Api.Model.SignUpViewModel
#{
Layout = "layout";
}
And in SignUpViewModel I have got a property isUnsubscribable
So in layout page I have to show a link for Unsubscribe based on this.
And I have few other Email Models which have this property, some others does't have this.
How can I send this data to Layout.cshtml

You want to create a parent ViewModel with your isUnsubscribable property. Then make your SignUpViewModel inherit from that parent.
Then in your layout page, your Model is as follows:
#model Api.Model.ViewModel
//Access your property here
And in your cshtml page, you will have the child viewmodel:
#model Api.Model.SignUpViewModel
This will work because both pages are getting what they need, when you pass the model in from the controller.

There is no need to send data to layout. It is already accessible there using below given syntax
#Model.isUnsubscribable

Related

Can we add Models in Layout.cshtml?

i have layout of 4 pages and at header i need to access name of logged in admin. how to access that database model in admin in starting of layout i have added
#model ProjectName.Models.Admin
and while accessing name from admin i am writing
#Model.Name
it gives error how to do it in proper way to access that attribute in Layout and it cant be partial view it should be layout so kindly help
As #Stephen Muecke stated in his comment on your question, there are more ways how you can do that. I would recommend you to keep your Layout view without model. Otherwise as #Stephen Muecke mentions, you would have to make types of models for each view that uses that layout of either the same or derived type, which would add unnecessary complexity to your code.
So the other way is to call HtmlHelper.Action(...) or HtmlHelper.RenderAction() in your layout view at the place when you'd like to render user's name. Example:
Layout page:
...
<div class="admin-name">
#{ Html.RenderAction("AdminName", "Partial"); }
</div>
...
Add a controller:
public class PartialController : Controller {
[ChildActionOnly] // action cannot be requested directly via URL
public ActionResult AdminName() {
string adminName = ...; // assign value to adminName variable
return Content(adminName);
}
}
You need logged in user details in so many pages in application, so better to store logged in user details in Session and you can retrieve session value in any view/partial view.
Other Solution:
Make your header partial view and call from Layout
Html.RenderAction("actionName", "controllerName")
Create an action method in your controller which returns partial view
Controller Action Method
[HttpGet]
public ActionResult Header()
{
HeaderModel HM = new HeaderModel()
// Your user information in HeaderModel
return PartialView("Header", HM)
}
_layout.cshtml
<body>
<div>
#{Html.RenderAction("Header", "ControllerName");}
</div>
</body>
I hope this will resolve your problem.

How to pass the model from the razor page to its master/layout page?

I have a page with following on top:
#model AppMainModel
#{
ViewData["Title"] = "Home Page";
}
I would like to use AppMainModel and its properties in its master/layout page. Strongly typed if possible (e.g. avoid ViewData and the like).
Is this possible?
The ViewModel data is available to the layout page. You can consider having a page viewmodel class with the common data if you want it to be strongly typed in the layout page. If not, simply pass in the common thing using the dynamic nature of ViewData. You might even apply a global filter to set up the common data if it seems appropriate.
Solution From here
You may also try this solution:
http://forums.asp.net/t/1799746.aspx?How+to+pass+a+value+to+the+LoginDisplay+from+HomeController+that+will+display+on+all+pages
You can set the #model on the layout page as well:
#model AppMainModel
<html>
<head>
<title>#Model.Title</title>
</head>
...
</html>
However, you must make sure everytime you use this layout you pass a model that inherits from AppMainModel.
To avoid being non-strongly typed on the _Layout page, i suggest you to take a look at the following great #jgauffin blog post about Getting information into the Layout without using ViewBag.
Using a LayoutViewModel in summary:
Create a viewmodel with all the types/fields you need on your _Layout page
Wrap handling of this LayoutViewModel into a BaseController class (that your other controllers inherit from) overriding its OnResultExecuting() method
Create a Viewbase layout class that will inherit WebViewPage, and register it in web.config to use your Viewbase layout model as pageBaseType
An example: I use this approach to pass meta field values to my _Layout page.

ASP.Net MVC Partial View Model Binding

I'm very new to MVC and I am looking to put a list of links on the main layout(master page) based on database table. I'm sure I read before that you shouldn't try to load models on the master page but use Partial Views instead (correct me if I'm wrong).
I've looked on Google and on other questions here but they only seem to talk about passing data from a main view to a partial view via ViewBag but I think I just want to add a partial view that I can add to the master page.
Can someone please tell me how to create a partial view I can add to master page so its used on every page and be able to load the list of links required i.e. by binding IEnumerable model to Partial View?
Try using ChildActionExtensions.Action
In your layout:
#Html.Action("MyAction", "MyController")
Controller:
public ActionResult MyAction()
{
var list = // get your list values
return PartialView("MyViewName", list);
}
Then just create your partial view:
#model IEnumerable<WhateverType>
#* View goodness *#
You can use this to bind whatever model you need to your partial view and if you use the Action helper in your Layout.cshtml it'll be rendered on every page.

Do we have user control and hidden field in razor?

In Asp.net , there is user control, which is an ascx page, and we can have hidden fields:
public partial class classA:System.Web.Mvc.ViewUserControl<Models.classB>
{
//hidden field
public string url
{
get{ ...... }
}
}
But now i am using razor in asp.net mvc3 ,which is cshtml file. Do we have anything corresponding to that? How can i use hidden field now?
MVC views do no have fields like a Web Forms user control.
MVC views (partial views, too) get their data by passing an instance of a Viewmodel class to them. You can indicate the type of the viewmodel class with the #model directive (usually the first line in a view):
#model MyViewmodelClass
<span>#Model.MyClassProperty</span>
The viewmodel class itself could contain private fields like any class.
If you need variables to be used within the view itself, you can simply declare them within a razor code block and use them wwithin the view:
#{
var privatevar = "value";
}
<span>#privatevar</span>
However, as a best practice, the view's responsibility in ASP.NET MVC should be limited to the display of the data and therefore not contain code unrelated to that.
While working with razor it is essential to have basic HTML knowledge as you need to write some html and there is no and Drag and Drop to add controls on the page.
MVC have introduced Partial Views which can be said a alternate/replacement to User Control.
You can create a PartialView by selecting Checkbox stating "Create Partial View" in View Creation Dialog. Secondly In MVC it is not difficult to create partial view mannual as well.
As you are using Razor, just set Layout = null; at the top of your view and it will be treated as partial view. Secondly you can easily make any field as hidden using display property under Style attribute.
Happy Coding :)

Razor - write unique tag into <body>

I am follwing this dom-based routing for kicking off specific javascript on each page
http://viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution
So need to write a unique data attribute into the tag each time a page loads
e.g.
<body data-controller="Home" data-action="Index">
What's the best place to put this logic for a razor view?
The body tag is in my masterpage (_layout.cshtml) file. And it needs to dynamically render that on each page
Was thinking of overriding OnActionExecuting in a base controller and have that inject the current controller and action name into the ViewBag. Then referencing the ViewBag properties in my _layout.cshtml
Does that make sense or is there a more appropriate place for this functionality?
You don't need to pass the data through ViewBag (although it could work), instead of you can access the current controller and action through the ViewContext property in any View (even in Layout)
<body
data-controller="#(ViewContext.RequestContext.RouteData.Values["controller"])"
data-action="#(ViewContext.RequestContext.RouteData.Values["action"])">
For setting other "global properties" on the ViewBag the OnActionExecuting (maybe combined with a base class or using a custom a filter) is the right place.

Resources