Some users have been asking for a way to not serialize WebApiModule responses. The rationale is that Web API controllers are the easiest way to write server code, but one may want to return HTML, an image, or whatever, instead of JSON data.
ResponseSerializer.None
This PR adds a ResponseSerializer.None method that can be used when initializing a WebApiModule as follows:
var server = new WebServer(o => o
// ... other initialization code ...
.WithWebApi("/api", ResponseSerializer.None(false), m => m
.WithController<MyController>())
// ... other initialization code ...
Chunked transfer encoding vs. buffering
The false parameter in the code snippet above tells EmbedIO to send data directly to the client using chunked transfer encoding. Although this has always been the behavior of ResponseSerializer.Json, some clients require a Content-Length header to be present in the response; by specifying ResponseSerializer.None(true) the response will be buffered in memory and sent all at once, along with a Content-Length header.
Supported data types
If a controller method returns void, Task<void>, or otherwise returns a null value, the response will have no body.
If a controller method returns byte[] or Task<byte[]>, ResponseSerializer.None will send the returned array of bytes as-is.
If a controller method returns string or Task<string>, ResponseSerializer.None will send the returned string, encoded according to context.ContentEncoding.
Any other type (or result type, for asynchronous controller methods) will be converted to a string via its ToString method and sent as specified in the previous paragraph.
Response compression
ResponseSerializer.None will negotiate content compression according to context.ContentType and relevant request headers, the same way FileModule does.
Additions to ResponseSerializer.Json
This PR adds three new overloads to the ResponseSerializer.Json method, to allow for buffering of JSON responses. Existing overloads will continue to use chunked transfer encoding.
The new overloads, as well as the previously existing ones, will also negotiate content compression the same way as ResponseSerializer.None (which all of them now use under the hood).
WebServer.Utf8NoBomEncoding
Another addition is the static WebServer.Utf8NoBomEncoding property, a UTF-8 encoding that does not send a byte order mark at the start of a response stream. Some clients, especially non-Windows clients, may get confused by the byte order mark, which is also totally redundant given that text encoding is (or should be) specified in the Content-Type response header; this had been fixed in ResponseSerializer.Json, but not on a global level. The WebServer.DefaultEncoding property is now set to Utf8NoBomEncoding.
Other modifications
The target platform for tests and samples is now net5.0; GitHub actions have been updated accordingly.
Dependency versions are now managed centrally via a Directory.Packages.props file.
The Directory.Build.props file is now in the repository root instead of the src folder and centralizes common build options, as well as development dependencies such as analyzers.
The library version specified in Directory.Build.props is now 3.5.0, which makes sense given the added funcionality.
All dependency versions have been updated; most noticeably, EmbedIO now uses SWAN version 3.1.0.
Finally, I did some some trivial code cleanup, mostly by adding discards on unused expressions values.
Some users have been asking for a way to not serialize
WebApiModule
responses. The rationale is that Web API controllers are the easiest way to write server code, but one may want to return HTML, an image, or whatever, instead of JSON data.ResponseSerializer.None
This PR adds a
ResponseSerializer.None
method that can be used when initializing aWebApiModule
as follows:Chunked transfer encoding vs. buffering
The
false
parameter in the code snippet above tells EmbedIO to send data directly to the client using chunked transfer encoding. Although this has always been the behavior ofResponseSerializer.Json
, some clients require aContent-Length
header to be present in the response; by specifyingResponseSerializer.None(true)
the response will be buffered in memory and sent all at once, along with aContent-Length
header.Supported data types
If a controller method returns
void
,Task<void>
, or otherwise returns anull
value, the response will have no body.If a controller method returns
byte[]
orTask<byte[]>
,ResponseSerializer.None
will send the returned array of bytes as-is.If a controller method returns
string
orTask<string>
,ResponseSerializer.None
will send the returned string, encoded according tocontext.ContentEncoding
.Any other type (or result type, for asynchronous controller methods) will be converted to a string via its
ToString
method and sent as specified in the previous paragraph.Response compression
ResponseSerializer.None
will negotiate content compression according tocontext.ContentType
and relevant request headers, the same wayFileModule
does.Additions to
ResponseSerializer.Json
This PR adds three new overloads to the
ResponseSerializer.Json
method, to allow for buffering of JSON responses. Existing overloads will continue to use chunked transfer encoding.The new overloads, as well as the previously existing ones, will also negotiate content compression the same way as
ResponseSerializer.None
(which all of them now use under the hood).WebServer.Utf8NoBomEncoding
Another addition is the static
WebServer.Utf8NoBomEncoding
property, a UTF-8 encoding that does not send a byte order mark at the start of a response stream. Some clients, especially non-Windows clients, may get confused by the byte order mark, which is also totally redundant given that text encoding is (or should be) specified in theContent-Type
response header; this had been fixed inResponseSerializer.Json
, but not on a global level. TheWebServer.DefaultEncoding
property is now set toUtf8NoBomEncoding
.Other modifications
The target platform for tests and samples is now
net5.0
; GitHub actions have been updated accordingly.Dependency versions are now managed centrally via a
Directory.Packages.props
file.The
Directory.Build.props
file is now in the repository root instead of thesrc
folder and centralizes common build options, as well as development dependencies such as analyzers.The library version specified in
Directory.Build.props
is now 3.5.0, which makes sense given the added funcionality.All dependency versions have been updated; most noticeably, EmbedIO now uses SWAN version 3.1.0.
Finally, I did some some trivial code cleanup, mostly by adding discards on unused expressions values.