Как выставить глобальный объект, такой как @User, в бритвенных видах? - PullRequest
16 голосов
/ 20 декабря 2011

Как / Где я могу объявить объект наподобие @User, чтобы на него можно было ссылаться глобально в любом виде бритвы, используя @?

Что-то похожее на:

_LoginPartial.cshtml:

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

, но вместо этого ссылайтесь на мой объект:

  @if(this && that) { <text>@MyObject.GetData</text> }

Ответы [ 4 ]

27 голосов
/ 20 декабря 2011

Вы можете изменить базовый тип страницы Razor на свой собственный, например:

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

А затем измените ваш конфигурационный файл следующим образом:

<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>

У Фила Хаака очень хорошая запись в блоге по этому вопросу здесь .

Кроме того, вы можете добавить метод расширения к System.Web.Mvc.WebViewPage (базовый тип для бритвенных страниц) и использовать его.

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

Что бы можно было использовать так:

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

Лично я предпочитаю первый подход, но подумал, что предоставлю второй для альтернативного варианта.

4 голосов
/ 20 декабря 2011

Синтаксис @ никоим образом не ссылается на значения, он просто сообщает движку представления, что вы начинаете кодовый блок на стороне сервера.

В этом нет ничего "глобального".В этом случае User является свойством абстрактного класса System.Web.WebPages.WebPageRenderingBase, которое используется механизмом представления при отображении представлений как , которые они наследуют от него .

Полагаю, вы можете расширить классы WebViewPage или WebViewPage<>, чтобы добавить к ним свойства.Однако может быть лучший способ достичь того, что вы пытаетесь сделать, не изменяя их.Если вы пытаетесь передать данные в представление, не должны ли эти данные быть частью ViewModel?

В идеале вы должны предоставить все необходимое представление в пользовательской модели представления, а представление будет наследоваться от WebViewPage<CustomViewModel>.

В синтаксисе Razor я думаю, что вы начнете CSHTML с чего-то вроде:

@model CustomViewModel

Затем вы получите доступ к свойствам этого с помощью свойства Model:

@Model.SomeProperty
2 голосов
/ 21 декабря 2011

Или для менее навязчивого подхода, и это работает для любой страницы Razor, просто по умолчанию:

@Context.User.Identity.IsAuthenticated

Конечно, вы можете установить быстрый псевдоним переменной, если хотите вверху вашего файла Razor (_Layoutили иным образом):

@{
  var User = Context.User;
}

но на самом деле в этом нет необходимости, если только у вас нет обычного IPrincipal объекта в этом случае:

@{
  var User = (MyAuthenticatedUser)Context.User;
}

, и это работает, и это то, что я использую:)

2 голосов
/ 20 декабря 2011

Вы, вероятно, могли бы сделать что-то подобное в своем View:

@Html.ViewContext.HttpContext.User.Identity.Name

Однако я бы порекомендовал против этого и добавил эту информацию в ViewModel. Например:

public ActionResult SomeController()
{
    var model = new MyViewModel
    {
        Username = User.Identity.Name
    }
    return View(model);
}

Теперь внутри представления вы можете отобразить эту информацию:

@Model.Username
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...