Result Writers
Writing the result is the last step of the request flow. It occurs after post-operation Actions. The Result Writer is responsible for serializing the affected models and optional wrapped response body. Only one result writer may be attached to a route. A Result Writer is required for a route to be accessible. If serialization fails, an exception of type WritingFailedException is thrown.
FormattingOptions
Every result writer accepts a FormattingOptions object, which specifies the properties on the model that should be serialized and whether to [strip the array if the dataset only contains one element](#returning-a-single-element instead-of-an-array). Methods for controlling this object are listed below in Formatting Options.
Builder Methods
Low-Level Methods
These methods are primarily used when you've implemented your own IResultWriter<TModel, TUser> and want to attach it to a route.
High-Level Methods
Result Writers
Builder Prefix: Write
- WriteJson()
- WriteJson(JsonSerializerOptions)
- WriteJsonOrXml(JsonSerializerOptions)
- WriteNumberAffected(String)
- WriteString(String)
- WriteXml()
Formatting Options
- Include(Expression<Func<TModel, Object>>)
- Include(PropertyInfo)
- IncludeAll()
- Omit(Expression<Func<TModel, Object>>)
- Omit(PropertyInfo)
- OmitAll()
- StripArrayIfSingleResult(Boolean)
Extension Methods:
- IncludePrimaryKey<TModel, TUser>(SeltzrOptionsBuilder<TModel, TUser>)
- OmitPrimaryKey<TModel, TUser>(SeltzrOptionsBuilder<TModel, TUser>)
Important
Don't confuse Omit
and Include
with Require
, Ignore
, and Optional
. The former methods work with response bodies, the latter with request bodies.
Note
Methods in bold are only available with an ORM-backed version of Seltzr, e.g Seltzr.EntityFrameworkCore
Examples
Result Writing
Writing JSON or XML depending on the request
The WriteJsonOrXml(JsonSerializerOptions) method will determine the result writer to use using the following criteria in order:
- The
Accept
header was specified andapplication/json
orapplication/xml
is accepted. - The
format
query parameter is specified and set tojson
orxml
(case insensitive). - The
Content-Type
header was specified and set toapplication/json
orapplication/xml
. - JSON is used as the default result writer
app.UseSeltzr<MyModel>(api => {
api.WriteJsonOrXml();
});
POST https://localhost:5000/
Content-Type: application/xml
...
<ArrayOfMyModel>
...
</ArrayOfMyModel>
Writing the number of affected models
The WriteNumberAffected(String) method can be used with a template string to write out the number of affected models.
app.UseSeltzr<MyModel>(api => {
api
.WriteNumberAffected("{0} Model(s) Updated")
.PostUpdateByPrimaryKey();
});
POST https://localhost:5000/5
...
1 Model(s) Updated
Choosing a result writer based on a query parameter
The QueryDependentResultWriter<TModel, TUser> class supports using different result writers based on a query parameter.
This example defines a fmt
parameter which can either write "json"
or "xml"
. Since no value is provided for the defaultIndex
parameter, if the parameter is not specified, an exception is thrown.
QueryDependentResultWriter<TModel, TUser> QueryDependentResultWriter = new QueryDependentResultWriter<TModel, TUser>(
"fmt",
new[] {"json", "xml"},
new IResultWriter<TModel, TUser>[] { new JsonResultWriter<TModel>(), new XmlResultWriter<TModel>() },
caseSensitive: true);
app.UseSeltzr<MyModel>(api => {
api.UseResultWriter(QueryDependentResultWriter);
});
GET https://localhost:5000/?fmt=json
[{
...
}]
GET https://localhost:5000/?fmt=xml
<ArrayOfMyModel>
...
</ArrayOfMyModel>
GET https://localhost:5000/
Request aborted. Cannot serialize response to request
Modifying Formatting Options
Omitting properties from the response body
Unless previous calls to Include
have affected the formatting options, a call to Omit
will include every property except for the omitted one.
app.UseSeltzr<MyModel>(api => {
api
.WriteJson()
.Omit(m => m.Value)
.CanGet();
});
GET https://localhost:5000/
[
{
"Id": 4,
"Token": "52d10081-8730-4a04-8725-f2aefb6dfac8"
},
{ ... }
]
Including a single property on the response body
Unless previous calls to Omit
have affected the formatting options, a call to Include
will omit every property except for the included one.
app.UseSeltzr<MyModel>(api => {
api
.WriteJson()
.Include(m => m.Id)
.Include(m => m.Value)
.CanGet();
});
Now only two properties (Id
and Value
) will be included in the response.
GET https://localhost:5000/
[
{
"Id": 4,
"Value": 8
},
{ ... }
]
Returning a single element instead of an array
The StripArrayIfSingleResult(Boolean) method can be used to strip the array from the response if the dataset only contains a single element. So, if a route will only ever logically return a single element, it makes sense to use this method.
app.UseSeltzr<MyModel>(api => {
api
.WriteJson()
.GetByPrimaryKey(getOptions => getOptions.StripArrayIfSingleResult())
});
GET https://localhost:5000/4
{
"Id": 4,
"Value": 8,
"Token": "52d10081-8730-4a04-8725-f2aefb6dfac8"
}
Tip
To throw an error when no elements are found, use the RequireExactlyOne(String) method.