-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReportMiddleware.cs
85 lines (70 loc) · 3.01 KB
/
ReportMiddleware.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
using z.Report.Services;
using Microsoft.AspNetCore.Http;
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using z.Data;
namespace z.Report
{
public class ReportMiddleware
{
private readonly RequestDelegate _next;
private readonly IRenderService _renderService;
public ReportMiddleware(RequestDelegate next, IRenderService renderService)
{
_next = next;
_renderService = renderService;
}
public async Task Invoke(HttpContext context)
{
// put to the Response.Body our own stream so we can later forward the underlying buffer to jsreport
var buffer = new MemoryStream();
var originalResponseStream = context.Response.Body;
context.Response.Body = buffer;
context.Features.Set<IReportFeature>(new ReportFeature(context));
try
{
await _next(context);
var feature = context.Features.Get<IReportFeature>();
// we don't deal with failed request and let the other middlewares handle it
if (!feature.Enabled || context.Response.StatusCode != 200)
{
buffer.Seek(0, SeekOrigin.Begin);
await buffer.CopyToAsync(originalResponseStream);
return;
}
buffer.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(buffer);
string responseBody = await reader.ReadToEndAsync();
feature.RenderRequest.Template = responseBody;
var report = await _renderService.RenderAsync(feature.RenderRequest);
//feature.AfterRender?.Invoke(report);
context.Response.Headers["Content-Disposition"] = feature.RenderRequest.Options.ContentType();
if (feature.Base64Content)
{
context.Response.ContentType = "application/pdf;base64";
var data = Convert.ToBase64String(report);
if (feature.Base64AppendString)
data = $"data:application/pdf;base64,{ data }";
var rpts = new StringContent(data);
var marr = await rpts.ReadAsByteArrayAsync();
using var ms = new MemoryStream(marr);
context.Response.ContentLength = ms.Length;
await ms.CopyToAsync(originalResponseStream);
}
else
{
context.Response.ContentType = feature.RenderRequest.Options.ContentType();
using var ms = new MemoryStream(report);
await ms.CopyToAsync(originalResponseStream);
}
}
finally
{
// finally copy the jsreport output stream to the Response.Body
context.Response.Body = originalResponseStream;
}
}
}
}