我正在尝试使用扩展方法来装饰 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);
}
答案 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
如上所述,您只能访问ViewData
和Controller
中的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);
}
}