gpt4 book ai didi

c# - 在 OnResultExecuting 中更改 filterContext.Result

转载 作者:太空狗 更新时间:2023-10-29 23:21:54 26 4
gpt4 key购买 nike

我有一个应用了属性的 Controller 操作,如果 ModelState 有错误,它会将它们设置为 OnResultExecuting 方法中的 JsonResult

我在 MyAction 中设置值。我在 OnResultExecuting 的属性中更改了它,但在 Controller 中的 OnResultExecuted 中,结果是来自 Controller 的结果,而不是在属性中设置的结果。

所以我的问题是为什么 OnResultExecuted 中的值保持不变,我如何让它停止这样做?

public class MyController:Controller
{
[ValidateDatedObject(SkipActionExecution = true, LeaveJustModelState = true)]
public JsonResult MyAction(ViewModel viewModel)
{
return new JsonResult { Data = new { Success = false }}; // Setting the initial value
}
protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);//filterContext.Result here is the on from the controller instead of the one from the attribute
}
}

public class ValidateDatedObject : ModelValidationFilter
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
}//filterContext.Result here is the one from the attribute
}

public abstract class ModelValidationFilter : ActionFilterAttribute
{
private JsonResult getModelStateAsJsonResult(ModelStateDictionary modelState)
{
return new JsonResult { Data = new { modelState = SerializeErrors(modelState) } };
}

public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.Result = getModelStateAsJsonResult(filterContext.Controller.ViewData.ModelState); //Setting filterContext.Result here
}
}

最佳答案

那是因为在 OnResultExecuting 中,您要用新实例替换当前结果。这将修改 ResultExecutingContext 中的结果,但会使整体结果保持不变。

但是您可以修改结果而不是替换它

public abstract class ModelValidationFilter : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
//Modify the values in the current filterContext.Result instead of replacing it with a new instance
var jsonResult = filterContext.Result as JsonResult;
if(jsonResult == null) return;
//possibly replace Data only under certain conditions
jsonResult.Data = new { modelState = SerializeErrors(modelState) };
}
}

原因是 MVC 执行 ResultFilters 的方式。您可以检查 ControllerActionInvoker.InvokeActionResultFilterRecursive 的实现.这是在每个过滤器上调用 OnResultExecuting 的代码,执行操作,然后以相反的顺序调用 OnResultExecuted

如果仔细观察,您会注意到 ResultExecutedContext 是通过对原始 actionResult 对象的引用创建的,而不是通过对 ResultExecutingContext.Result 的引用创建的。 (除非您设置 ResultExecutingContext.Cancel=true,这将停止处理其他过滤器并返回当时的任何结果,但这也意味着 Controller OnResultExecute 不会被执行)

因此在这段代码中有一个假设,即 ResultFilters 可能会修改 ResultExecutingContext.Result 中的属性值,但不会用新实例完全替换它。

关于c# - 在 OnResultExecuting 中更改 filterContext.Result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29693402/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com