【问题标题】:how to retrieve actual error message in case of Bad Request using OwinContext middleware in .Net Web Api 2?如果在.Net Web Api 2中使用OwinContext中间件出现错误请求,如何检索实际错误消息?
【发布时间】:2020-06-02 07:15:34
【问题描述】:

当 .Net Web API 返回 Badrequest("this is an example of Badrequest".) 时,我的中间件中的 IOwinContext 对象仅包含 context.Response.StatusCode 400 和 context.Response.ReasonPhrase 作为“错误请求”。我想要实际的错误消息,以便我可以在某处记录它。是否可以在不编写任何自定义类的情况下从IOwinContext 获取实际错误消息?

编辑: Startup.cs

public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ICoreLogger dv_logger = new CoreLogger();
            app.Use<InvalidAuthenticationMiddleware>(dv_logger);
            ConfigureOAuth(app);
            //register log4net
            XmlConfigurator.Configure();
            // configure log4net variables
            GlobalContext.Properties["processId"] = "dv_logger";
            System.Web.Http.GlobalConfiguration.Configure(WebApiConfig.Register);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            //entity framework
            DbContext.Intialize();
            AuthContext.Intialize();
            .....
   }

中间件

 public class InvalidAuthenticationMiddleware : OwinMiddleware
{
        public override async Task Invoke(IOwinContext context)
        {
            var stream = context.Response.Body;
            using (var buffer = new MemoryStream())
            {
                context.Response.Body = buffer;
                await Next.Invoke(context);

                buffer.Seek(0, SeekOrigin.Begin);
                using (var reader = new StreamReader(buffer))
                {
                    string responseBody = await reader.ReadToEndAsync();

                    if (context.Response.StatusCode == (int)HttpStatusCode.BadRequest)
                    {
                        var definition = new { Message = "" };
                        var error = JsonConvert.DeserializeAnonymousType(responseBody, definition);

                        Debug.WriteLine(error.Message);
                    }

                    buffer.Seek(0, SeekOrigin.Begin);
                    await buffer.CopyToAsync(stream);
                }
            }
        }

}

控制器

public class LoginController : BaseController
{
        [Route("")]
        public IHttpActionResult Get(string email)
        {
           return BadRequest("this is an example of bad request!");
        }
}

【问题讨论】:

  • ConfigureOAuth() 是做什么的?你为什么不使用appBuilder.UseWebApi(config) 而不是GlobalConfiguration.Configure()?您应该简化您的Startup.Configuration() 并删除一些部分以缩小您的问题范围。
  • 我们使用的是appBuilder.UseWebApi(config),但我们的项目中也有一个 MVC 控制器。所以,我们不得不切换到GlobalConfiguration.Configure()ConfigureOAuth 设置 Owin 授权的属性。

标签: c# asp.net-web-api2 owin http-status-code-400 owin-middleware


【解决方案1】:

您必须阅读响应的正文。 BadRequest("this is an example of BadRequest") 在响应正文中设置一个对象,其属性Message 包含该消息。我假设您使用 JSON 作为序列化格式:

{
    "Message": "this is an example of BadRequest"
}

这是在响应为BadRequest 时记录错误消息的中间件代码:

public override async Task Invoke(IOwinContext context)
{
    var stream = context.Response.Body;
    using (var buffer = new MemoryStream())
    {
        context.Response.Body = buffer;

        await next.Invoke();

        buffer.Seek(0, SeekOrigin.Begin);
        using (var reader = new StreamReader(buffer))
        {
            string responseBody = await reader.ReadToEndAsync();

            if (context.Response.StatusCode == (int)HttpStatusCode.BadRequest)
            {
                var definition = new { Message = "" };
                var error = JsonConvert.DeserializeAnonymousType(responseBody, definition);

                Console.WriteLine(error.Message);
            }

            buffer.Seek(0, SeekOrigin.Begin);
            await buffer.CopyToAsync(stream);
        }
    }
}

请注意,我使用匿名类型以避免必须为错误消息对象声明一个类。

【讨论】:

  • 如果我在上面运行代码,responseBody 变量总是设置为空字符串。有什么建议吗?
  • 如何注册中间件?您能否包含代码的最小示例(您的控制器返回 BadRequest + 您的启动)?
  • app.Use(dv_logger);在这里, InvalidAuthenticationMiddleware 包含您的代码。控制器:return BadRequest("这是一个错误请求的例子!");
  • 你也没有app.UseWebApi(config); 吗?注册中间件的顺序很重要。确保在app.UseWebApi(config); 之前注册您的InvalidAuthenticationMiddleware。一般来说,日志中间件必须先注册。
  • 是的。中间件在System.Web.Http.GlobalConfiguration.Configure(WebApiConfig.Register);之前注册
猜你喜欢
  • 2019-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
  • 2016-06-10
  • 1970-01-01
  • 2017-07-28
相关资源
最近更新 更多