Skip to content

Missing Callback Exception #28

@gbd77rc

Description

@gbd77rc

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...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions