Skip to content
This repository was archived by the owner on Aug 30, 2025. It is now read-only.

Commit 2f262f0

Browse files
authored
Merge pull request #23 from TechNobre/main
Deploy nuget v1.1.0
2 parents da875bd + 2ce3bfe commit 2f262f0

16 files changed

Lines changed: 239 additions & 67 deletions

File tree

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33

44

55

6+
## [1.1.0] - 2022-05-29
7+
[Full Changelog](https://github.com/TechNobre/PowerUtils.AspNetCore.ErrorHandler/compare/v1.0.1...v1.1.0)
8+
9+
10+
### Enhancements
11+
12+
- Added support to error code 413 when the payload too large;
13+
14+
15+
16+
617
## [1.0.1] - 2022-05-28
718
[Full Changelog](https://github.com/TechNobre/PowerUtils.AspNetCore.ErrorHandler/compare/v1.0.0...v1.0.1)
819

media/test_3_23mb.jpg

3.26 MB
Loading
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using PowerUtils.AspNetCore.ErrorHandler.Samples.Models;
3+
using PowerUtils.Net.Constants;
4+
5+
namespace PowerUtils.AspNetCore.ErrorHandler.Samples.Controllers;
6+
7+
[ApiController]
8+
[Route("files")]
9+
public class FilesController : ControllerBase
10+
{
11+
[HttpPost]
12+
[Consumes(ExtendedMediaTypeNames.Multipart.FORM_DATA)]
13+
public IActionResult Upload([FromForm] FileRequest _)
14+
=> Ok();
15+
}

samples/PowerUtils.AspNetCore.ErrorHandler.Samples/Controllers/ModelStateController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace PowerUtils.AspNetCore.ErrorHandler.Samples.Controllers;
88
public class ModelStateController : ControllerBase
99
{
1010
[HttpPost]
11-
public IActionResult Post(Product _)
11+
public IActionResult Post(ProductRequest _)
1212
{
1313
if(!ModelState.IsValid)
1414
{
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using Microsoft.AspNetCore.Http;
2+
3+
namespace PowerUtils.AspNetCore.ErrorHandler.Samples.Models;
4+
5+
public class FileRequest
6+
{
7+
public IFormFile File { get; set; }
8+
}

samples/PowerUtils.AspNetCore.ErrorHandler.Samples/Models/Product.cs renamed to samples/PowerUtils.AspNetCore.ErrorHandler.Samples/Models/ProductRequest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace PowerUtils.AspNetCore.ErrorHandler.Samples.Models;
44

5-
public class Product
5+
public class ProductRequest
66
{
77
[Required]
88
public string Name { get; set; }

samples/PowerUtils.AspNetCore.ErrorHandler.Samples/Startup.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Microsoft.AspNetCore.Authentication.JwtBearer;
44
using Microsoft.AspNetCore.Builder;
55
using Microsoft.AspNetCore.Http;
6+
using Microsoft.AspNetCore.Http.Features;
67
using Microsoft.Extensions.DependencyInjection;
78
using PowerUtils.AspNetCore.Authentication.BasicAuth.Attributes;
89
using PowerUtils.AspNetCore.ErrorHandler.Samples.Exceptions;
@@ -48,6 +49,16 @@ public void ConfigureServices(IServiceCollection services)
4849
options.ExceptionMapper<TestException>(exception => StatusCodes.Status503ServiceUnavailable);
4950
options.ExceptionMapper<TimeoutException>(exception => StatusCodes.Status504GatewayTimeout);
5051
});
52+
53+
54+
55+
// Configurations to payload size
56+
services.Configure<FormOptions>(options =>
57+
{
58+
options.ValueLengthLimit = 1048576; // Default value (4194304 Bytes -> 4 MB) - 1048576 = 1MB
59+
options.MultipartBodyLengthLimit = 1048576; // Default value (134217728 Bytes -> 128 MB) - 1048576 = 1MB
60+
options.MemoryBufferThreshold = 1048576; // Default value (65536 Bytes -> 128 MB) - 1048576 = 1MB
61+
});
5162
}
5263

5364
public void Configure(IApplicationBuilder app)

src/Handlers/ModelStateMiddleware.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using Microsoft.AspNetCore.Http;
2-
using Microsoft.AspNetCore.Mvc;
1+
using Microsoft.AspNetCore.Mvc;
32
using Microsoft.Extensions.DependencyInjection;
43
using Microsoft.Extensions.Logging;
54
using PowerUtils.Net.Constants;
@@ -16,16 +15,18 @@ internal static IServiceCollection AddModelStateMiddleware(this IServiceCollecti
1615
var loggerFactory = actionContext.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>();
1716
var logger = loggerFactory.CreateLogger("ModelStateHandler");
1817

19-
actionContext.HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
20-
2118
var problemDetails = problemDetailsFactory.Create(actionContext);
2219

2320
logger.Debug(problemDetails);
2421

22+
2523
actionContext.HttpContext.ResetResponse();
24+
actionContext.HttpContext.Response.StatusCode = problemDetails.Status;
25+
2626

27-
return new BadRequestObjectResult(problemDetails)
27+
return new ObjectResult(problemDetails)
2828
{
29+
StatusCode = problemDetails.Status,
2930
ContentTypes = { ExtendedMediaTypeNames.ProblemApplication.JSON }
3031
};
3132
});

src/ModelStateExtensions.cs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Microsoft.AspNetCore.Mvc.ModelBinding;
5+
6+
namespace PowerUtils.AspNetCore.ErrorHandler
7+
{
8+
internal static class ModelStateExtensions
9+
{
10+
private const string BODY_PROPERTY_NAME = "RequestBody";
11+
12+
public static IDictionary<string, string> MappingModelState(this ModelStateDictionary modelState)
13+
{
14+
var modelStateErrors = modelState.Where(s => s.Value.Errors.Count > 0);
15+
16+
var errors = new Dictionary<string, string>();
17+
foreach(var modelStateError in modelStateErrors)
18+
{
19+
(var property, var error) = modelStateError._mappingModelStateErrors();
20+
errors.Add(property, error);
21+
}
22+
23+
return errors;
24+
}
25+
26+
public static IDictionary<string, string> CheckPayloadTooLargeAndReturnError(this ModelStateDictionary modelState)
27+
{
28+
var modelStateErrors = modelState.Where(s => s.Value.Errors.Count > 0);
29+
if(modelStateErrors.Count() != 1)
30+
{
31+
return new Dictionary<string, string>();
32+
}
33+
34+
35+
var errorMessage = modelStateErrors
36+
.Single()
37+
.Value.Errors
38+
.Select(s => s.ErrorMessage)
39+
.First()
40+
.ToLower();
41+
42+
if("failed to read the request form. multipart body length limit 1048576 exceeded.".Equals(errorMessage))
43+
{
44+
var maxSize = errorMessage
45+
.Replace("failed to read the request form. multipart body length limit ", "")
46+
.Replace(" exceeded.", "");
47+
48+
return new Dictionary<string, string>()
49+
{
50+
{ BODY_PROPERTY_NAME, "MAX:" + maxSize }
51+
};
52+
}
53+
54+
return new Dictionary<string, string>();
55+
}
56+
57+
private static (string Property, string Error) _mappingModelStateErrors(this KeyValuePair<string, ModelStateEntry> modelStateError)
58+
{
59+
if(modelStateError.Key.StartsWith("$."))
60+
{
61+
return (
62+
modelStateError.Key[2..],
63+
"INVALID"
64+
);
65+
}
66+
67+
var error = modelStateError
68+
.Value
69+
.Errors
70+
.Select(s => s.ErrorMessage)
71+
.First();
72+
73+
return _mappingError(modelStateError.Key, error);
74+
}
75+
76+
private static (string Property, string Error) _mappingError(string property, string error)
77+
{
78+
if(property == "$")
79+
{
80+
return (BODY_PROPERTY_NAME, "INVALID");
81+
}
82+
83+
if("A non-empty request body is required.".Equals(error, StringComparison.InvariantCultureIgnoreCase))
84+
{
85+
return (BODY_PROPERTY_NAME, "REQUIRED");
86+
}
87+
88+
return (property, error);
89+
}
90+
}
91+
}

src/PowerUtils.AspNetCore.ErrorHandler.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<PackageId>PowerUtils.AspNetCore.ErrorHandler</PackageId>
1919
<title>PowerUtils.AspNetCore.ErrorHandler</title>
2020
<Product>PowerUtils.AspNetCore.ErrorHandler</Product>
21-
<Version>1.0.1</Version>
21+
<Version>1.1.0</Version>
2222

2323
<Authors>Nelson Nobre</Authors>
2424
<Company>TechNobre</Company>

0 commit comments

Comments
 (0)