Подтвердить что ты не робот

Render Razor отображает строку в ASP.NET 5

В предыдущих версиях ASP.NET было возможно, хотя и не очень просто, отображать представления Razor как строки. Методы, которые, как мне кажется, должны использовать поддельный контроллер, а также использовать какой-то внешний движок, например RazorEngine.

Теперь многое изменилось с помощью ASP.NET 5, и мне стало интересно, проще ли это сейчас. Итак, в новой версии рамки есть один простой способ визуализации представлений Razor в виде строк или нам все еще нужно использовать методы из предыдущих версий?

4b9b3361

Ответ 1

Я использую следующие типы, введенные из IServiceProvider:

ICompositeViewEngine viewEngine;
ITempDataProvider tempDataProvider;
IHttpContextAccessor httpContextAccessor;

Я создаю контент, используя следующий метод:

private async Task<string> RenderView(string path, ViewDataDictionary viewDataDictionary, ActionContext actionContext)
{
    using (var sw = new System.IO.StringWriter())
    {
        var viewResult = viewEngine.FindView(actionContext, path);

        var viewContext = new ViewContext(actionContext, viewResult.View, viewDataDictionary, new TempDataDictionary(httpContextAccessor, tempDataProvider), sw);

        await viewResult.View.RenderAsync(viewContext);
        sw.Flush();

        if (viewContext.ViewData != viewDataDictionary)
        {
            var keys = viewContext.ViewData.Keys.ToArray();
            foreach (var key in keys)
            {
                viewDataDictionary[key] = viewContext.ViewData[key];
            }
        }

        return sw.ToString();
    }
}

Я называю это следующим образом:

var path = "~/Views/Home/Index.cshtml";
var viewDataDictionary = new ViewDataDictionary(new Microsoft.AspNet.Mvc.ModelBinding.EmptyModelMetadataProvider(), new Microsoft.AspNet.Mvc.ModelBinding.ModelStateDictionary());
var actionContext = new ActionContext(httpContextAccessor.HttpContext, new Microsoft.AspNet.Routing.RouteData(), new ActionDescriptor());
viewDataDictionary.Model = null;
var text = await RenderView(path, viewDataDictionary, actionContext);

Конечно, мои переменные viewDataDictionary и actionContext устанавливаются другим методом для инкапсуляции. Модификация строки new ViewDataDictionary может привести к тому, что типичная модель привязана к вашему представлению, если вы выберете.

Этот код использует тяжелые заголовки, я думаю, что я перечислил их ниже. В противном случае VS2015 неплохо находит их.

using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;

Это было написано в бета-3; он все еще строит, но некоторые вещи могут измениться. Я попробую вернуться сюда, чтобы обновить, если это произойдет.

Ответ 2

Есть решение, которое я использовал год назад. Я не уверен, есть ли новый/лучший способ сделать, но он решает проблему.

public string RenderViewToString(string viewName, object model)
{
    ViewData.Model = model;
    using (var sw = new StringWriter())
    {
       var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
       var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
       viewResult.View.Render(viewContext, sw);
       viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
       return sw.GetStringBuilder().ToString();
     }
}