如何在ExecuteResultAsync中访问ViewDataDictionary?

时间:2019-01-31 00:34:34

标签: c# asp.net-core asp.net-core-mvc asp.net-core-2.0

简介

我正在尝试使用扩展方法来装饰 static void Main(string[] args) { string[] dates = { "20190127144251", "20190127123315", "20190127035942" }; foreach (string i in dates) { string str = i; str.Insert(3, "-"); str.Insert(5, "-"); str.Insert(7, "-"); str.Insert(9, ":"); str.Insert(11, ":"); Console.WriteLine(i); } } } 。目标是可以在Action - ViewResult之外的Decorator使用范围内设置ViewData。但是,我只能访问Controller,而我想访问方法TempData内部的ViewData

问题

  

在使用对ActionContext的访问中如何从ExecuteResultAsync访问ViewData?这是以下   可能吗?

场景

因此,不要编写以下内容:

ExecuteResultAsync

我正在尝试使其工作:

public async Task<IActionResult> ChangePassword()
{
    ViewData["Title"] = "Change Password";
    return PartialView("_ChangePasswordPartial",...);
}

扩展方式:

public async Task<IActionResult> ChangePassword()
{
    return PartialView("_ChangePasswordPartial",...).WithTitle("Change Password");
}

装饰器:

public static IActionResult WithTitle(this IActionResult action, string modalTitle)
{
    return new ModalTitleDecorator(action,modalTitle);
}

1 个答案:

答案 0 :(得分:1)

对于ViewData,您无法通过context.HttpContext.RequestServices.GetService来解决。

/// <summary>
/// Gets or sets <see cref="ViewDataDictionary"/> used by <see cref="ViewResult"/> and <see cref="ViewBag"/>.
/// </summary>
/// <remarks>
/// By default, this property is intiailized when <see cref="Controllers.IControllerActivator"/> activates
/// controllers.
/// <para>
/// This property can be accessed after the controller has been activated, for example, in a controller action
/// or by overriding <see cref="OnActionExecuting(ActionExecutingContext)"/>.
/// </para>
/// <para>
/// This property can be also accessed from within a unit test where it is initialized with
/// <see cref="EmptyModelMetadataProvider"/>.
/// </para>
/// </remarks>
[ViewDataDictionary]
public ViewDataDictionary ViewData

如上所述,您只能访问ViewDataController中的OnActionExecuting(ActionExecutingContext)。您无法通过已解决的服务访问它。

您可以尝试通过反映ViewData来访问IActionResult

尝试

public static class ActionResultExtension
{
    public static IActionResult WithTitle(this IActionResult action, string modalTitle)
    {
        return new ModalTitleDecorator(action, modalTitle);
    }
}

public class ModalTitleDecorator : PartialViewResult
{
    private readonly IActionResult _actionResult;
    private readonly string _modalTitle;

    public ModalTitleDecorator(IActionResult action, string modalTitle)
    {
        _actionResult = action;
        _modalTitle = modalTitle;
    }

    public override async Task ExecuteResultAsync(ActionContext context)
    {
        ViewDataDictionary viewData = _actionResult
                                    .GetType()
                                    .GetProperty("ViewData")
                                    .GetValue(_actionResult) as ViewDataDictionary;
        if (viewData != null)
        {
            viewData["Title"] = _modalTitle;
        }
        await _actionResult.ExecuteResultAsync(context);
    }
}