-
Notifications
You must be signed in to change notification settings - Fork 45
Description
Hi,
If I have an ODATA (EntitySetController) endpoint that I want to switch between JSONP and JSON via ACCEPT header (application/json-p or application/odata), this formatter will throw an exception complaining about a missing callback parameter.
The issue happens in the GetPerRequestFormatterInstance method. It seems that the content negotiation is happening and this method get called before the check for supported media types. I could be wrong here, but from debugging the source code this seems to be what is happening. I am using Visual Studio 2013, with ODATA 5.6.1 assemblies.
For my own issue I have modified the code in three places.
In the GetPerRequestFormatterInstance
string callback;
// Check if we do have callback and therefore really what jsonp
if (IsJsonpRequest(request, _callbackQueryParameter, out callback))
{
return new JsonpMediaTypeFormatter(request, callback, _jsonMediaTypeFormatter, _callbackQueryParameter);
}
else
{
// Check if we really want ODATA and therefore need to continue
// and test the supported media types.
if (type.GetInterfaces().Contains(typeof(IQueryable)))
{
return new JsonpMediaTypeFormatter(request, _jsonMediaTypeFormatter, _callbackQueryParameter);
}
}
In the CanWriteType method I check if we can write the type back, if it is a ODATA request and the ACCEPT header is "application/odata" then just return false.
var accepttype = false;
//Get the accept header.
if ( _request != null )
{
accepttype = _request.Headers.Accept.Any(a => a.MediaType.ToLower() == "application/odata");
}
// Check for ODATA
if ( type.GetInterfaces().Contains(typeof(IQueryable))
&& accepttype )
{
return false;
}
Added a new constructor so we can have a default value for the callback, but to be honest I don't think it is required.
private JsonpMediaTypeFormatter(HttpRequestMessage request, MediaTypeFormatter jsonMediaTypeFormatter, string callbackQueryParameter)
: this(jsonMediaTypeFormatter, callbackQueryParameter)
{
if (request == null)
{
throw new ArgumentNullException("request");
}
_request = request;
_callback = "foobar";
}
I have not forked or submitted these changes as I don't think they will be suitable for everyone. I just wanted you to know that someone else may run into this issue if they have a mix of standard webapi endpoints and EntitySetController endpoints in their service and need to have JSONP as well. Normally I use CORS but I have been told I need to support IE 8 now :(, hence the reason for JSONP.
Regards
Richard...