ASP.net核心:在将页面呈现为字符串时模型为空

ASP.net core: Model is null during rendering a page to string

我想将页面呈现为电子邮件模板。
但是当渲染器想要使用模型时出现错误
我遵循本教程:learnrazorpages.com

RazorRenderer.cs:

public class RazorRenderer : IRazorRenderer
{
    private readonly IRazorViewEngine _viewEngine;
    private readonly ITempDataProvider _tempDataProvider;
    private readonly IServiceProvider _serviceProvider;

    public RazorRenderer(
        IRazorViewEngine viewEngine,
        ITempDataProvider tempDataProvider,
        IServiceProvider serviceProvider)
    {
        _viewEngine = viewEngine;
        _tempDataProvider = tempDataProvider;
        _serviceProvider = serviceProvider;
    }

    public async Task<string> ToStringAsync<TModel>(string partialName, TModel model)
    {
        var actionContext = GetActionContext();
        var partial = FindView(actionContext, partialName);
        var viewData = new ViewDataDictionary<TModel>(new EmptyModelMetadataProvider(), new ModelStateDictionary());
        var tempData = new TempDataDictionary(actionContext.HttpContext, _tempDataProvider);

        viewData.Model = model;

        await using var stringWriter = new StringWriter();

        var viewContext = new ViewContext(
            actionContext,
            partial,
            viewData,
            tempData,
            stringWriter,
            new HtmlHelperOptions()
        );

        await partial.RenderAsync(viewContext);

        return stringWriter.ToString();
    }

    private IView FindView(ActionContext actionContext, string partialName)
    {
        var getPartialResult = _viewEngine.GetView(null, partialName, false);

        if (getPartialResult.Success)
        {
            return getPartialResult.View;
        }

        var findPartialResult = _viewEngine.FindView(actionContext, partialName, false);

        if (findPartialResult.Success)
        {
            return findPartialResult.View;
        }

        var searchedLocations = getPartialResult.SearchedLocations.Concat(findPartialResult.SearchedLocations);
        var errorMessage = string.Join(
            Environment.NewLine,
            new[]
            {
                $"Unable to find partial '{partialName}'. The following locations were searched:"
            }.Concat(searchedLocations));

        throw new InvalidOperationException(errorMessage);
    }

    private ActionContext GetActionContext()
    {
        var httpContext = new DefaultHttpContext
        {
            RequestServices = _serviceProvider
        };

        return new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
    }
}

Test.cs:

public class TestModel : PageModel
{
    private readonly IRazorRenderer _razorRenderer;

    public RecoveryModel(IRazorRenderer razorRenderer)
    {
        _razorRenderer = razorRenderer;
    }

    public void OnGet()
    {
    }

    public async Task<IActionResult> OnPost()
    {
        var body = await _razorRenderer.ToStringAsync(
            "Email",
            new Test
            {
                Email = "Email@Test.com"
            });

        return Content(body);
    }
}

Email.cshtml.cs

public class EmailModel : PageModel
{
    public string Email { get; set; }

    public void OnGet()
    {
    }
}

Email.cshtml:

@page
@model EmailModel
@{
    Layout = null;
}
@Model.Email // Here I get the exception (Model is null)

我哪里做错了?

Where did I do the wrong thing?

您需要创建一个局部视图,它是 razor 视图 而不是 razor 页面

Email.cshtml:

@model Test
@{
    Layout = null;
}
@Model.Email

型号:

public class Test
{ 
    public string Email { get; set; }
}

测试模型:

public async Task<IActionResult> OnPost()
{
    var body = await _razorRenderer.ToStringAsync(
        "Email",
        new Test
        {
            Email = "Email@Test.com"
        });

    return Content(body);
}

结果: