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

时间:2019-05-05 05:53:42

标签: c# asp.net-core extension-methods razor-pages

我有一个ActionResult扩展名,当返回页面时,它向TempData添加了敬酒:

public static IActionResult WithMessage(this ActionResult result, InformMessage msg)
{
    return new InformMessageResult(result, msg);
}

这是InformMessageResult:

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);
        }
    }

这很适合

return RedirectToPage(etc).WithMessage(etc)

之类,但失败

return Page().WithMessage(etc)

和调试器亮点

await InnerResult.ExecuteResultAsync(context);

说InnerResult未设置为对象的实例。

是否可以使用Return Page()进行此工作?

编辑以获取其他信息:

我测试了作为“ InnerResult”发送的内容,并且看起来像使用Return Page()一样,所有内容都是空的(根据设计,我会说,因为在此之前我什么都不做):

with RedirectToPage():

enter image description here

使用Page():

enter image description here

3 个答案:

答案 0 :(得分:2)

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

从调试中可以看到,folder_N/script.py方法生成一个完全空白的from folder_N import script。由于每个属性都为空,因此在其上调用Page会失败,因为它显然无法对全空值执行任何操作。

PageResult其余时间仍然有效的原因是PageActionInvoker中的幕后魔术,尤其是其InvokeResultAsync方法。它将检测到您的ViewData和Page为空白,并在其本身调用ExecuteResultAsync方法之前填充它们。

因此,如果您执行与PageActionInvoker相同的工作,仍然可以使Page()正常工作。方法如下:

pageResult.ExecuteResultAsync

答案 1 :(得分:1)

我怀疑的问题是Page()和RedirectToPage()继承自不同的基类。

RedirectToPage()按照此documentation。它具有以下继承:

  

对象->动作结果-> RedirectToPageResult

这通过控制器的某些继承而暴露。因此,您可以使用ActionResult的扩展名。

但是,根据此documentation,Page()方法是RazorPages类的一部分。因此它的继承如下: 1

  

对象-> RazorPageBase-> PageBase->页面

现在,该类的Page()方法确实返回了一个PageResult,它看起来是从ActionResult继承为defined here.

因此,考虑到这一点,我建议先将其强制转换为基础ActionResult,然后再使用扩展方法。也许是这样的:

var baseClass = (Page() as ActionResult);
return baseClass.WithMessage(etc);

1 您可以在OP提供的第二张图像中看到基本类型。

答案 2 :(得分:0)

Page()RedirectToPage()分别是PageResultRedirectToPageResult的帮助方法。因此,您无需调用新方法就可以调用这些方法。

调用Page()时,它会在后台调用ExecuteResultAsync来渲染PageResult。此时,所有属性均为空,即PageModelViewData等。由于已经渲染了结果,因此您不能使用来调用另一个ExecuteResultAsync WithMessage扩展方法。

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

话虽如此,我认为在使用WithMessage方法AFAIK时无法利用Page()