This repository has been archived by the owner on Jan 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Supports JSON, XML and CSV output. Supports content negotiation via Accept HTTP header. Supports content negotiation via 'file extensions'.
- Loading branch information
Showing
8 changed files
with
264 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace WebApplication1 | ||
{ | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
[ApiController] | ||
public class ApiController : ControllerBase | ||
{ | ||
[HttpGet("api")] | ||
[HttpGet("api.{format}")] | ||
[FormatFilter] | ||
public IActionResult Get([FromQuery] ApiParameters p) => | ||
this.Ok(p); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
namespace WebApplication1 | ||
{ | ||
using System; | ||
using System.Net; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ClassLibrary1; | ||
using Microsoft.AspNetCore.Mvc.Formatters; | ||
using Microsoft.Net.Http.Headers; | ||
|
||
internal class CsvFormatter : TableFormatter | ||
{ | ||
internal CsvFormatter() | ||
: base(new MediaTypeHeaderValue("text/csv")) | ||
{ | ||
} | ||
|
||
protected override async Task WriteResponseBodyAsync(MultiplicationTable table, CancellationToken cancellationToken, OutputFormatterWriteContext context, Encoding encoding) | ||
{ | ||
using var writer = context.WriterFactory(context.HttpContext.Response.Body, encoding); | ||
|
||
try | ||
{ | ||
await foreach (var row in table.WithCancellation(cancellationToken)) | ||
{ | ||
var fieldNumber = 0; | ||
await foreach (var cell in row) | ||
{ | ||
if (fieldNumber++ > 0) | ||
{ | ||
await writer.WriteAsync(","); | ||
} | ||
|
||
await writer.WriteAsync(cell?.ToString()); | ||
} | ||
|
||
await writer.WriteLineAsync(); | ||
} | ||
} | ||
catch (OperationCanceledException) | ||
{ | ||
await writer.WriteAsync("# Could not multiply primes in time limit. Try less."); | ||
|
||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; | ||
} | ||
|
||
await writer.FlushAsync(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
namespace WebApplication1 | ||
{ | ||
using System; | ||
using System.Net; | ||
using System.Net.Mime; | ||
using System.Text; | ||
using System.Text.Json; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ClassLibrary1; | ||
using Microsoft.AspNetCore.Mvc.Formatters; | ||
using Microsoft.Net.Http.Headers; | ||
|
||
internal class JsonFormatter : TableFormatter | ||
{ | ||
internal JsonFormatter() | ||
: base(new MediaTypeHeaderValue(MediaTypeNames.Application.Json)) | ||
{ | ||
} | ||
|
||
protected override async Task WriteResponseBodyAsync(MultiplicationTable table, CancellationToken cancellationToken, OutputFormatterWriteContext context, Encoding encoding) | ||
{ | ||
using var writer = new Utf8JsonWriter(context.HttpContext.Response.Body); | ||
|
||
try | ||
{ | ||
writer.WriteStartArray(); | ||
|
||
await foreach (var row in table.WithCancellation(cancellationToken)) | ||
{ | ||
writer.WriteStartArray(); | ||
|
||
await foreach (var cell in row) | ||
{ | ||
if (cell.HasValue) | ||
{ | ||
writer.WriteNumberValue(cell.Value); | ||
} | ||
else | ||
{ | ||
writer.WriteNullValue(); | ||
} | ||
} | ||
|
||
writer.WriteEndArray(); | ||
} | ||
|
||
writer.WriteEndArray(); | ||
} | ||
catch (OperationCanceledException) | ||
{ | ||
writer.WriteStartObject(); | ||
writer.WriteString("error", "Could not multiply primes in time limit. Try less."); | ||
writer.WriteEndObject(); | ||
|
||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; | ||
} | ||
|
||
await writer.FlushAsync(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
namespace WebApplication1 | ||
{ | ||
using System; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ClassLibrary1; | ||
using Microsoft.AspNetCore.Mvc.Formatters; | ||
using Microsoft.Net.Http.Headers; | ||
|
||
internal abstract class TableFormatter : TextOutputFormatter | ||
{ | ||
protected TableFormatter(MediaTypeHeaderValue mimeType) | ||
{ | ||
this.SupportedMediaTypes.Add(mimeType); | ||
this.SupportedEncodings.Add(new UTF8Encoding(false)); | ||
} | ||
|
||
public sealed override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding encoding) | ||
{ | ||
var data = (ApiParameters)context.Object; | ||
|
||
var options = data.ThrowOnCancel ? | ||
PrimeGeneratorOptions.ThrowOnCancel : | ||
PrimeGeneratorOptions.None; | ||
|
||
var table = new MultiplicationTable(data.Count, options); | ||
|
||
var cancellationToken = | ||
CancellationTokenSource.CreateLinkedTokenSource( | ||
data.cancellationToken, | ||
context.HttpContext.RequestAborted).Token; | ||
|
||
if (data.Timeout.HasValue) | ||
{ | ||
cancellationToken = | ||
CancellationTokenSource.CreateLinkedTokenSource( | ||
cancellationToken, | ||
new CancellationTokenSource(data.Timeout.Value).Token).Token; | ||
} | ||
|
||
await this.WriteResponseBodyAsync(table, cancellationToken, context, encoding); | ||
} | ||
|
||
protected abstract Task WriteResponseBodyAsync(MultiplicationTable table, CancellationToken cancellationToken, OutputFormatterWriteContext context, Encoding encoding); | ||
|
||
protected sealed override bool CanWriteType(Type type) => | ||
typeof(ApiParameters).IsAssignableFrom(type); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
namespace WebApplication1 | ||
{ | ||
using System; | ||
using System.Net; | ||
using System.Net.Mime; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using System.Xml; | ||
using ClassLibrary1; | ||
using Microsoft.AspNetCore.Mvc.Formatters; | ||
using Microsoft.Net.Http.Headers; | ||
|
||
internal class XmlFormatter : TableFormatter | ||
{ | ||
internal XmlFormatter() | ||
: base(new MediaTypeHeaderValue(MediaTypeNames.Text.Xml)) | ||
{ | ||
} | ||
|
||
protected override async Task WriteResponseBodyAsync(MultiplicationTable table, CancellationToken cancellationToken, OutputFormatterWriteContext context, Encoding encoding) | ||
{ | ||
using var writer = XmlWriter.Create(context.WriterFactory(context.HttpContext.Response.Body, encoding), new XmlWriterSettings { Async = true }); | ||
|
||
try | ||
{ | ||
await writer.WriteStartElementAsync(null, "table", null); | ||
|
||
await foreach (var row in table.WithCancellation(cancellationToken)) | ||
{ | ||
await writer.WriteStartElementAsync(null, "row", null); | ||
|
||
await foreach (var cell in row) | ||
{ | ||
await writer.WriteElementStringAsync(null, "cell", null, cell.ToString()); | ||
} | ||
|
||
await writer.WriteEndElementAsync(); | ||
} | ||
|
||
await writer.WriteEndElementAsync(); | ||
} | ||
catch (OperationCanceledException) | ||
{ | ||
await writer.WriteProcessingInstructionAsync("error", "Could not multiply primes in time limit. Try less."); | ||
|
||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; | ||
} | ||
|
||
await writer.FlushAsync(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
namespace WebApplication1 | ||
{ | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Threading; | ||
|
||
public class ApiParameters | ||
{ | ||
[Range(1, int.MaxValue)] | ||
public int Count { get; set; } | ||
|
||
[Range(1, int.MaxValue)] | ||
public int? Timeout { get; set; } | ||
|
||
public bool ThrowOnCancel { get; set; } | ||
|
||
public CancellationToken cancellationToken { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters