NotSupportedException в Asp.NET Core MVC Визуализация бритвенных страниц - PullRequest
0 голосов
/ 04 апреля 2019

Недавно я создал небольшой проект ASP.Net Core MVC и поместил все мои файлы .cshtml в каталог Views.Затем я использовал следующий код в Startup.cs, чтобы изменить место, где Razor ищет файлы представлений:

services.Configure<RazorViewEngineOptions>(options => {
    //{2} is area, {1} is controller, {0} is the action    
    options.ViewLocationFormats.Clear();
    options.ViewLocationFormats.Add("/Views/{1}" + RazorViewEngine.ViewExtension);
});

Файлы .cshtml сопоставляются с соответствующим именем контроллера, где все контроллеры содержат действие «Индекс» по умолчаниюэто просто возвращает связанный View ().

Это текущая маршрутизация:

app.UseMvc(routes => {
    routes.MapRoute(
        name: "default",
        template: "{controller=Index}/{action=Index}/{id?}");
});

На мой взгляд, эта конфигурация должна работать, однако Razor выбрасывает исключение NotSupportedException всякий раз, когда япопробуйте вызвать любую страницу, и я не уверен, как отладить это:

NotSupportedException: Specified method is not supported.
Microsoft.AspNetCore.Mvc.RazorPages.PageBase.EnsureRenderedBodyOrSections()
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderLayoutAsync(ViewContext context, ViewBufferTextWriter bodyWriter)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ActionContext actionContext, IView view, ViewDataDictionary viewData, ITempDataDictionary tempData, string contentType, Nullable<int> statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext context, ViewResult result)
Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync<TFilter, TFilterAsync>()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Я посмотрел на исходный код EnsureRenderedBodyOrSections (), который просто следующий:

public override void EnsureRenderedBodyOrSections() {
    //This will never be called by MVC. MVC only calls this method on layout pages, and a Page can never be a layout page.
    throw new NotSupportedException();
}

MVC, очевидно, вызывает функцию, когда она не должна.В чем конкретно заключается проблема?

PS: Это проект на GitHub: https://github.com/mathusummut/nemesys-stackoverflow

1 Ответ

1 голос
/ 04 апреля 2019

Причина, по которой вызывается метод EnsureRenderedBodyOrSections, заключается в том, что вы возвращаете View() результат из контроллера, и этот метод является частью жизненного цикла рендеринга для Views . Однако ваши файлы Razor имеют директивы @page вверху, что превращает их в файлы подкачки для Razor Pages .

Хотя вы можете использовать MVC Views и Razor Pages в одном приложении, их нельзя смешивать для одного пути запроса . Если вы удалите директиву @page из файлов View, они будут скомпилированы как Razor Views, а не как Razor Pages, поэтому вы не получите NotSupportedException.

В качестве примечания, я бы порекомендовал удалить строку options.ViewLocationFormats.Clear(); и оставить расположение вида по умолчанию, чтобы в будущем вы могли использовать местоположение вида Views/{Controller}/{Action}, при этом сохраняя возможность иметь файл вида с именем * 1018. *. Таким образом, добавляя больше функциональности в приложение MVC, вы можете сделать это, используя традиционные шаблоны MVC.

...