温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

ASP.NET Core AutoWrapper自定义响应输出的实现示例

发布时间:2021-02-04 16:04:01 来源:亿速云 阅读:184 作者:小新 栏目:开发技术

小编给大家分享一下ASP.NET Core AutoWrapper自定义响应输出的实现示例,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

前言

AutoWrapper是一个简单可自定义全局异常处理程序和ASP.NET Core API响应的包装。他使用ASP.NET Core middleware拦截传入的HTTP请求,并将最后的结果使用统一的格式来自动包装起来.目的主要是让我们更多的关注业务特定的代码要求,并让包装器自动处理HTTP响应。这可以在构建API时加快开发时间,同时为HTTP响应试试我们统一的标准。

安装

AutoWrapper.Core从NuGet或通过CLI下载并安装

PM> Install-Package AutoWrapper.Core

在Startup.cs Configure方法中注册以下内容,但是切记要放在UseRouting前

app.UseApiResponseAndExceptionWrapper();

启动属性映射

默认情况下AutoWrapper将在成功请求成功时输出以下格式:

{   "message": "Request successful.",   "isError": false,   "result": [    {     "id": 7002,     "firstName": "Vianne",     "lastName": "Durano",     "dateOfBirth": "2018-11-01T00:00:00"    }   ] }

如果说不喜欢默认属性命名方式,那么我们可以通过AutoWrapperPropertyMap属性进行映射为我们需要指定的任何名称。例如我么可以将result属性的名称更改为data。如下所示

public class MapResponseObject  {   [AutoWrapperPropertyMap(Prop.Result)]   public object Data { get; set; } }

然后将MapResponseObject类传递给AutpWrapper middleware

app.UseApiResponseAndExceptionWrapper<MapResponseObject>();

通过映射重新请求后,现在影响格式如下所示

{   "message": "Request successful.",   "isError": false,   "data": {     "id": 7002,     "firstName": "Vianne",     "lastName": "Durano",     "dateOfBirth": "2018-11-01T00:00:00"   } }

可以从中看出result属性已经更换为data属性了

默认情况下AutoWrapper发生异常时将吐出以下响应格式

{   "isError": true,   "responseException": {     "exceptionMessage": "Unhandled Exception occurred. Unable to process the request."   } }

而且如果在AutoWrapperOptions中设置了IsDebug,则将产生带有堆栈跟踪信息的类似信息

{   "isError": true,   "responseException": {     "exceptionMessage": " Input string was not in a correct format.",     "details": "  at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type)\r\n  at System.Number.ParseInt32(ReadOnlySpan`1 value, NumberStyles styles, NumberFormatInfo info)\r\n …"   } }

如果想将某些APIError属性名称更改为其他名称,只需要在以下代码中添加以下映射MapResponseObject

public class MapResponseObject  {   [AutoWrapperPropertyMap(Prop.ResponseException)]   public object Error { get; set; }   [AutoWrapperPropertyMap(Prop.ResponseException_ExceptionMessage)]   public string Message { get; set; }   [AutoWrapperPropertyMap(Prop.ResponseException_Details)]   public string StackTrace { get; set; } }

通过如下代码来模拟错误

int num = Convert.ToInt32("10s");

现在映射后的输出如下所示

{   "isError": true,   "error": {     "message": " Input string was not in a correct format.",     "stackTrace": "  at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type)\r\n  at System.Number.ParseInt32(ReadOnlySpan`1 value, NumberStyles styles, NumberFormatInfo info)\r\n …"   } }

请注意APIError现在根据MapResponseObject类中定义的属性更改了模型的默认属性。

我们可以自由的选择映射任何属性,下面是映射属性相对应的列表

[AutoWrapperPropertyMap(Prop.Version)] [AutoWrapperPropertyMap(Prop.StatusCode)] [AutoWrapperPropertyMap(Prop.Message)] [AutoWrapperPropertyMap(Prop.IsError)] [AutoWrapperPropertyMap(Prop.Result)] [AutoWrapperPropertyMap(Prop.ResponseException)] [AutoWrapperPropertyMap(Prop.ResponseException_ExceptionMessage)] [AutoWrapperPropertyMap(Prop.ResponseException_Details)] [AutoWrapperPropertyMap(Prop.ResponseException_ReferenceErrorCode)] [AutoWrapperPropertyMap(Prop.ResponseException_ReferenceDocumentLink)] [AutoWrapperPropertyMap(Prop.ResponseException_ValidationErrors)] [AutoWrapperPropertyMap(Prop.ResponseException_ValidationErrors_Field)] [AutoWrapperPropertyMap(Prop.ResponseException_ValidationErrors_Message)]

自定义错误架构

AutoWrapper还提供了一个APIException可用于定义自己的异常的对象,如果想抛出自己的异常消息,则可以简单地执行以下操作

throw new ApiException("Error blah", 400, "511", "http://blah.com/error/511");

默认输出格式如下所示

{   "isError": true,   "responseException": {     "exceptionMessage": "Error blah",     "referenceErrorCode": "511",     "referenceDocumentLink": "http://blah.com/error/511"   } }

当然我们可以自定义错误格式

public class MapResponseObject  {   [AutoWrapperPropertyMap(Prop.ResponseException)]   public object Error { get; set; } } public class Error  {   public string Message { get; set; }   public string Code { get; set; }   public InnerError InnerError { get; set; }   public Error(string message, string code, InnerError inner)   {     this.Message = message;     this.Code = code;     this.InnerError = inner;   } } public class InnerError  {   public string RequestId { get; set; }   public string Date { get; set; }   public InnerError(string reqId, string reqDate)   {     this.RequestId = reqId;     this.Date = reqDate;   } }

然后我们可以通过如下代码进行引发我们错误

throw new ApiException(     new Error("An error blah.", "InvalidRange",    new InnerError("12345678", DateTime.Now.ToShortDateString()) ));

输出格式如下所示

{   "isError": true,   "error": {     "message": "An error blah.",     "code": "InvalidRange",     "innerError": {       "requestId": "12345678",       "date": "10/16/2019"     }   } }

使用自定义API响应格式

如果映射满足不了我们的需求。并且我们需要向API响应模型中添加其他属性,那么我们现在可以自定义自己的格式类,通过设置UseCustomSchema为true来实现,代码如下所示

app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { UseCustomSchema = true });

现在假设我们想在主API中响应中包含一个属性SentDate和Pagination对象,我们可能希望将API响应模型定义为以下格式

public class MyCustomApiResponse  {   public int Code { get; set; }   public string Message { get; set; }   public object Payload { get; set; }   public DateTime SentDate { get; set; }   public Pagination Pagination { get; set; }   public MyCustomApiResponse(DateTime sentDate, object payload = null, string message = "", int statusCode = 200, Pagination pagination = null)   {     this.Code = statusCode;     this.Message = message == string.Empty ? "Success" : message;     this.Payload = payload;     this.SentDate = sentDate;     this.Pagination = pagination;   }   public MyCustomApiResponse(DateTime sentDate, object payload = null, Pagination pagination = null)   {     this.Code = 200;     this.Message = "Success";     this.Payload = payload;     this.SentDate = sentDate;     this.Pagination = pagination;   }   public MyCustomApiResponse(object payload)   {     this.Code = 200;     this.Payload = payload;   } } public class Pagination  {   public int TotalItemsCount { get; set; }   public int PageSize { get; set; }   public int CurrentPage { get; set; }   public int TotalPages { get; set; } }

通过如下代码片段进行测试结果

public async Task<MyCustomApiResponse> Get()  {   var data = await _personManager.GetAllAsync();   return new MyCustomApiResponse(DateTime.UtcNow, data,     new Pagination     {       CurrentPage = 1,       PageSize = 10,       TotalItemsCount = 200,       TotalPages = 20     }); }

运行后会得到如下影响格式

{   "code": 200,   "message": "Success",   "payload": [     {       "id": 1,       "firstName": "Vianne",       "lastName": "Durano",       "dateOfBirth": "2018-11-01T00:00:00"     },     {       "id": 2,       "firstName": "Vynn",       "lastName": "Durano",       "dateOfBirth": "2018-11-01T00:00:00"     },     {       "id": 3,       "firstName": "Mitch",       "lastName": "Durano",       "dateOfBirth": "2018-11-01T00:00:00"     }   ],   "sentDate": "2019-10-17T02:26:32.5242353Z",   "pagination": {     "totalItemsCount": 200,     "pageSize": 10,     "currentPage": 1,     "totalPages": 20   } }

但是从这里要注意一旦我们对API响应进行自定义,那么就代表我们完全控制了要格式化数据的方式,同时丢失了默认API响应的某些选项配置。但是我们仍然可以利用ApiException()方法引发用户定义的错误消息

如下所示

[Route("{id:long}")] [HttpPut] public async Task<MyCustomApiResponse> Put(long id, [FromBody] PersonDTO dto)  {   if (ModelState.IsValid)   {     try     {       var person = _mapper.Map<Person>(dto);       person.ID = id;       if (await _personManager.UpdateAsync(person))         return new MyCustomApiResponse(DateTime.UtcNow, true, "Update successful.");       else         throw new ApiException($"Record with id: {id} does not exist.", 400);     }     catch (Exception ex)     {       _logger.Log(LogLevel.Error, ex, "Error when trying to update with ID:{@ID}", id);       throw;     }   }   else     throw new ApiException(ModelState.AllErrors()); }

现在当进行模型验证时,可以获得默认响应格式

{   "isError": true,   "responseException": {     "exceptionMessage": "Request responded with validation error(s). Please correct the specified validation errors and try again.",     "validationErrors": [       {         "field": "FirstName",         "message": "'First Name' must not be empty."       }     ]   } }

看完了这篇文章,相信你对“ASP.NET Core AutoWrapper自定义响应输出的实现示例”有了一定的了解,如果想了解更多相关知识,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI