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

Commit 469caf8

Browse files
Ihar YakimushIhar Yakimush
authored andcommitted
responce body for MVC
1 parent 8e1713f commit 469caf8

File tree

10 files changed

+223
-60
lines changed

10 files changed

+223
-60
lines changed

Commmunity.AspNetCore.ExceptionHandling.Integration/Commmunity.AspNetCore.ExceptionHandling.Integration.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>netcoreapp2.0</TargetFramework>
4+
<TargetFramework>netcoreapp2.1</TargetFramework>
55
</PropertyGroup>
66

77
<ItemGroup>
88
<Folder Include="wwwroot\" />
99
</ItemGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
12+
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.1.2" />
1313
<PackageReference Include="Microsoft.AspNetCore.Buffering" Version="0.2.2" />
1414
</ItemGroup>
1515

@@ -18,6 +18,7 @@
1818
</ItemGroup>
1919

2020
<ItemGroup>
21+
<ProjectReference Include="..\Commmunity.AspNetCore.ExceptionHandling.Mvc\Commmunity.AspNetCore.ExceptionHandling.Mvc.csproj" />
2122
<ProjectReference Include="..\Commmunity.AspNetCore.ExceptionHandling\Commmunity.AspNetCore.ExceptionHandling.csproj" />
2223
</ItemGroup>
2324

Commmunity.AspNetCore.ExceptionHandling.Integration/Startup.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Text;
77
using System.Threading.Tasks;
8+
using Commmunity.AspNetCore.ExceptionHandling.Mvc;
89
using Microsoft.AspNetCore.Builder;
910
using Microsoft.AspNetCore.Hosting;
1011
using Microsoft.Extensions.Configuration;
@@ -39,15 +40,13 @@ public void ConfigureServices(IServiceCollection services)
3940
options.For<InvalidCastException>()
4041
.Response(e => 400)
4142
.Headers((h, e) => h["X-qwe"] = e.Message)
42-
.WithBody((req,sw, exception) =>
43-
{
44-
return sw.WriteAsync(exception.ToString());
45-
})
43+
.WithBody((req,sw, exception) => sw.WriteAsync(exception.ToString()))
4644
.NextChain();
4745

4846
options.For<Exception>()
4947
.Log(lo => { lo.Formatter = (o, e) => "qwe"; })
50-
.Response(e => 500, RequestStartedBehaviour.SkipHandler).ClearCacheHeaders().WithBodyJson((r, e) => new { msg = e.Message, path = r.Path })
48+
//.Response(e => 500, RequestStartedBehaviour.SkipHandler).ClearCacheHeaders().WithBodyJson((r, e) => new { msg = e.Message, path = r.Path })
49+
.Response(e => 500, RequestStartedBehaviour.SkipHandler).ClearCacheHeaders().WithBodyObjectResult((r, e) => new { msg = e.Message, path = r.Path })
5150
.Handled();
5251
});
5352

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp2.1</TargetFramework>
5+
<Description>Extension methods to configure exception handler which write MVC action result to responce body. Userfull for writing objects</Description>
6+
<PackageProjectUrl>https://github.com/IharYakimush/AspNetCore</PackageProjectUrl>
7+
<PackageLicenseUrl>https://github.com/IharYakimush/AspNetCore/blob/develop/LICENSE</PackageLicenseUrl>
8+
<Copyright>IharYakimush</Copyright>
9+
<PackageTags>AspNetCore exception handling policy mvc action result</PackageTags>
10+
<AssemblyVersion>2.0.0.0</AssemblyVersion>
11+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
12+
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
13+
<FileVersion>2.0.0.0</FileVersion>
14+
<Company />
15+
<Authors>IharYakimush</Authors>
16+
<Version>2.0.0</Version>
17+
<SignAssembly>true</SignAssembly>
18+
<AssemblyOriginatorKeyFile>..\sgn.snk</AssemblyOriginatorKeyFile>
19+
<ApplicationIcon />
20+
<OutputType>Library</OutputType>
21+
<StartupObject />
22+
</PropertyGroup>
23+
24+
<ItemGroup>
25+
<ProjectReference Include="..\Commmunity.AspNetCore.ExceptionHandling\Commmunity.AspNetCore.ExceptionHandling.csproj" />
26+
</ItemGroup>
27+
28+
<ItemGroup>
29+
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.1.1" />
30+
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.1" />
31+
<PackageReference Include="Microsoft.AspNetCore.Routing.Abstractions" Version="2.1.1" />
32+
</ItemGroup>
33+
34+
</Project>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System;
2+
using Commmunity.AspNetCore.ExceptionHandling.Builder;
3+
using Microsoft.AspNetCore.Http;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.AspNetCore.Mvc.Abstractions;
6+
using Microsoft.AspNetCore.Mvc.Infrastructure;
7+
using Microsoft.AspNetCore.Routing;
8+
using Microsoft.Extensions.DependencyInjection;
9+
10+
namespace Commmunity.AspNetCore.ExceptionHandling.Mvc
11+
{
12+
public static class PolicyBuilderExtensions
13+
{
14+
private static readonly RouteData EmptyRouteData = new RouteData();
15+
16+
private static readonly ActionDescriptor EmptyActionDescriptor = new ActionDescriptor();
17+
18+
public static IResponseHandlers<TException> WithBodyActionResult<TException, TResult>(
19+
this IResponseHandlers<TException> builder, Func<HttpRequest, TException, TResult> resultFactory, int index = -1)
20+
where TException : Exception
21+
where TResult : IActionResult
22+
{
23+
return builder.WithBody((request, streamWriter, exception) =>
24+
{
25+
var context = request.HttpContext;
26+
var executor = context.RequestServices.GetService<IActionResultExecutor<TResult>>();
27+
28+
if (executor == null)
29+
{
30+
throw new InvalidOperationException($"No result executor for '{typeof(TResult).FullName}' has been registered.");
31+
}
32+
33+
var routeData = context.GetRouteData() ?? EmptyRouteData;
34+
35+
var actionContext = new ActionContext(context, routeData, EmptyActionDescriptor);
36+
37+
return executor.ExecuteAsync(actionContext, resultFactory(request, exception));
38+
});
39+
}
40+
41+
public static IResponseHandlers<TException> WithBodyActionResult<TException, TResult>(
42+
this IResponseHandlers<TException> builder, TResult result, int index = -1)
43+
where TException : Exception
44+
where TResult : IActionResult
45+
{
46+
return builder.WithBodyActionResult((request, exception) => result);
47+
}
48+
49+
public static IResponseHandlers<TException> WithBodyObjectResult<TException, TObject>(
50+
this IResponseHandlers<TException> builder, TObject value, int index = -1)
51+
where TException : Exception
52+
{
53+
return builder.WithBodyActionResult(new ObjectResult(value), index);
54+
}
55+
56+
public static IResponseHandlers<TException> WithBodyObjectResult<TException, TObject>(
57+
this IResponseHandlers<TException> builder, Func<HttpRequest, TException, TObject> valueFactory, int index = -1)
58+
where TException : Exception
59+
{
60+
return builder.WithBodyActionResult(
61+
(request, exception) => new ObjectResult(valueFactory(request, exception)), index);
62+
}
63+
}
64+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<Description>Extension methods to configure exception handler which write object serialized using Newtonsoft.Json serializer to responce body. In case of using netcore2.1+ use Commmunity.AspNetCore.ExceptionHandling.Mvc package instead</Description>
6+
<Authors>IharYakimush</Authors>
7+
<Copyright>IharYakimush</Copyright>
8+
<PackageLicenseUrl>https://github.com/IharYakimush/AspNetCore/blob/develop/LICENSE</PackageLicenseUrl>
9+
<PackageProjectUrl>https://github.com/IharYakimush/AspNetCore</PackageProjectUrl>
10+
<PackageTags>AspNetCore exception handling policy json response</PackageTags>
11+
<AssemblyVersion>2.0.0.0</AssemblyVersion>
12+
<Version>2.0.0</Version>
13+
<Company />
14+
</PropertyGroup>
15+
16+
<ItemGroup>
17+
<PackageReference Include="Newtonsoft.Json" Version="10.0.1" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<ProjectReference Include="..\Commmunity.AspNetCore.ExceptionHandling\Commmunity.AspNetCore.ExceptionHandling.csproj" />
22+
</ItemGroup>
23+
24+
</Project>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.IO;
3+
using System.Threading.Tasks;
4+
using Commmunity.AspNetCore.ExceptionHandling.Builder;
5+
using Microsoft.AspNetCore.Http;
6+
using Microsoft.Extensions.DependencyInjection;
7+
using Microsoft.Net.Http.Headers;
8+
using Newtonsoft.Json;
9+
10+
namespace Commmunity.AspNetCore.ExceptionHandling.NewtonsoftJson
11+
{
12+
public static class PolicyBuilderExtensions
13+
{
14+
[Obsolete("In case of using netcore2.1+ use Commmunity.AspNetCore.ExceptionHandling.Mvc instead")]
15+
public static IResponseHandlers<TException> WithBodyJson<TException, TObject>(
16+
this IResponseHandlers<TException> builder, Func<HttpRequest, TException, TObject> value, JsonSerializerSettings settings = null, int index = -1)
17+
where TException : Exception
18+
{
19+
return builder.WithBody((request, streamWriter, exception) =>
20+
{
21+
if (settings == null)
22+
{
23+
settings = request.HttpContext.RequestServices.GetService<JsonSerializerSettings>();
24+
}
25+
26+
if (settings == null)
27+
{
28+
settings = new JsonSerializerSettings();
29+
}
30+
31+
JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
32+
33+
var headers = request.HttpContext.Response.Headers;
34+
if (!headers.ContainsKey(HeaderNames.ContentType))
35+
{
36+
headers[HeaderNames.ContentType] = "application/json";
37+
}
38+
39+
TObject val = value(request, exception);
40+
41+
//return Task.CompletedTask;
42+
using (MemoryStream ms = new MemoryStream())
43+
{
44+
using (StreamWriter sw = new StreamWriter(ms, streamWriter.Encoding, 1024, true))
45+
{
46+
jsonSerializer.Serialize(sw, val);
47+
}
48+
49+
ms.Seek(0, SeekOrigin.Begin);
50+
byte[] array = ms.ToArray();
51+
BinaryWriter binaryWriter = new BinaryWriter(streamWriter.BaseStream, streamWriter.Encoding, true);
52+
binaryWriter.Write(array);
53+
54+
return Task.CompletedTask;
55+
}
56+
});
57+
}
58+
}
59+
}

Commmunity.AspNetCore.ExceptionHandling/Commmunity.AspNetCore.ExceptionHandling.csproj

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netstandard2.0</TargetFramework>
4+
<TargetFrameworks>netstandard2.0;netcoreapp2.1</TargetFrameworks>
55
<Description>Middleware to configure exception handling policies. Configure chain of handlers per exception type. OOTB handlers: log, retry, set responce headers and body</Description>
66
<PackageProjectUrl>https://github.com/IharYakimush/AspNetCore</PackageProjectUrl>
77
<PackageLicenseUrl>https://github.com/IharYakimush/AspNetCore/blob/develop/LICENSE</PackageLicenseUrl>
@@ -16,12 +16,30 @@
1616
<Version>2.0.0</Version>
1717
<SignAssembly>true</SignAssembly>
1818
<AssemblyOriginatorKeyFile>..\sgn.snk</AssemblyOriginatorKeyFile>
19+
<ApplicationIcon />
20+
<OutputType>Library</OutputType>
21+
<StartupObject />
1922
</PropertyGroup>
2023

21-
<ItemGroup>
24+
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
25+
<DefineConstants>TRACE;DEBUG</DefineConstants>
26+
</PropertyGroup>
27+
28+
<PropertyGroup Condition="'$(TargetFramework)'=='netcoreapp2.1'">
29+
<DefineConstants>NETCOREAPP;NETCOREAPP2_1</DefineConstants>
30+
</PropertyGroup>
31+
<ItemGroup Condition="'$(TargetFramework)'=='netcoreapp2.1'">
32+
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.1.1" />
33+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
34+
</ItemGroup>
35+
36+
<PropertyGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
37+
<DefineConstants>NETSTANDARD;NETSTANDARD2_0</DefineConstants>
38+
</PropertyGroup>
39+
40+
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
2241
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.0.0" />
2342
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
24-
<PackageReference Include="Newtonsoft.Json" Version="10.0.1" />
2543
</ItemGroup>
2644

2745
</Project>

Commmunity.AspNetCore.ExceptionHandling/PolicyBuilderExtensions.cs

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.IO;
3-
using System.Net;
43
using System.Threading.Tasks;
54
using Commmunity.AspNetCore.ExceptionHandling.Builder;
65
using Commmunity.AspNetCore.ExceptionHandling.Exc;
@@ -11,9 +10,7 @@
1110
using Microsoft.AspNetCore.Http;
1211
using Microsoft.Extensions.DependencyInjection;
1312
using Microsoft.Extensions.DependencyInjection.Extensions;
14-
using Microsoft.Extensions.Options;
1513
using Microsoft.Net.Http.Headers;
16-
using Newtonsoft.Json;
1714

1815
namespace Commmunity.AspNetCore.ExceptionHandling
1916
{
@@ -197,50 +194,6 @@ public static IResponseHandlers<TException> WithBody<TException>(
197194
});
198195

199196
return builder;
200-
}
201-
202-
public static IResponseHandlers<TException> WithBodyJson<TException, TObject>(
203-
this IResponseHandlers<TException> builder, Func<HttpRequest, TException, TObject> value, JsonSerializerSettings settings = null, int index = -1)
204-
where TException : Exception
205-
{
206-
return builder.WithBody((request, streamWriter, exception) =>
207-
{
208-
if (settings == null)
209-
{
210-
settings = request.HttpContext.RequestServices.GetService<JsonSerializerSettings>();
211-
}
212-
213-
if (settings == null)
214-
{
215-
settings = new JsonSerializerSettings();
216-
}
217-
218-
JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
219-
220-
var headers = request.HttpContext.Response.Headers;
221-
if (!headers.ContainsKey(HeaderNames.ContentType))
222-
{
223-
headers[HeaderNames.ContentType] = "application/json";
224-
}
225-
226-
TObject val = value(request, exception);
227-
228-
//return Task.CompletedTask;
229-
using (MemoryStream ms = new MemoryStream())
230-
{
231-
using (StreamWriter sw = new StreamWriter(ms, streamWriter.Encoding, 1024, true))
232-
{
233-
jsonSerializer.Serialize(sw, val);
234-
}
235-
236-
ms.Seek(0, SeekOrigin.Begin);
237-
byte[] array = ms.ToArray();
238-
BinaryWriter binaryWriter = new BinaryWriter(streamWriter.BaseStream, streamWriter.Encoding, true);
239-
binaryWriter.Write(array);
240-
241-
return Task.CompletedTask;
242-
}
243-
});
244-
}
197+
}
245198
}
246199
}

Commmunity.AspNetCore.ExceptionHandling/Response/RawResponseExceptionHandler.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ public static Task SetStatusCode(HttpContext context, TException exception, Func
8383
return Task.CompletedTask;
8484
}
8585

86-
public static Task SetBody<TException>(HttpContext context, TException exception, Func<HttpRequest, StreamWriter, TException, Task> settings)
87-
where TException : Exception
86+
public static Task SetBody(HttpContext context, TException exception, Func<HttpRequest, StreamWriter, TException, Task> settings)
8887
{
8988
if (!context.Items.ContainsKey(BodySetKey))
9089
{

Commmunity.AspNetCore.sln

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1313
README.md = README.md
1414
EndProjectSection
1515
EndProject
16+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Commmunity.AspNetCore.ExceptionHandling.Mvc", "Commmunity.AspNetCore.ExceptionHandling.Mvc\Commmunity.AspNetCore.ExceptionHandling.Mvc.csproj", "{0D080E5A-9500-43AC-88CD-069947CFA5EF}"
17+
EndProject
18+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Commmunity.AspNetCore.ExceptionHandling.NewtonsoftJson", "Commmunity.AspNetCore.ExceptionHandling.NewtonsoftJson\Commmunity.AspNetCore.ExceptionHandling.NewtonsoftJson.csproj", "{B3BAD0B5-15BC-46EE-A224-9DAF10376B81}"
19+
EndProject
1620
Global
1721
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1822
Debug|Any CPU = Debug|Any CPU
@@ -27,6 +31,14 @@ Global
2731
{393C6033-4255-43C3-896D-BFE30E264E4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
2832
{393C6033-4255-43C3-896D-BFE30E264E4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
2933
{393C6033-4255-43C3-896D-BFE30E264E4A}.Release|Any CPU.Build.0 = Release|Any CPU
34+
{0D080E5A-9500-43AC-88CD-069947CFA5EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35+
{0D080E5A-9500-43AC-88CD-069947CFA5EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
36+
{0D080E5A-9500-43AC-88CD-069947CFA5EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
37+
{0D080E5A-9500-43AC-88CD-069947CFA5EF}.Release|Any CPU.Build.0 = Release|Any CPU
38+
{B3BAD0B5-15BC-46EE-A224-9DAF10376B81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39+
{B3BAD0B5-15BC-46EE-A224-9DAF10376B81}.Debug|Any CPU.Build.0 = Debug|Any CPU
40+
{B3BAD0B5-15BC-46EE-A224-9DAF10376B81}.Release|Any CPU.ActiveCfg = Release|Any CPU
41+
{B3BAD0B5-15BC-46EE-A224-9DAF10376B81}.Release|Any CPU.Build.0 = Release|Any CPU
3042
EndGlobalSection
3143
GlobalSection(SolutionProperties) = preSolution
3244
HideSolutionNode = FALSE

0 commit comments

Comments
 (0)