Giter Club home page Giter Club logo

autowrapper's Introduction

Hi there ๐Ÿ‘‹

I'm Vince and I work as a Solutions Architect. Iโ€™m very passionate about learning new technologies and ideas, I enjoy tackling challenges and sharing what I learned in the technical community through writing articles, books and answering to forums. I have over 18 years of software engineering experience - years of making mistakes and learning from them. 11-time Microsoft MVP, 5-time C# Corner MVP, CodeProject MVP, MVA, MVA, OSS Contributor, Microsoft Influencer, DZone MVB and a regular contributor at various online technical communities.

Microsoft MVP | CodeProject MVP | CodeProject MVA | CodeProject MVE | CsharpCorner MVP

  • ๐Ÿ“ I write technical articles related to ASP.NET CORE, .NET 5 and Azure on my blog. Feel free to subscribe and get the latest posts delivered right to your inbox!
  • ๐Ÿ”ญ Iโ€™m currently working on a new open-source project template for ASP.NET Core APIs. Stay tuned!
  • ๐Ÿ“˜ The recent book that I coauthored is out. Check it out here: ASP.NET Core 5 for Beginners.
  • โ˜๏ธ Iโ€™m currently learning Azure and Cloud stuff.
  • ๐Ÿฆ Follow me on twitter @vmsdurano
  • ๐Ÿ”— Let's connect on linkedin
  • ๐Ÿซ I'm an All-Star member at Microsoft ASP.NET forums (100k+ rep), Legend member at CodeProject (72k+ rep) and Platinum member at C# Corner (15k+ rep)

๐Ÿ“š Books written:

autowrapper's People

Contributors

arhen avatar boyko-ant avatar chen1tian avatar cuneytdogru avatar dependabot[bot] avatar hueifeng avatar nick-cromwell avatar proudmonkey avatar sawankumarbundelkhandi avatar swissarmytech avatar wylanosorio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

autowrapper's Issues

Custom Formats for API Response

Hi Vincent,

Is it possible to return the response in the format as shown in your article? We have our api written in asp.net core 2.2 with the approach shown in your article. Now we are upgrading our api to asp.net core 3.1 and the code shown in the above link fails for asp.net core 3.1 api. The response gets clipped with this approach.

But now If I use AutoWrapper, then response contracts are different and since our API is already in production, we cannot change the response contract. Is it possible to achieve the same response contract here with AutoWrapper?

Old Response as per your article:

{  
    "Version": "1.0.0.0",  
    "StatusCode": 200,  
    "Message": "Request successful.",  
    "Result": [  
        "value1",  
        "value2"  
    ]  
}    

New AutoWrapper Response:

{
    "message": "Request successful.",
    "isError": false,
    "result": [
        {
            "date": "2019-09-16T23:37:51.5544349-05:00",
            "temperatureC": 21,
            "temperatureF": 69,
            "summary": "Mild"
        },
        {
            "date": "2019-09-17T23:37:51.554466-05:00",
            "temperatureC": 28,
            "temperatureF": 82,
            "summary": "Cool"
        },
        {
            "date": "2019-09-18T23:37:51.554467-05:00",
            "temperatureC": 21,
            "temperatureF": 69,
            "summary": "Sweltering"
        },
        {
            "date": "2019-09-19T23:37:51.5544676-05:00",
            "temperatureC": 53,
            "temperatureF": 127,
            "summary": "Chilly"
        },
        {
            "date": "2019-09-20T23:37:51.5544681-05:00",
            "temperatureC": 22,
            "temperatureF": 71,
            "summary": "Bracing"
        }
    ]
}

I find two issues here,

  1. StatusCode Property is missing in AutoWrapper Response.
  2. Properties names are camel casing in AutoWrapper and its pascal casing previously

Can this change be done globally? Please can you assist me further on this?

Thanks.
Abdul Rahman

Question

Hi,
first of all thank you for nice package.
I am using it but one thing noted, if api method not found any record or update I am sending status code accordingly, but my client side code always receive 200 OK status.
mean api method throw exception or if I try to intentionally send 404 I always receive 200 status.
more
I try to find record in db using ef core suppose there is no record in db and I am sending this
return new APIResponse(StatusCodes.Status404NotFound, "Error", response);
but actual browser shows me status 200 OK in http response.

here is screenshot for your package response

image

and here actual header response
image

Possible Enhancement for ignored paths

Thanks for fixing the isApiOnly.

So under my crazy setup of a WebAPI, Swagger, AutoMapper, AutoWrapper I also at times wanted to return straight up images. So I needed a way to skip this for some paths so they did not get wrapped (like the swagger I guess). I am not sure if I will keep this. I may see about having something else serve the images because this may not be worth the extra string compare on each call. I just needed this working for now so thought it as a possible option.

This is what I did:

Added Option:

///


/// Set the Api start paths to be ignored. The default value is null;
///

public List IgnoreWhenPathStarts { get; set; } = null;

Added the Method to check the path:

public bool IsIgnorePath(HttpContext context)
{
if (_options.IgnoreWhenPathStarts == null)
return false;

        foreach (string pathStart in _options.IgnoreWhenPathStarts)
        {
            if (context.Request.Path.StartsWithSegments(new PathString(pathStart)))
                return true;
        }

        return false;
    }

}

Check for the Ignore:

if (awm.IsIgnorePath(context) || awm.IsSwagger(context) || !awm.IsApi(context))
await _next(context);

How to show the result value type in swagger?

Hi,

I wish to show the result type schema in swagger ui. I am returning the ApiResponse type in the controller. I am not sure how to achieve this. Can someone from the team please guide me?

Thanks.

Int gets automatically converted to string

I am using AutoWrapper 3.0. This is the Api Function i call:

[HttpGet("loadInt")]
public int LoadInt(int schiffnr)
{
       return 13;
 }

This is the configuration I made:

 app.UseApiResponseAndExceptionWrapper<WrapperPM>(new AutoWrapperOptions { UseCamelCaseNamingStrategy = false });`

This is my custom response class:

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

        [AutoWrapperPropertyMap(Prop.Message)]
        public string ErrorMessage { get; set; }

        [AutoWrapperPropertyMap(Prop.ResponseException)]
        public CustomError Error { get; set; }

        [AutoWrapperPropertyMap(Prop.IsError)]
        public bool hasError { get; set; }
}

I expect the Data attribute to be int, but it is string.

{"$id":"1052","Data": "111","ErrorMessage":null,"Error":null,"hasError":false}

Bug in Download Response headers

[HttpPost]
[AutoWrapIgnore]
public async Task< FileStreamResult> GetExcel()
{
var filePath = "xxx..xlsx";
var file = System.IO.File.OpenRead(filePath);
var provider = new FileExtensionContentTypeProvider();
var fileInfo = new System.IO.FileInfo(filePath);
var memi = provider.Mappings[fileInfo.Extension];
return File(file, memi, fileInfo.Name);
}
Bug:
content-type: application/json
{978E9BF7-6A16-49EE-938F-0BB2E03FEDA6}_20200601115104

Right:
content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

new ApiException("Test", 404) always returning 500

Hello,

First of all, thanks for AutoWrapper, it's a joy and breeze to use.

In my new .NET Core Web API app, I want to throw an exception if an object wasn't found in the database, for example. But in my controller, when I do:

throw new ApiException("test", 404);

I receive:

{
    "isError": true,
    "type": "https://httpstatuses.com/500",
    "title": "Internal Server Error",
    "status": 500,
    "detail": "test",
    "instance": "/api/v1.0/notifications",
    "extensions": {},
    "errors": {
        "message": "test",
        "type": "ApiException",
        "source": "PM.Core.API",
        "raw": "<snip>"
    }
}

My result has a status code of 500 when I was expecting it to be a 404. Here is the configuration definition in Startup.cs:

            app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions
                                                  {
                                                      EnableExceptionLogging = true,
                                                      IsDebug = env.IsDevelopment()                       || Debugger.IsAttached,
                                                      UseApiProblemDetailsException = env.IsDevelopment() || Debugger.IsAttached,
                                                      ShowApiVersion = true,
                                                      ShowStatusCode = true,
                                                      LogRequestDataOnException = true,
                                                      EnableResponseLogging = true,
                                                      ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
                                                      ApiVersion = "1.0"
                                                  });

What am I missing or what did I do wrong? Thanks much in advance!

JSON with HTML characters issue

Out of the box any circular reference results in a 'nested' response:

image

I've modified the code to support passing an option for Newtonsofts ReferenceLoopHandling, however this doesn't fix the problem. (I'll submit a PR, once we're able to resolve this).

All of my other controllers and methods work just fine, but none of them have a potential loop.

Here's my API Method that's problematic:
image

Here's one that works:
image

The only real difference is the data source.

App is a Blazor App with MVC API Support
.NET Core 3.1

Latest version drastically reduce the response time

The response time is too slow when I upgraded the to the latest version. You can consider it like 10 times slower. I have reverted to version 2.1 and performance is normal.
I implemented in the .net Core 3.1.

Parser Error with special characters

Hi,

If the response contains special characters like รฉ รบ รฑ, etc, returns a bad JSON response.

Bad Response example:
SyntaxError: JSON.parse: end of data after property value in object at line 1 column 61 of the JSON data
{"statusCode":200,"isError":false,"result":"Jaime Sepรบlveda"

Error when action return FileResult

In a Controller, I have an action that returns the type FileResult. Even adding the [AutoWrapIgnore] tag to the action is returning the error below:

System.ObjectDisposedException: Cannot access a closed Stream. at System.IO.MemoryStream.Seek(Int64 offset, SeekOrigin loc) at AutoWrapper.Base.WrapperBase.InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm) at AutoWrapper.AutoWrapperMiddleware.InvokeAsync(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT1.ProcessRequestAsync()`

image

Any suggestion?

Showing CreatedAtAction IActionResult as ErrorResponse

Used ActionResult Status

CreatedAtAction(nameof(GetById), new { id = result.Id }, result);

Response From AutoWrapper

{
"statusCode": 201,
"isError": true,
"responseException": {
"exceptionMessage": "{"id":24,"countryCode":"BHUtyhfsdg","countryName":"Bhutan","countryDescription":"Bhutan","cultureName":2}"
}
}

Bug in WrapperBase/InvokeAsyncBase for StatusCode 304 or 204

Line 55:

image

Should actually be:

image

Otherwise that check is always false when status is 304 or 204. Although you will ultimately still get a 304 or a 204 response, the server throws an exception:

image

I'm seeing this particularly with OPTIONS requests.

Using System.Text.Json instead

As System.Text.Json had been instroduced from .Net Core 3.0. May I submit an request to migrate Json serialization from Newtonsoft.Json to System.Text.Json

when PUT and receive 204 NoContent AutoWrapper will intercepted an Unhandle error.

After sending a PUT request, when the server receive 204 NoContent it will intercepted an error

Put Action in ProductController.cs:

[HttpPut("{productId}")]
        public async Task<IActionResult> UpdateProduct(Guid productId, [FromBody]ProductUpdateDTO productUpdateDTO)
        {
            if (productUpdateDTO == null)
            {
                return BadRequest();
            }

            if (!ModelState.IsValid)
            {
                return new UnprocessableEntityObjectResult(ModelState); // larsson๏ผšๅฆ‚ๆžœ่ฆ่‡ชๅฎšไน‰422ไน‹ๅค–็š„ๅ“ๅบ”ๅˆ™้œ€่ฆๆ–ฐๅปบไธ€ไธช็ฑป็ปงๆ‰ฟUnprocessableEntityObjectResult
            }

            var result = await _repository.TryGetProduct(productId);
            if (!result.hasProduct)
            {
                return NotFound();
            }

            _mapper.Map(productUpdateDTO, result.product);
            _repository.UpdateProduct(result.product);

            if (!await _unitOfWork.SaveAsync())
            {
                return StatusCode(500, "Updating product field.");
            }

            return NoContent();
        }

startup.cs:

...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { ShowStatusCode = true });

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
...

error:

fail: AutoWrapper.AutoWrapperMiddleware[0]
      [500]: Unhandled Exception occurred. Unable to process the request.
System.InvalidOperationException: Writing to the response body is invalid for responses with status code 204.
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowWritingToResponseBodyNotSupported()
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Advance(Int32 bytes)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponsePipeWriter.Advance(Int32 bytes)
   at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.Write(HttpResponse response, String text, Encoding encoding)
   at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, String text, Encoding encoding, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, String text, CancellationToken cancellationToken)
   at AutoWrapper.AutoWrapperMembers.WriteFormattedResponseToHttpContext(HttpContext context, Int32 code, String jsonString, Boolean isError)
   at AutoWrapper.AutoWrapperMembers.HandleNotSuccessRequestAsync(HttpContext context, Object body, Int32 code)
   at AutoWrapper.Base.WrapperBase.InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)
info: AutoWrapper.AutoWrapperMiddleware[0]
      Source:[::1] Request: PUT http localhost:5000/product/c632690e-1784-45b9-9e98-69ad427575c3  {
        "name":"aaaaa",
        "description":"bbb.",
        "isonsale":false,
        "createtime":"2020-2-17"
} Responded with [204] in 157ms
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HLTJBD08K61J", Request id "0HLTJBD08K61J:00000002": An unhandled exception was thrown by the application.
System.InvalidOperationException: StatusCode cannot be set because the response has already started.
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowResponseAlreadyStartedException(String value)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.set_StatusCode(Int32 value)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode(Int32 value)
   at Microsoft.AspNetCore.Http.DefaultHttpResponse.set_StatusCode(Int32 value)
   at AutoWrapper.AutoWrapperMembers.WriteFormattedResponseToHttpContext(HttpContext context, Int32 code, String jsonString, Boolean isError)
   at AutoWrapper.AutoWrapperMembers.HandleExceptionAsync(HttpContext context, Exception exception)
   at AutoWrapper.Base.WrapperBase.InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)
   at AutoWrapper.AutoWrapperMiddleware.InvokeAsync(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

core using Microsoft.AspNetCore.ResponseCompression is invalid

My service compresses results and I am trying to use autowrapper, but it wraps after the compression, so results look like:

{"message":"GET Request successful.","isError":false,"result":" \u0001\u0000 tM B

you can see the results are compressed, but it should be the entire json message. How can I move autowrapper to run before compression?

Thanks,
Greg

the problem of exceptionMessage To JSON

when i use autowrapper , i will get a json result just like this:

{
"statusCode": 422,
"isError": true,
"responseException": {
"exceptionMessage": "{"Username":["username is needed."]}"
}
}

if not use autowrapper, it is :

{
"username": [
"username is needed."
]
}

and this๏ผš

{
"statusCode": 400,
"isError": true,
"responseException": {
"exceptionMessage": "{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1\",\"title\":\"Bad Request","status":400,"traceId":"|12b5128e-441a91a7c1e0b449."}"
}
}

if not use autowrapper ๏ผˆProblemDetail entity๏ผ‰:

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Bad Request",
"status": 400,
"traceId": "|2fc8416d-4f4fdb099ade0681."
}

how can i fixed the value of "exceptionMessage" to JSON ?
Or will autowrapper adapt the verification results returned by "ProblemDetial" and FluentValidation in the future?

Swagger not working after installing AutoWrapper.

Hi,

Great Job! you deserve all respect in the world.

This is what I've got after installing AutoWrapper:

**Unable to render this definition
The provided definition does not specify a valid version field.

Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: "2.0" and those that match openapi: 3.0.n (for example, openapi: 3.0.0).**

I'm using the latest version of Swashbuckle.AspNetCore

Waiting your response please...

IsApiOnly not working for Blazor app

Hello,

This is breaking our Blazor WebAssembly app.
It now comes up with the message to set the flag. I did that but it didn't help.

I modified Startup.cs of my server with:
app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { IsApiOnly = false });

Is there something else I should do?

BTW, when you mention the flag in the readme it would be very helpful to provide context such as what method in what file needs to be modified.

I hope we can get an answer quickly so we can continue using this.

How to turn off default logging for autowrapper?

How do I turn off this Logging information ?
Can we change log level to Trace for auto wrapper?

_logger.Log(LogLevel.Information, $@"Request: {request} Responded with [{context.Response.StatusCode}] in {stopWatch.ElapsedMilliseconds}ms");

There are some instances where we would like to log information, but with autowrapper this puts logging for all single requests which becomes so noisy..

ApiException Example using ModelState Validation is not completed

in the docs, you had given example how to throw exception using ApiException using ModelState validation errors. But based on this post, since NetCore version 2, "[ApiController] attribute will automatically responding with a 400 when validation errors occur". So on your example, this kind of response is never happen.

{
    "isError": true,
    "responseException": {
        "exceptionMessage": "Request responded with validation error(s). Please correct the specified validation errors and try again.",
        "validationErrors": [
            {
                "field": "Name",
                "message": "The Name field is required."
            }
        ]
    }
}

It is because this validation checking will never happened,

if (ModelState.IsValid)
    {
        //Call a method to add a new record to the database
        try
        {
            var result = await SampleData.AddNew(band);
            return new ApiResponse("New record has been created to the database", result, 201);
        }
        catch (Exception ex)
        {
            //TO DO: Log ex
            throw;
        }
    }
    else
        throw new ApiException(ModelState.AllErrors());

The solution is, you must explain more about this state and pointing out to disable automatic model state validation. And the better approach to disable the default behavior by setting SuppressModelStateInvalidFilter option to true. You can set this option to true in the ConfigureServices method. Like,

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ApiBehaviorOptions>(options =>
    {
        options.SuppressModelStateInvalidFilter = true;
    });
}

After adding that option, model state validation will work on Controller.

Blazor Client

It would be nice to define a generic response class that a blazor client could use, to deserialise a wrapped response.

Some sort of WrappedApiResponse<T> that has the consistent properties as well as the Result (of type T).

Usage would be.. the blazor client application would use HttpClient to send a request to the api, and get back a response. It could then deserialise the response body to WrappedResponse<T>.

ApiResponse doesn't return HTTP statusCode

The issue is the title. The response header is missing a valid HTTP status code. Only occurred with ApiResponse

The example code:

public ApiResponse Register([FromBody] RegisterViewModel model)
{
    return new ApiResponse("Test", model);
}

The logs from docker-compose:

api_1       | info: AutoWrapper.AutoWrapperMiddleware[0]
api_1       |       Request: POST http localhost:5000/api/auth/register  {"full_name":"Hello","username":"sample","email":"[email protected]","password":"hello@123"} Responded with [0] in 21ms

In the above output you can see the statusCode responded is [0]

Tested on both v1.0 - 2.1.0 with the same results.

Here is my csproj file in case it's needed:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <RootNamespace>ltmart_api_core</RootNamespace>
    <UserSecretsId>31ef5065-3068-4c82-a978-cab1a5f14bd3</UserSecretsId>
    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
    <DockerfileContext>.</DockerfileContext>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
    <PackageReference Include="AutoWrapper.Core" Version="2.1.0" />
    <PackageReference Include="Hangfire.AspNetCore" Version="1.7.7" />
    <PackageReference Include="Hangfire.Postgresql" Version="1.6.3" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="4.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.9.5" />
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.0.1" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
  </ItemGroup>

</Project>

Ignore Atrribute

Hi, your package is very useful. Can i suggest to add an IgnoreAction attribute for the actions ?

Thanks in advance
Stefano

When EnableResponseLogging option enabled, multipart/form-data requests with files dumps binary data in console

When submitting request data using multipart/form-data, the automatic logging feature dumps the entire binary contents of the files being uploaded into the logger/console. I tried using AutoWrapIgnore attribute and the logging still persists. I would love if logging was disabled when AutoWrapIgnore attribute is being used on a controller method or possibly adding another attribute that disables logging for specific controller method. This would also be useful when trying to hide requests with sensitive information (ex: authentication endpoints with passwords) from the logger.

HTML Content in a string property with IsApiOnly

I have a ViewModel that contains some HTLM in a string property. I tried setting BypassHTMLValidation=true with keeping IsApiOnly=true because it is a WebAPI only.

This resulted in me losing the outer Wrapper that I wanted AutoWrapper for. I made the below adjustment to get the wrapper back.

Line 65 of WrapperBase.cs I suggest maybe something like:
&& !_options.BypassHTMLValidation && bodyAsText.IsHtml()

This fixed my problem.

What do you think?

Every requests frombody parameter became empty

Hi,

I found an edge case when your middleware causing a weird problem.
In my .net core 3.1 application I tried to create HttpClient from WebApplicationFactory because I wanted to write an integration test for a POST request.
The problem is that this request is containing a (FromBody) parameter, which could not be found after I was registered your middleware btw I'm using a second middleware. Actually I don't really know what is the root cause of the issue but I found the solution.
Can you please change the following code in the AutoWrapperMembers.FormatRequest method?
from

var buffer = new byte[Convert.ToInt32(request.ContentLength)];
await request.Body.ReadAsync(buffer, 0, buffer.Length);
var bodyAsText = Encoding.UTF8.GetString(buffer);
request.Body.Seek(0, SeekOrigin.Begin);

to

request.Body.Seek(0, SeekOrigin.Begin);
request.Body.CopyToAsync(stream);
bodyAsText = Encoding.UTF8.GetString(stream.ToArray());
request.Body.Seek(0, SeekOrigin.Begin);

Because it looks like that the request.Body.ReadAsync closes the request body stream anyway, even if you executing the request.Body.Seek().

Best regard,
Attila

APIResponse produces invalid JSON.

Hey,

I've installed this package to a .net core web API project and tried to call the APIs from an angular app there was a problem with parsing the returned JSON, but when calling the same API from postman the response was a valid JSON.
after debugging and troubleshooting the problem, I've figured out what has caused it, simply the response content-length header always remains the same length of the original body length even after the HandleSuccessRequestAsync update the body, and the browser takes only the same number of characters that match the value of the content-length header from the returned body and tries to parse it which causes the problem.

I've just added the below line in finally scope to fix it:
context.Response.ContentLength = memoryStream.Length;

Fluent Model Validation result

I am trying to implement a generic model validation filter attribute
here is code sample
using AutoWrapper.Wrappers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using XERide.Core;

namespace XERide.API.Filters
{
public class ModelValidationFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!filterContext.ModelState.IsValid)
{
if (filterContext.HttpContext.Request.Method == "GET")
{
var result = new BadRequestResult();
filterContext.Result = result;
}
else
{
//throw new ApiProblemDetailsException(filterContext.ModelState);
var result = new ContentResult();
string content = Helpers.JsonSerialize(new ApiError(filterContext.ModelState));
result.Content = content;
result.ContentType = "application/json";
filterContext.HttpContext.Response.StatusCode = 400;
filterContext.Result = result;
}
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}
}
}
if use ApiProblemDetailsException in filter it is not working. even in controller
without ApiProblemDetailsException this is the response which is valid response I am expecting.
I am using .net core 3.1 and with AutoWrapper 4 version.
could please help me how to use that generic model filter validation

image

Receiving OPTIONS ERROR during POST

Hello, i am receiving an error during a post, it seems to happen during the options call:

Unhandled Exception occurred. Unable to process the request.
System.InvalidOperationException: Writing to the response body is invalid for responses with status code 204.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowWritingToResponseBodyNotSupported()

Full stack trace:

2019-11-20 11:19:00,608 [59] INFO  Microsoft.AspNetCore.Hosting.Internal.WebHost - Request finished in 37.78ms 204 application/json
2019-11-20 11:19:00,632 [48] INFO  Microsoft.AspNetCore.Hosting.Internal.WebHost - Request starting HTTP/1.1 OPTIONS http://localhost/Elicio_Api/api/Project/list/  
2019-11-20 11:19:00,642 [48] INFO  Microsoft.AspNetCore.Cors.Infrastructure.CorsService - Policy execution successful.
2019-11-20 11:19:00,648 [48] ERROR AutoWrapper.AutoWrapperMiddleware - [500]: Unhandled Exception occurred. Unable to process the request.
System.InvalidOperationException: Writing to the response body is invalid for responses with status code 204.
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowWritingToResponseBodyNotSupported()
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.WriteAsync(ReadOnlyMemory`1 data, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, String text, Encoding encoding, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, String text, CancellationToken cancellationToken)
   at AutoWrapper.AutoWrapperMembers.WriteFormattedResponseToHttpContext(HttpContext context, Int32 code, String jsonString, Boolean isError)
   at AutoWrapper.AutoWrapperMembers.HandleNotSuccessRequestAsync(HttpContext context, Object body, Int32 code)
   at AutoWrapper.Base.WrapperBase.InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)
2019-11-20 11:19:00,654 [48] INFO  AutoWrapper.AutoWrapperMiddleware - Request: OPTIONS http localhost/api/Project/list/   Responded with [204] in 11ms
2019-11-20 11:19:00,660 [48] ERROR Microsoft.AspNetCore.Server.Kestrel - Connection id "0HLRDJUQ2J50D", Request id "0HLRDJUQ2J50D:00000001": An unhandled exception was thrown by the application.
System.InvalidOperationException: StatusCode cannot be set because the response has already started.
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowResponseAlreadyStartedException(String value)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.set_StatusCode(Int32 value)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode(Int32 value)
   at Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.set_StatusCode(Int32 value)
   at AutoWrapper.AutoWrapperMembers.WriteFormattedResponseToHttpContext(HttpContext context, Int32 code, String jsonString, Boolean isError)
   at AutoWrapper.AutoWrapperMembers.HandleExceptionAsync(HttpContext context, Exception exception)
   at AutoWrapper.Base.WrapperBase.InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)
   at AutoWrapper.AutoWrapperMiddleware.InvokeAsync(HttpContext context)
   at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Builder.Extensions.UsePathBaseMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
2019-11-20 11:19:00,665 [48] INFO  Microsoft.AspNetCore.Hosting.Internal.WebHost - Request finished in 34.248ms 204 application/json

I have managed to get around it by adding the following in de middleware class in the function: InvokeAsync

 else if (context.Response.StatusCode == 204) { }

Regards

Potential improvements to HandleSuccessRequestAsync

The HandleSuccessRequestAsync method will attempt to perform a check for valid json, convert to JSON string and then serialize to JSON, the response from a call. This happens even if the content being served is HTML. This is highly inefficient and there is probably a much better way to ignore the JSON deserialization when the code discovers the content is not JSON.

image

ApiResponse with statusCode 4XX not setting isError: true

In my opinion I've found a major inconsistency. If I return an ApiResponse from a controller in the following way:

return new ApiResponse($"Must provide a tenantId or domain query string parameter", statusCode: StatusCodes.Status400BadRequest);

This is the response I receive:

{
    "statusCode": 400,
    "message": "Must provide a tenantId or domain query string parameter",
    "isError": false
}

But if an API Version is not specified in the header for that same request, this is the response I receive:

{
    "statusCode": 400,
    "isError": true,
    "error": {
        "exceptionMessage": {
            "error": {
                "code": "ApiVersionUnspecified",
                "message": "An API version is required, but was not specified.",
                "innerError": null
            }
        }
    }
}

I would expect isError to be true regardless if an exception is throw, an ApiException is thrown with a 4XX, or an ApiResponse is returned with a 4XX. Is there are reason for not doing so?

I could throw an ApiException in the controller with a 4XX status code but that spams my logs:
image

Quick response to the client

Thanks for your greate work.

Some times I like to response with a message "quickly", e.g.

`

        return Unauthorized("Access code error");

        return NotFound(new {  msg1="file abc.txt is gone", fileName2="efg"});

        return BadRequest("User name is null");

`

How can I get the message on the client?
I found the code in WrapperBase.cs Line 66 handle not success request. The bodyAsText has been igored. How about to keep the message and set to property(Message) of ApiResponse in ApiResponse.cs?
Thank you.

Exception: StatusCode cannot be set because the response has already started

Creating a new Web App with API and Angular with Visual Studio 2019 and .NET Core 3.0, then adding the app.UseApiResponseAndExceptionWrapper(); to the Configure method, will result in many exceptions like this:

"System.InvalidOperationException: StatusCode cannot be set because the response has already started."

image

When using with gRPC, will make the gPRC call response with 'null'

[Scenario]
I've implement the API that will have REST + gRPC

[The problem]

  • This package will transfer the gRPC result and the client will not receive the correct model, then the client will got response with null

[Troubleshooting]

  • I remove this package and make the API with purely gRPC instead

P.S.
Thanks for your package made my REST Easy and look great

BypassHTMLValidationEnsure amendment

  1. BypassHTMLValidation is not available in current release version on nuget
  2. Add BypassHTMLValidationEnsure to ApiOnly only condition to ensure HTML within the payload for ApiOnly is also permitted if BypassHTMLValidation is set to true.

if (!context.Request.Path.StartsWithSegments(new PathString(_options.WrapWhenApiPathStartsWith)) && bodyAsText.IsHtml() && context.Response.StatusCode == Status200OK)

if (!context.Request.Path.StartsWithSegments(new PathString(_options.WrapWhenApiPathStartsWith)) && (!_options.BypassHTMLValidation && bodyAsText.IsHtml()) && context.Response.StatusCode == Status200OK)

AutoWrapIgnore didn't work for Return File

Hi, one of my API endpoint is serving for generate pdf. inside it's action, there couple of logic to build a PDF then return it as file view at browser with return File(file, "application/pdf");

Default when AutoWrapper activated, it's generate the file as json so the output seems like this broken. I've tried to add AutoWrapIgnore but it still didnt work.

Schema for ApiResponse

How much research on existing industry wide APIs and how they handle and return errors was done?

"responseException" doesn't really ring well in my head and can't remember seeing anyone else having the error like that.

Here are some results from some quick resource on the topic:

Microsoft Graph:

{
  "error": {
    "code": "invalidRange",
    "message": "Uploaded fragment overlaps with existing data.",
    "innerError": {
      "requestId": "request-id",
      "date": "date-time"
    }
  }
}

Salesforce example on StackExchange

public class ResponseWrapper{
    public list<Account> lstaccounts;
    public boolean isError ;
    public string errorCode;
    public integer statusCode;
       public ResponseWrapper(){
         lstaccounts = new list<Account>();
         isError= false;
    }
}

From an article on the topic:

image

How I design JSON API responses

{
    "status": "ok",
    "code": 200,
    "messages": [],
    "result": {
        "user": {
            "id": 123,
            "name": "shazow"
        }
    }
}

RESTful API Design Tips from Experience

This article uses texts for codes, such as: "EMAIL_ALREADY_EXISTS" and "FIELDS_VALIDATION_ERROR". This is a bit weird, if one really wants to copy the HTTP status codes (to make the response independent of HTTP protocol).

418: I'M A TEAPOT, AND OTHER BAD API RESPONSES - RESTFUL API DESIGN

This one argues against wrappers, but I'm leaning towards them due to a multitude of reasons.

RESTful API Design. Best Practices in a Nutshell.

// 400 Bad Request
{
  "errors": [
    {
      "status": 400,
      "detail": "Invalid state. Valid values are 'internal' or 'external'",
      "code": 352,
      "links": {
        "about": "http://www.domain.com/rest/errorcode/352"
      }
    }
  ]
}

AutoWrapper fails on OPTIONS request.

I am using AutoWrapper in .net core 3.0 API Project. I found an issue regarding pre-flight requests. When ever a pre-flight request (OPTIONS method) is sent from font-end ( Angular 8 in my case), the AutoWrapper fails with exception
AutoWrapper.AutoWrapperMiddleware[0] [500]: Unhandled Exception occurred. Unable to process the request. System.InvalidOperationException: Writing to the response body is invalid for responses with status code 204. at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowWritingToResponseBodyNotSupported() at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Advance(Int32 bytes) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponsePipeWriter.Advance(Int32 bytes) at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.Write(HttpResponse response, String text, Encoding encoding) at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, String text, Encoding encoding, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, String text, CancellationToken cancellationToken) at AutoWrapper.AutoWrapperMembers.WriteFormattedResponseToHttpContext(HttpContext context, Int32 code, String jsonString, Boolean isError) at AutoWrapper.AutoWrapperMembers.HandleNotSuccessRequestAsync(HttpContext context, Object body, Int32 code) at AutoWrapper.Base.WrapperBase.InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)

While I was investigating, I found that the OPTIONS requests are usually responded with Stauts204NoContent response and writing to response body is not allowed for responses with 204 status code, but AutoWrapper somehow tries to add response body which throws this exception.
Am I missing some configuration?

Regards

Ready for production

Hi, Thank you for such great Wrapper really like it.
I am currently using VMD.RESTApiResponseWrapper.Core package
is different than VMD.RESTApiResponseWrapper.Core?
and one thing more is it ready for production?
When are you planning final release?

Package AutoWrapper.Core 1.1.0 is not compatible with netcoreapp2.2 (.NETCoreApp,Version=v2.2). Package AutoWrapper.Core 1.1.0 supports: netcoreapp3.0 (.NETCoreApp,Version=v3.0)

error: Package AutoWrapper.Core 1.1.0 is not compatible with netcoreapp2.2 (.NETCoreApp,Version=v2.2). Package AutoWrapper.Core 1.1.0 supports: netcoreapp3.0 (.NETCoreApp,Version=v3.0) error: Package 'AutoWrapper.Core' is incompatible with 'all' frameworks in project 'xxx.csproj.

Should target dotnet core 2 unless it's completely incompatible.

Using Your Own API Response Schema Response Error

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();

        return new NovatoApiResponse(DateTime.UtcNow, forecast,
    new Pagination
    {
        CurrentPage = 1,
        PageSize = 10,
        TotalItemsCount = 200,
        TotalPages = 20
    });

    }

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.

can not catch the 500 errors.

part of the .proj:

...
<ItemGroup> <PackageReference Include="AutoMapper" Version="9.0.0" /> **<PackageReference Include="autowrapper.core" Version="3.0.0" />** <PackageReference Include="FluentValidation" Version="8.6.1" /> <PackageReference Include="FluentValidation.AspNetCore" Version="8.6.1" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.1" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.6.0" /> </ItemGroup> <PropertyGroup> **<TargetFramework>netcoreapp3.1</TargetFramework>** </PropertyGroup>

...

part of the startup.cs:

...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseApiResponseAndExceptionWrapper(new AutoWrapperOptions { ShowStatusCode = true });
...

the stack:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.FormatException: Input string was not in a correct format.
at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type)
at System.Number.ParseInt32(ReadOnlySpan1 value, NumberStyles styles, NumberFormatInfo info) at System.Convert.ToInt32(String value) at RESTfulAPISample.Api.Controller.ProductController.GetById(Guid id) in /Users/larsson/Documents/working/proj/_netcore/RESTfulAPISample/RESTfulAPISample.Api/Controllers/ProductController.cs:line 156 at lambda_method(Closure , Object ) at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult() at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Marvin.Cache.Headers.HttpCacheHeadersMiddleware.HandleResponse(HttpContext httpContext)
at Marvin.Cache.Headers.HttpCacheHeadersMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[3]
An exception was thrown attempting to display the error page.
System.ObjectDisposedException: Cannot access a closed Stream.
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.MemoryStream.WriteAsync(ReadOnlyMemory1 buffer, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(CancellationToken cancellationToken) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) fail: AutoWrapper.AutoWrapperMiddleware[0] [500]: Unhandled Exception occurred. Unable to process the request. System.FormatException: **Input string was not in a correct format**. at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type) at System.Number.ParseInt32(ReadOnlySpan1 value, NumberStyles styles, NumberFormatInfo info)
at System.Convert.ToInt32(String value)
at RESTfulAPISample.Api.Controller.ProductController.GetById(Guid id) in /Users/larsson/Documents/working/proj/_netcore/RESTfulAPISample/RESTfulAPISample.Api/Controllers/ProductController.cs:line 156
at lambda_method(Closure , Object )
at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Marvin.Cache.Headers.HttpCacheHeadersMiddleware.HandleResponse(HttpContext httpContext) at Marvin.Cache.Headers.HttpCacheHeadersMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) at AutoWrapper.Base.WrapperBase.InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm) info: AutoWrapper.AutoWrapperMiddleware[0] Source:[::1] Request: GET http localhost:5000/product/5a30526a-a574-4fa9-ab5a-1b30e553b9bd Responded with [500] in 45ms fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HLTA3078EHRE", Request id "0HLTA3078EHRE:00000006": An unhandled exception was thrown by the application. System.ObjectDisposedException: **Cannot access a closed Stream**. at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) at System.IO.MemoryStream.WriteAsync(ReadOnlyMemory1 buffer, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(CancellationToken cancellationToken)
at AutoWrapper.Base.WrapperBase.InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)
at AutoWrapper.AutoWrapperMiddleware.InvokeAsync(HttpContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication1 application) fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HLTA3078EHRE", Request id "0HLTA3078EHRE:00000006": An unhandled exception was thrown by the application. System.ObjectDisposedException: **Cannot access a closed Stream**. at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) at System.IO.MemoryStream.WriteAsync(ReadOnlyMemory1 buffer, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(CancellationToken cancellationToken)
at System.IO.Pipelines.StreamPipeWriter.CompleteAsync(Exception exception)
at Microsoft.AspNetCore.Http.StreamResponseBodyFeature.CompleteAsync()
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.FireOnCompletedAwaited(Task currentTask, Stack`1 onCompleted)
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 49.628ms 500

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.