Razor View - Проблемы с разделом - PullRequest
2 голосов
/ 25 января 2011

Я только что получил ошибку, которую не ожидал увидеть ...

Для ясности я покажу рабочий код и код с ошибкой:

Это работает

_MainLayout.cshtml

<div id="content">
    <h1>@Page.Title</h1>
    @RenderSection("left", false)
    @RenderBody()
</div> 

Page.cshtml

@section left{
<p>Some text on left side</p>
}

<div>
    Some content
</div>

В этом случае все работает нормально, но когда я удалил @RenderSection("left", false) внутри _MainLayout.cshtml, я получаюисключение!В каком случае мне это нужно?См. Пример ниже:

Это не работает

_MainLayout.cshtml

@if (WebSecurity.IsAuthenticated) {
    <h1>@Page.Title</h1>
    @RenderSection("left", false)
    @RenderBody()
} else {
    <h1>You not logged in!</h1>
    <p>To see this page, you have to login first.</p>
}

Page.cshtml

@section left{
<p>Some text on left side</p>
}

<div>
    Some content
</div>

В этом случае, если пользовательне аутентифицирован, у меня есть это исключение:

Описание: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Сведения об исключении: System.Web.HttpException: Следующие разделы были определены, но не были обработаны для страницы макета "~/_MainLayout.cshtml": "left". Что может бытьпереводится как: Section was created but wasn't rendered for layout page "~/_MainLayout.cshtml": "left".

Ошибка источника:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Трассировка стека:

[HttpException (0x80004005): Следующие разделы были определены, но не были обработаны для страницы макета "~/_MainLayout.cshtml": "left".]
   System.Web.WebPages.WebPageBase.VerifyRenderedBodyOrSections() +91298
   System.Web.WebPages.WebPageBase.PopContext() +332
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +95
   System.Web.WebPages.<>c__DisplayClass7.<RenderPageCore>b__6(TextWriter writer) +102
   System.Web.WebPages.HelperResult.WriteTo(TextWriter writer) +12
   System.Web.WebPages.WebPageBase.Write(HelperResult result) +67
   System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body) +66
   System.Web.WebPages.WebPageBase.PopContext() +262
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +95
   System.Web.WebPages.WebPageHttpHandler.ProcessRequestInternal(HttpContext context) +249

Вопрос: как я могу заставить его работать?Любой совет ценен!

Ответы [ 2 ]

2 голосов
/ 25 января 2011

Проблема в том, что вы все еще объявляете раздел в своем дочернем представлении, а механизм рендеринга бритвы не знает, что с ним делать.

Я не уверен, что лучшим способом решения этой проблемы были бы некоторые возможные обходные пути:

  • Переместите RenderSection("left", false) за пределы тела блока if.
  • Обработайте вашу безопасность в контроллере и выведите на экран другое представление, если пользователь ничего не видит ( это, вероятно, предпочтительнее )
1 голос
/ 04 марта 2013

К сожалению, эта "проблема" все еще сохраняется с Razor ( Веб-страницы на самом деле ). Распространенное решение, которое я видел ( и применялось при необходимости ), заключается в том, чтобы молча отбросить содержимое раздела до нуля TextWriter:

@if (WebSecurity.IsAuthenticated) {
    <h1>@Page.Title</h1>
    @RenderSection("left", false)
    @RenderBody()
} else {
    <h1>You not logged in!</h1>
    <p>To see this page, you have to login first.</p>
    @{
        WriteTo(TextWriter.Null, RenderSection("left"));
    }
}

Вызов RenderSection удовлетворяет навязанному требованию вызова соответствующего RenderSection для каждого определенного раздела. Дамп до TextWriter.Null отбрасывает содержимое и обеспечивает минимальное влияние на потребление памяти ( другие реализации использовали new StringWriter(), но содержимое временно буферизовалось в памяти )

Это взлом, но это работает; Я пытаюсь скрыть это как часть процесса рендеринга.

...