Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to expose global object like @User in razor views?

How/Where can I declare an object like @User so that it can be referenced globally in any razor view using @?

Something similar to:

_LoginPartial.cshtml:

@if(Request.IsAuthenticated) {
    <text>Signed In As  <strong>@User.Identity.Name</strong> |

but instead reference my object:

  @if(this && that) { <text>@MyObject.GetData</text> }
like image 377
genxgeek Avatar asked Dec 20 '11 17:12

genxgeek


People also ask

How do you declare a global variable in Razor?

To declare a variable in the View using Razor syntax, we need to first create a code block by using @{ and } and then we can use the same syntax we use in the C#. In the above code, notice that we have created the Code block and then start writing C# syntax to declare and assign the variables.

What is the difference between Razor view and Razor page?

The difference between them is that View Pages are Razor views that are used to provide the HTML representations (aka views) for services in much the same way View Pages work for MVC Controllers.

How do you use namespace in Razor view?

To import a namespace in Razor view, we use using statement as we write in C# class however it should be prefixed with @. Here we are importing namespace MVCTraining5. Utility namespace. To call any method insider that namespace, we do not need to give a fully qualified name.

What does return View () in MVC do?

The default behavior of the View method ( return View(); ) is to return a view with the same name as the action method from which it's called. For example, the About ActionResult method name of the controller is used to search for a view file named About.


2 Answers

You can change the base type of a Razor page to a one of your own eg:

public class UserAwareViewPage : System.Web.Mvc.WebViewPage
{
  public IPrincipal User { get { return Thread.CurrentPrincipal; } }
}

And then modify your config file like so:

<system.web.webPages.razor>
  <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, 
  System.Web.Mvc, Version=3.0.0.0, 
  Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  <pages pageBaseType="Your.Namespace.UserAwareViewPage">
    <namespaces>
      <add namespace="System.Web.Mvc" />
      <add namespace="System.Web.Mvc.Ajax" />
      <add namespace="System.Web.Mvc.Html" />
      <add namespace="System.Web.Routing" />
    </namespaces>
  </pages>
</system.web.webPages.razor>

Phil Haack has a very good blog post on this here.

Alternatively, you can add an extension method to System.Web.Mvc.WebViewPage (the base type for razor pages) and use this.

public static IPrincipal User(this System.Web.Mvc.WebViewPage page)
{
  return Thread.CurrentPrincipal;
}

Which would be useable like so:

@if(Request.IsAuthenticated) {
<text>Signed In As  <strong>@User().Identity.Name</strong>

Personally, I prefer the first approach, but thought I'd provide the second for an alternative option.

like image 131
Rich O'Kelly Avatar answered Oct 12 '22 05:10

Rich O'Kelly


The @ syntax isn't referencing values in any way, it's just telling the view engine that you're beginning a server-side code block.

There's nothing "global" about it. In this case, User is a property on the System.Web.WebPages.WebPageRenderingBase abstract class, which is used by the view engine when rendering views as they inherit from it.

I suppose you can extend the WebViewPage or the WebViewPage<> classes to add properties to them. There may be a better way to achieve what you're trying to do without modifying those, though. If you're trying to pass data to the View, shouldn't that data be part of the ViewModel?

Ideally you'd supply everything the View needs in a custom ViewModel and the View would inherit from WebViewPage<CustomViewModel>.

In Razor syntax I think you'd begin the CSHTML with something like:

@model CustomViewModel

Then you'd access properties on that using the Model property:

@Model.SomeProperty
like image 26
David Avatar answered Oct 12 '22 04:10

David