Web Api 请求内容在操作过滤器中为空

编程入门 行业动态 更新时间:2024-10-17 21:17:08
本文介绍了Web Api 请求内容在操作过滤器中为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个名为 Log 的属性,它尝试将请求和响应的内容记录到文本文件中.我已经把它放在我的控制器上以覆盖所有的动作.在 LogAttribute 中,我将内容作为字符串 (ReadAsStringAsync) 读取,因此我不会丢失请求正文.

I have an attribute named Log that tries to log the content of request and response into a text file. I've put that over my Controller to cover all the actions. In LogAttribute I'm reading content as a string (ReadAsStringAsync) so I don't lose request body.

public class LogAttribute : ActionFilterAttribute { // .. public override void OnActionExecuting(HttpActionContext actionContext) { // stuff goes here var content = actionContext.Request.Content.ReadAsStringAsync().Result; // content is always empty because request body is cleared } public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { // other stuff goes here var content = actionContext.Request.Content.ReadAsStringAsync().Result; // content is always empty because request body is cleared } // .. }

另一方面,我已将 FromBody 属性放在我的操作参数类之前,以利用其优势.

On the other hand, I've put the FromBody attribute before my action parameter class to take advantage of its benefits.

[Log] public class SomethingController { public HttpResponseMessage Foo([FromBody] myModel) { // something } }

问题是 ActionExecuting 或 ActionExecuted 中的内容始终为空.

The problem is the content is always empty either in ActionExecuting or ActionExecuted.

我认为这是因为 FromBody 在我的 Log 属性之前运行,这与它们在代码中的顺序不同.我再次认为这是因为根据动作参数(路由处理)为请求找到最佳动作/控制器匹配.之后我的请求正文被清除,因为请求正文在 WebApi 中没有缓冲.

I think this is because FromBody runs before my Log attribute unlike their order in the code. And again I think its because of finding the best action/controller match for the request according to action parameters (Route Processing). After that my request body is cleared since request body is non-buffered in WebApi.

我想知道有没有什么办法可以改变FromBody属性和我的Log属性的运行时顺序?或其他解决问题的方法!我应该提到我不想删除 FromBody 并使用 HttpRequestMessage 而不是我的模型或类似的东西.

I want to know if there is any way to change the run time order of the FromBody attribute and my Log attribute? or something else that solves the problem! I should mention that I don't want to remove the FromBody and using HttpRequestMessage instead of my Model or something like that.

推荐答案

请求体是不可回绕的流;它只能读取一次.格式化程序已经读取了流并填充了模型.我们无法在操作过滤器中再次读取流.

The request body is a non-rewindable stream; it can be read only once. The formatter has already read the stream and populated the model. We're not able to read the stream again in the action filter.

你可以试试:

public class LogAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { var myModel = actionContext.ActionArguments["myModel"]; } public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { var myModel = actionContext.ActionArguments["myModel"]; } }

实际上,ActionArguments 只是一个字典,如果我们需要避免硬编码参数名称("myModel"),我们可以循环遍历它.当我们创建一个通用动作过滤器,需要针对某些特定要求处理类似对象的类时,我们可以让我们的模型实现一个接口 => 知道哪个参数是我们需要处理的模型,但我们可以调用这些方法界面.

Actually, ActionArguments is just a dictionary, we can loop though it if we need to avoid hardcoded parameter name ("myModel"). When we create a generic action filter that needs to work on a class of similar objects for some specific requirements, we could have our models implement an interface => know which argument is the model we need to work on and we can call the methods though the interface.

示例代码:

public class LogAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { foreach(var argument in actionContext.ActionArguments.Values.Where(v => v is ILogable))) { ILogable model = argument as ILogable;//assume that only objects implementing this interface are logable //do something with it. Maybe call model.log } } public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { foreach(var argument in actionContext.ActionArguments.Values.Where(v => v is ILogable))) { ILogable model = argument as ILogable;//assume that only objects implementing this interface are logable //do something with it. Maybe call model.log } } }

更多推荐

Web Api 请求内容在操作过滤器中为空

本文发布于:2023-11-02 17:06:45,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1552944.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:为空   器中   操作   内容   Web

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!