I'm running Nancy on Microsoft.Owin.Host.IIS (Helios).
I'm trying to wire up conneg via IResponseProcessor
to respond to an Accept
header of text/plain
, but it will only return 406.
I've tried multiple content types, and nothing works.... EXCEPT, strangely, text/html
(after clearing the base ViewProcessor
).
public class ViewApiProcessor : IResponseProcessor
{
private readonly IViewFactory viewFactory;
public ViewApiProcessor(IViewFactory _viewFactory)
{
this.viewFactory = _viewFactory;
}
private static readonly IEnumerable<Tuple<string, MediaRange>> extensionMappings =
new[] { new Tuple<string, MediaRange>("txt", MediaRange.FromString("text/plain")) };
public IEnumerable<Tuple<string, MediaRange>> ExtensionMappings
{
get { return extensionMappings; }
}
public ProcessorMatch CanProcess(MediaRange requestedMediaRange, dynamic model, NancyContext context)
{
bool matchingContentType =
requestedMediaRange.Matches("text/plain");
return matchingContentType
? new ProcessorMatch { ModelResult = MatchResult.DontCare, RequestedContentTypeResult = MatchResult.ExactMatch }
: new ProcessorMatch();
}
public Response Process(MediaRange requestedMediaRange, dynamic model, NancyContext context)
{
context.ViewBag.RequestType = "api";
var response = (Response)this.viewFactory.RenderView(context.NegotiationContext.ViewName, model, GetViewLocationContext(context));
return response.WithContentType("text/plain");
}
private static ViewLocationContext GetViewLocationContext(NancyContext context)
{
return new ViewLocationContext
{
Context = context,
ModuleName = context.NegotiationContext.ModuleName,
ModulePath = context.NegotiationContext.ModulePath
};
}
}
Then, in the module:
Get["/"] = p =>
{
return Negotiate.WithView("Index");
};
UPDATED: I have edited the code above to show the proper combination of IResponseProcessor
and Negotiator
The more interesting thing here is, what does your routes look like? If you want it to be able to negotiate the response then you need to return a `Negotiator``
Get["/"] = _ => {
return Negotiator.WithModel(...).WithView("foo");
};
If you return a plain Response
(or anything that can be implicitly cast to a Response, such as string, int, HttpStatusCode or Action) then you will circumvent the content negotiation entirely as described here https://github.com/NancyFx/Nancy/wiki/Content-Negotiation.
If you are returning a view, using View[..]
then you are saying that the only permissible media range is text/html