首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ActionResult扩展不适用于Page() ActionResult方法

ActionResult扩展不适用于Page() ActionResult方法
EN

Stack Overflow用户
提问于 2019-05-05 05:53:41
回答 2查看 671关注 0票数 6

我有一个ActionResult的扩展名,它在返回页面时为TempData添加了一个祝酒词:

代码语言:javascript
复制
public static IActionResult WithMessage(this ActionResult result, InformMessage msg)
{
    return new InformMessageResult(result, msg);
}

这是InformMessageResult:

代码语言:javascript
复制
public class InformMessageResult : ActionResult
    {
        public ActionResult InnerResult { get; set; }
        public InformMessage InformMessage { get; set; }

        public InformMessageResult (ActionResult innerResult, InformMessage informMsg)
        {
            InnerResult = innerResult;
            InformMessage = informMsg;
        }

        public override async Task ExecuteResultAsync(ActionContext context)
        {
            ITempDataDictionaryFactory factory = context.HttpContext.RequestServices.GetService(typeof(ITempDataDictionaryFactory)) as ITempDataDictionaryFactory;
            ITempDataDictionary tempData = factory.GetTempData(context.HttpContext);

            tempData.Put("InformMessage", InformMessage);

            await InnerResult.ExecuteResultAsync(context);
        }
    }

这很适用于

代码语言:javascript
复制
return RedirectToPage(etc).WithMessage(etc)

诸如此类的,但失败了

代码语言:javascript
复制
return Page().WithMessage(etc)

调试器突出显示

代码语言:javascript
复制
await InnerResult.ExecuteResultAsync(context);

表示InnerResult未设置为对象的实例。

有什么方法可以让返回页面()来完成这个任务吗?

编辑以获取更多信息:

我测试了作为"InnerResult“发送的内容,它看起来与返回Page()类似,一切都是空的(根据设计,我要说,在此之前我什么也不做):

使用RedirectToPage():

与Page()一起:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-16 10:17:06

Page()RedirectToPage()分别是PageResultRedirectToPageResult的辅助方法。所以,你可以把这些方法称为newing,而不是newing。

当您调用Page()时,它会在幕后调用ExecuteResultAsync来呈现PageResult。此时,所有属性都为null,即PageModelViewData等。由于结果已经呈现,所以不能使用WithMessage扩展方法调用另一个ExecuteResultAsync

当您调用RedirectToPage时,它会发出301/302并生成一个新的Request,这将导致RedirectToPageResult。因此,RedirectToPageResult尚未呈现,您可以选择使用您的WithMessage扩展方法。

尽管如此,我认为在使用WithMessage方法AFAIK时不可能使用Page()

票数 0
EN

Stack Overflow用户

发布于 2020-04-20 17:38:10

这是一个较老的问题,但我需要这样的功能,并深入挖掘,以找到原因。

从调试中可以看到,Page方法生成一个完全空白的PageResult。既然每个属性都是空的,那么对其调用ExecuteResultAsync就会失败,因为它显然不能对所有空值执行任何操作。

Page()之所以能在剩下的时间里工作,是因为PageActionInvoker中的幕后魔术,特别是它的InvokeResultAsync方法。它将检测到您的ViewData和Page是空的,并在它调用pageResult.ExecuteResultAsync方法之前填充它们。

因此,如果您执行与InformMessageResult相同的工作,仍然可以让您的PageActionInvoker工作。下面是操作步骤:

代码语言:javascript
复制
public override async Task ExecuteResultAsync(ActionContext context)
{
    /* temp data work goes here */

    if (InnerResult is PageResult pageResult)
    {
        var pageContext = context as PageContext
            ?? throw new ArgumentException("context must be a PageContext if your InnerResult is a PageResult.", "context");

        var pageFactoryProvider = pageContext.HttpContext.RequestServices.GetRequiredService<IPageFactoryProvider>();
        var pageFactory = pageFactoryProvider.CreatePageFactory(pageContext.ActionDescriptor);

        var viewContext = new ViewContext(
            pageContext,
            NullView.Instance,
            pageContext.ViewData,
            tempData,
            TextWriter.Null,
            new Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelperOptions()
        );
        viewContext.ExecutingFilePath = pageContext.ActionDescriptor.RelativePath;

        pageResult.ViewData = viewContext.ViewData;
        pageResult.Page = (PageBase)pageFactory(pageContext, viewContext);
    }

    await InnerResult.ExecuteResultAsync(context);
}

private class NullView : IView
{
    public static readonly NullView Instance = new NullView();

    public string Path => string.Empty;

    public Task RenderAsync(ViewContext context)
    {
        if (context == null) throw new ArgumentNullException("context");
        return Task.CompletedTask;
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55989209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档