Formatter Execution

Topics: Web Api
Oct 12, 2011 at 10:30 PM

I'm trying to follow the pattern found in the prototype branch in web api preview 5 for jsonp. The pattern seems to go like this:

Create a handler to add a header value if some query string value is found.

Create a formatter that checks for the header set in the response handler and modify the output.

So what I have done is insert a few formatters into my config object. Is there a way for these to cascade? It seems like only one will ever execute. I would like for the OnWriteToStream to check for the header value and if it doesn't exist let the next formatter in the config check to see if it's header exists until it finds one and the output stream is written. If it doesn't find anything it defaults to the input accept type. Sounds like a switch statement...

Do I need to create one formatter that acts as a factory/switch or is this already a built in path?

Coordinator
Oct 12, 2011 at 10:41 PM

Steve

You should look into our MediaTypeMapping api. Using a mapping you could add logic that checks for the header and if the header is not found then it does not match. If you look at formatters they expose a collection of mappings. You can create your own derived one for custom logic.

Glenn

Oct 12, 2011 at 11:06 PM
Edited Oct 13, 2011 at 1:08 AM

do you have a link to the api or docs or examples? or do I just do a find on the source code?

Oct 13, 2011 at 3:22 PM
Edited Oct 13, 2011 at 6:29 PM

Hi,

As Glenn mentioned above, you can use the api called AddRequestHeaderMapping for your purpose. This AddRequestHeaderMapping adds a mapping into the MediaTypeMappings collection of the formatter.

Example:

public class FormatterA : MediaTypeFormatter
{
    public FormatterA()
    {

       this. SupportedMediaTypes.Add("application/xyz");

        this.AddRequestHeaderMapping("header1", "abc", StringComparison.OrdinalIgnoreCase, isValueSubstring: false, mediaType: "application/xyz");
    }

.....
 
public class FormatterB : MediaTypeFormatter
{
    public FormatterB()
    {
        this. SupportedMediaTypes.Add("application/yahoo");
        this.AddRequestHeaderMapping("header1", "ghi", StringComparison.OrdinalIgnoreCase, isValueSubstring: false, mediaType: "application/yahoo");
    }
 
You should also check other ways of mappings like: AddQueryStringMapping, AddUriPathExtensionMapping to see if they meet your needs.
Thanks,
Kiran Challa
Nov 8, 2011 at 1:47 PM

I am also looking for a way to *cascade* MediaTypeFormatters.

first, i need JsonP, but I still want to use JsonFormatter

second, i need pagination in my way, so I need another formatter before all other formatters

any idea? thanks

Nov 18, 2011 at 11:07 PM

Only one formatter will be chosen, and you can't really *cascade* media type formatters together...  Why do you want to cascade JsonPMediaTypeFormatter and JsonMediaTypeFormatter?  By the way, JsonPMediaTypeFormatter does derive from JsonMediaTypeFormatter...