Как вернуть другую страницу Razor без перенаправления? - PullRequest
0 голосов
/ 24 мая 2018

Я портирую приложение Asp.Net MVC на Razor Pages.

В некоторых контроллерах приложения MVC используется return View("someOtherView", someModelForOtherView);

Как перенести это наБритва страницы?Что мне нужно сделать, это перенести запрос на другую страницу Razor и передать ему подготовленную PageModel (другая страница не должна выполнять OnMethod(), а просто отображает ее html. Или, другими словами, мне нужно толькоПоменяйте местами файл шаблона, который должен быть отображен с другим.

Я не могу использовать Redirect, так как не должно быть другого обхода через браузер.

1 Ответ

0 голосов
/ 26 октября 2018

Я сомневаюсь, что это (легко) возможно.Из запроса github , который Лернер связал выше, отмечается, что Razor Pages не были предназначены для этого.

Самый близкий обходной путь, которого мне удалось достичь, - это превратить мою страницу назначения Razor вПосмотреть.(Следовательно, без кода.) Очевидно, что это будет возможно, только если к вашей целевой странице никогда не будет прямого доступа через URL.Например, если вы хотите перенаправить на /Pages/MyPage, и вам все еще нужно иметь возможность доступа к URL http://example.com/MyPage, это не будет работать.

Но, скажем, все, что вы хотите, это общая ошибкаили страница состояния.Они не должны быть напрямую доступны через URL.Это хорошо работает для этого.

Вот пара методов расширения для PageModel, чтобы сделать это, один, который принимает модели, а другой - нет:

public static ViewResult View(this PageModel pageModel, string viewName) {
    return new ViewResult() {
        ViewName = viewName,
        ViewData = pageModel.ViewData,
        TempData = pageModel.TempData
    };
}

public static ViewResult View<TModel>(this PageModel pageModel, string viewName, TModel model) {
    var viewDataDictionary = new ViewDataDictionary<TModel>(new EmptyModelMetadataProvider(), new ModelStateDictionary()) {
        Model = model
    };
    foreach (var kvp in pageModel.ViewData) viewDataDictionary.Add(kvp);

    return new ViewResult {
        ViewName = viewName,
        ViewData = viewDataDictionary,
        TempData = pageModel.TempData
    };
}

FYI,причина для того, чтобы воссоздать словарь представления, состоит в том, что в вашем pageModel будет тип модели, специфичный для текущей страницы, а не для представления, на которое вы направляете, и вы не можете изменить модель внутриViewDataDictionary для другого типа.MVC будет жаловаться и выдавать исключение.

Использование:

public IActionResult OnGet(string id) {
    // check if id is good here     
    if (idIsNoGood) return this.View("InvalidId", new ErrorModel...);
    else {
        return Page();
    }
}

Выше будет выглядеть представление InvalidId.cshtml, которое может находиться в той же папке, что и ваша страница,корневая папка /Pages/ или /Pages/Shared/.И он все равно будет использовать ваш макет, как и любую другую страницу.

Просто убедитесь, что ваш файл cshtml не имеет директивы @page вверху;это не будет работать для страницы Razor, только View.

Пример InvalidId.cshtml:

@model MyProject.Models.ErrorModel
<h1>Invalid Request</h1>
<p>@Model.Message</p>
...