Closed aparun22 closed 4 years ago
That's interesting. I'll check on that. For the time being, instead of using UseCustomSchema = true
try to use `IgnoreWrapForOkRequests = true'
app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions {
IgnoreWrapForOkRequests = true,
});
I tested the this scenario and I'm not able to replicate the issue. I'm getting the expected result. Here's my example:
Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions
{
UseCustomSchema = true
});
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Controller Class
namespace AutoWrapper_Test
{
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; }
}
[Route("api/v1/[controller]")]
[ApiController]
public class TestsController : ControllerBase
{
private IEnumerable<PersonResponse> GetMockData()
{
return new List<PersonResponse>
{
new PersonResponse
{
FirstName = "Vince",
LastName = "Durano",
DateOfBirth = Convert.ToDateTime("01/02/1986")
},
new PersonResponse
{
FirstName = "Mitch",
LastName = "Durano",
DateOfBirth = Convert.ToDateTime("01/02/1986")
},
new PersonResponse
{
FirstName = "Vianne",
LastName = "Durano",
DateOfBirth = Convert.ToDateTime("01/02/1986")
},
new PersonResponse
{
FirstName = "Vynn",
LastName = "Durano",
DateOfBirth = Convert.ToDateTime("01/02/1986")
}
};
}
[HttpGet("testcustom")]
public MyCustomApiResponse Get()
{
var data = GetMockData();
return new MyCustomApiResponse(DateTime.UtcNow, data,
new Pagination
{
CurrentPage = 1,
PageSize = 10,
TotalItemsCount = 200,
TotalPages = 20
});
}
}
Here's the result:
GET: https://localhost:44321/api/v1/tests/testcustom
{
"code": 200,
"message": "Success",
"payload": [
{
"id": 0,
"firstName": "Vince",
"lastName": "Durano",
"dateOfBirth": "1986-01-02T00:00:00",
"fullName": "Vince Durano"
},
{
"id": 0,
"firstName": "Mitch",
"lastName": "Durano",
"dateOfBirth": "1986-01-02T00:00:00",
"fullName": "Mitch Durano"
},
{
"id": 0,
"firstName": "Vianne",
"lastName": "Durano",
"dateOfBirth": "1986-01-02T00:00:00",
"fullName": "Vianne Durano"
},
{
"id": 0,
"firstName": "Vynn",
"lastName": "Durano",
"dateOfBirth": "1986-01-02T00:00:00",
"fullName": "Vynn Durano"
}
],
"sentDate": "2020-07-02T18:18:38.4682669Z",
"pagination": {
"totalItemsCount": 200,
"pageSize": 10,
"currentPage": 1,
"totalPages": 20
}
}
I am following same but doesn't work for me. so i have downloaded your source and modified bellow it works as expected am using asp.net core 3.1 API.
My Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { UseCustomSchema = true, ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseCompression();
app.UseResponseCompression();
//app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { UseCustomSchema = true });
app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { UseCustomSchema = true , ReferenceLoopHandling = ReferenceLoopHandling.Ignore});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Novato Api 1.0");
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
My Controller
public NovatoApiResponse Get()
{
var rng = new Random();
var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
return new NovatoApiResponse(DateTime.UtcNow, forecast,
new Pagination
{
CurrentPage = 1,
PageSize = 10,
TotalItemsCount = 200,
TotalPages = 20
});
}
Modified Autowrapper fix the issue for me.
public async Task HandleSuccessfulRequestAsync(HttpContext context, object body, int httpStatusCode)
{
var bodyText = !body.ToString().IsValidJson() ? ConvertToJSONString(body) : body.ToString();
dynamic bodyContent = JsonConvert.DeserializeObject<dynamic>(bodyText);
Type type = bodyContent?.GetType();
string jsonString;
if (type.Equals(typeof(JObject)))
{
ApiResponse apiResponse = new ApiResponse();
if (_options.UseCustomSchema)
{
var formatJson = _options.IgnoreNullValue ? JSONHelper.RemoveEmptyChildren(bodyContent) : bodyContent;
await WriteFormattedResponseToHttpContextAsync(context, httpStatusCode, JsonConvert.SerializeObject(formatJson));
}
**else
{
if (_hasSchemaForMappping && (_propertyMappings.Count == 0 || _propertyMappings == null))
throw new ApiException(ResponseMessage.NoMappingFound);
else
apiResponse = JsonConvert.DeserializeObject<ApiResponse>(bodyText);
if (apiResponse.StatusCode == 0 && apiResponse.Result == null && apiResponse.ResponseException == null)
jsonString = ConvertToJSONString(httpStatusCode, bodyContent, context.Request.Method);
else if ((apiResponse.StatusCode != httpStatusCode || apiResponse.Result != null) ||
(apiResponse.StatusCode == httpStatusCode && apiResponse.Result == null))
{
httpStatusCode = apiResponse.StatusCode; // in case response is not 200 (e.g 201)
jsonString = ConvertToJSONString(GetSucessResponse(apiResponse, context.Request.Method));
}
else
jsonString = ConvertToJSONString(httpStatusCode, bodyContent, context.Request.Method);
}**
}
else
{
var validated = ValidateSingleValueType(bodyContent);
object result = validated.Item1 ? validated.Item2 : bodyContent;
jsonString = ConvertToJSONString(httpStatusCode, result, context.Request.Method);
**await WriteFormattedResponseToHttpContextAsync(context, httpStatusCode, jsonString);**
}
}
Thanks, Arun.
Your change makes sense to me. I should fix that in future release.
However, I noticed that you call the AutoWrapper
middleware after UseRouting
. You should call it before that:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Novato Api 1.0");
});
app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions
{
UseCustomSchema = true
});
app.UseRouting();
app.UseCompression();
app.UseResponseCompression();
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Thanks for your advise, I will make necessary changes. BTW great work it saved my time 💯 cheers keep rocking 👍
Hi Team,
I am trying to use Custom Response class based on your suggestion it doesn't work as expected i follow your code as below
in Startup.cs app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { UseCustomSchema = true });
my controller [HttpGet] public NovatoApiResponse Get() { var rng = new Random(); var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray();
Api returns me my custom response together with default response as bellow.
{"code":200,"message":"Success","payload":[{"date":"2020-07-03T15:18:21.1216077+08:00","temperatureC":40,"temperatureF":103,"summary":"Cool"},{"date":"2020-07-04T15:18:21.1223563+08:00","temperatureC":-18,"temperatureF":0,"summary":"Scorching"},{"date":"2020-07-05T15:18:21.1223597+08:00","temperatureC":-14,"temperatureF":7,"summary":"Balmy"},{"date":"2020-07-06T15:18:21.1223599+08:00","temperatureC":5,"temperatureF":40,"summary":"Hot"},{"date":"2020-07-07T15:18:21.1223602+08:00","temperatureC":42,"temperatureF":107,"summary":"Warm"}],"sentDate":"2020-07-02T07:18:21.1223606Z","pagination":{"totalItemsCount":200,"pageSize":10,"currentPage":1,"totalPages":20}} { "message": "GET Request successful.", "result": { "code": 200, "message": "Success", "payload": [ { "date": "2020-07-03T15:18:21.1216077+08:00", "temperatureC": 40, "temperatureF": 103, "summary": "Cool" }, { "date": "2020-07-04T15:18:21.1223563+08:00", "temperatureC": -18, "temperatureF": 0, "summary": "Scorching" }, { "date": "2020-07-05T15:18:21.1223597+08:00", "temperatureC": -14, "temperatureF": 7, "summary": "Balmy" }, { "date": "2020-07-06T15:18:21.1223599+08:00", "temperatureC": 5, "temperatureF": 40, "summary": "Hot" }, { "date": "2020-07-07T15:18:21.1223602+08:00", "temperatureC": 42, "temperatureF": 107, "summary": "Warm" } ], "sentDate": "2020-07-02T07:18:21.1223606Z", "pagination": { "totalItemsCount": 200, "pageSize": 10, "currentPage": 1, "totalPages": 20 } } }
Thanks, Arun.