Does 'AddUriPathExtensionMapping' even work?

Topics: Web Api
Oct 21, 2011 at 5:15 PM

This:

        public ADPJSONFormatter()
        {
            this.AddUriPathExtensionMapping("json", "application/json");
            this.AddQueryStringMapping("format", "json", "application/json");

            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/json"));
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
        }

crashes my running project. ?format=json works, '/json' crashes.

Any ideas?

Oct 21, 2011 at 5:39 PM

If you try “.json” (with a “.” Instead of “/”) then it should work.

What kind of exception do you see?

Henrik

Oct 25, 2011 at 8:25 AM

It's just a 404. Both '/json' and '.json' aren't called.

Iv'e examined your projects and you have indeed changed it to a '.'

The code above is being run, and, like i said, format work.

Very strange.

Oct 25, 2011 at 9:51 AM

As a test, I updated the ContactManager project as follows:

1. Commented out the /png in the ExtensionMapping like this:

    public class UriExtensionMappings : List<UriExtensionMapping>
    {
        public UriExtensionMappings()
        {
            this.AddMapping("xml", "application/xml");
            this.AddMapping("json", "application/json");
            //this.AddMapping("png", "image/png");
            this.AddMapping("odata", "application/atom+xml");
            this.AddMapping("vcf", "text/directory");
            this.AddMapping("ics", "text/calendar");
        }
    }

2. Changed the constructor of the ContactPngFormatter like so:

        public ContactPngFormatter()
        {
            this.AddUriPathExtensionMapping("png", "image/png");
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/png"));
        }

3. Expected this URI to work: http://localhost:9100/contact/1.png

4. Got the following exception:

The service operation 'Get' expected a value assignable to type 'Int32' for input parameter 'id' but received a value of type 'String'.

Stacktrace:

   at Microsoft.ApplicationServer.Http.Dispatcher.OperationHandlerPipelineInfo.ServiceOperationHandler.ValidateAndConvertInput(Object[] values) in C:\Users\howard\Desktop\wcf.codeplex.com\WCFWebApi\Http\Src\Microsoft.ApplicationServer.Http\Microsoft\ApplicationServer\Http\Dispatcher\OperationHandlerPipelineInfo.cs:line 693
   at Microsoft.ApplicationServer.Http.Dispatcher.OperationHandlerPipelineInfo.GetInputValuesForHandler(Int32 handlerIndex, Object[] pipelineValues) in C:\Users\howard\Desktop\wcf.codeplex.com\WCFWebApi\Http\Src\Microsoft.ApplicationServer.Http\Microsoft\ApplicationServer\Http\Dispatcher\OperationHandlerPipelineInfo.cs:line 99
   at Microsoft.ApplicationServer.Http.Dispatcher.OperationHandlerPipelineContext.GetInputValues() in C:\Users\howard\Desktop\wcf.codeplex.com\WCFWebApi\Http\Src\Microsoft.ApplicationServer.Http\Microsoft\ApplicationServer\Http\Dispatcher\OperationHandlerPipelineContext.cs:line 31
   at Microsoft.ApplicationServer.Http.Dispatcher.OperationHandlerPipeline.ExecuteRequestPipeline(HttpRequestMessage request, Object[] parameters) in C:\Users\howard\Desktop\wcf.codeplex.com\WCFWebApi\Http\Src\Microsoft.ApplicationServer.Http\Microsoft\ApplicationServer\Http\Dispatcher\OperationHandlerPipeline.cs:line 69
   at Microsoft.ApplicationServer.Http.Dispatcher.OperationHandlerFormatter.OnDeserializeRequest(HttpRequestMessage request, Object[] parameters) in C:\Users\howard\Desktop\wcf.codeplex.com\WCFWebApi\Http\Src\Microsoft.ApplicationServer.Http\Microsoft\ApplicationServer\Http\Dispatcher\OperationHandlerFormatter.cs:line 67
   at Microsoft.ApplicationServer.Http.Dispatcher.HttpMessageFormatter.DeserializeRequest(HttpRequestMessage request, Object[] parameters) in C:\Users\howard\Desktop\wcf.codeplex.com\WCFWebApi\Http\Src\Microsoft.ApplicationServer.Http\Microsoft\ApplicationServer\Http\Dispatcher\HttpMessageFormatter.cs:line 85
   at Microsoft.ApplicationServer.Http.Dispatcher.HttpMessageFormatter.System.ServiceModel.Dispatcher.IDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters) in C:\Users\howard\Desktop\wcf.codeplex.com\WCFWebApi\Http\Src\Microsoft.ApplicationServer.Http\Microsoft\ApplicationServer\Http\Dispatcher\HttpMessageFormatter.cs:line 41
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)

 

This is pretty much predictable behavior. The .png is not trimmed of and '1' is no int but a string containing '1.png', However, this is the wayI would expect it to work in an even more finished product.

To summarize, this is what I want, for you to decide if it's reasonable:

1. I instruct my formatter to which uri string or querystring parameter it must 'listen'.

2. Magically, a uri extension and query extension delagatinghandler is being added for me in run-time examining each of my incoming requests. It adjusts the request uri and adds the appropriate Accept header.

Thx,

Gerben.

Oct 26, 2011 at 7:32 AM

I hate to bump (though I realize I'm doing that anyway) but the problem in this thread is for me something that worked in 4 and not in 5. 

It seems to be better designed now but in our prototype project I've now lost the ability to do this: http://localhost/myimage.png even when I add my own UriExtensionHandler to the MessageHandlers collection.

But adding the UriExtensionHandler should not be needed because all indications are that in preview 5 this is sufficient:

        public ADPJSONFormatter()
        {
            this.AddUriPathExtensionMapping("json", "application/json");
            this.AddQueryStringMapping("format", "json", "application/json");

            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/json"));
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
        }

Can you take a look at this? Am I using it right? Or is it a bug?

Thx (again)

Gerben.