Unable to parse odata json responses containing root property "d" using wcf client services 5.3 generator
Asked Answered
E

1

0

I am starting this new thread as a continuation of comments in: Consume Odata Service and get result in JSON

The issue that I am facing is that I have upgraded to wcf data services 5.5 and wcf client tools 5.3 as recommended in the thread. And I am trying to perform a simple post to the following JayStorm service: https://open.jaystack.net/c72e6c4b-27ba-49bb-9321-e167ed03d00b/6494690e-1d5f-418d-adca-0ac515b7b742/api/mydatabase/

I generated the client service reference in .Net and am running the following code:

using Microsoft.Data.Edm;
using Microsoft.Data.Edm.Csdl;
using Microsoft.Data.Edm.Validation;
using Microsoft.Data.OData;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Spatial;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace AirportDBDataImporter
{
    class Program
    {
        static void Main(string[] args)
        {
            var url = "https://open.jaystack.net/c72e6c4b-27ba-49bb-9321-e167ed03d00b/6494690e-1d5f-418d-adca-0ac515b7b742/api/mydatabase/";
            var db = new AirportDB.mydatabaseService(new Uri(url));
            var xmlTextReader = new XmlTextReader(url+"$metadata");
            IEdmModel edmModel = null;
            IEnumerable<EdmError> errors = null;
            if (EdmxReader.TryParse(xmlTextReader, out edmModel, out errors))
            {

            }

            db.Format.UseJson(edmModel);

            //{"Name":"sfd","Abbrev":"sd","GeoLocation":{"type":"Point","coordinates":[-71.56236648559569,42.451074707889646],"crs":{"properties":{"name":"EPSG:4326"},"type":"name"}}}
            var airport = new AirportDB.Airport();
            airport.Abbrev = "Foo";
            airport.Name = "Bar";

            airport.GeoLocation = GeographyPoint.Create(51.87796, -176.64603);
            db.AddToAirport(airport);

            db.SaveChanges();

            //var foo = db.Airport.ToList();


        }
    }
}

The EdmxReader part is necessary because without it and with a no parameter UseJson() an exception is thrown because the service is not fully odata v3 compliant. With this approach SaveChanges() still throws an exception but the airport record is actually inserted in to the database and the returned information for the record (from JayStorm), because it contains the old school style root "d" property, causes a parse exception and the exception is thrown in the second part of the SaveChanges().

My question is: Is there anything I can do about this in order to fully complete the post to JayStorm? It seems not as the new wcf client no longer supports the old verbose json (which I think is where the "d" comes from?).

EDIT: Here is the POST raw data from fiddler:

POST https://open.jaystack.net/c72e6c4b-27ba-49bb-9321-e167ed03d00b/6494690e-1d5f-418d-adca-0ac515b7b742/api/mydatabase/Airport HTTP/1.1
DataServiceVersion: 3.0;NetFx
MaxDataServiceVersion: 3.0;NetFx
Content-Type: application/json;odata=minimalmetadata
Accept: application/json;odata=minimalmetadata
Accept-Charset: UTF-8
User-Agent: Microsoft ADO.NET Data Services
Host: open.jaystack.net
Content-Length: 196
Expect: 100-continue

{"odata.type":"mydatabase.Airport","Abbrev":"Foo","GeoLocation":{"type":"Point","coordinates":[-176.64603,51.87796],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}},"id":null,"Name":"Bar"}

Here is the response raw data from fiddler:

HTTP/1.1 201 Created
Server: nginx/1.4.1
Date: Fri, 21 Jun 2013 15:07:40 GMT
Content-Type: application/json;odata=verbose;charset=utf-8;charset=UTF-8
Content-Length: 574
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: open.jaystack.net
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type, MaxDataServiceVersion, DataServiceVersion, Authorization, X-Domain, X-Requested-With
Access-Control-Allow-Method: POST
Access-Control-Allow-Methods: OPTIONS, GET, HEAD, POST, MERGE, PATCH, DELETE, PUT
Access-Control-Allow-Credentials: true
location: https://open.jaystack.net/c72e6c4b-27ba-49bb-9321-e167ed03d00b/6494690e-1d5f-418d-adca-0ac515b7b742/api/mydatabase/Airport('NTFjNDZjM2MyMjg1Y2FiNjMzMDAwMDAx')
Set-Cookie: connect.sid=s%3AvwHQXjoJQO3VUxJdE2jrQ3ja.A4tG9Bv4XTg1gS5xAVgxMyWXJYrV6DULf3xWvj1Uhq8; Path=/; HttpOnly

{"d":{"__metadata":{"type":"mydatabase.Airport","id":"https://open.jaystack.net/c72e6c4b-27ba-49bb-9321-e167ed03d00b/6494690e-1d5f-418d-adca-0ac515b7b742/api/mydatabase/Airport('NTFjNDZjM2MyMjg1Y2FiNjMzMDAwMDAx')","uri":"https://open.jaystack.net/c72e6c4b-27ba-49bb-9321-e167ed03d00b/6494690e-1d5f-418d-adca-0ac515b7b742/api/mydatabase/Airport('NTFjNDZjM2MyMjg1Y2FiNjMzMDAwMDAx')"},"Name":"Bar","Abbrev":"Foo","GeoLocation":{"type":"Point","coordinates":[-176.64603,51.87796],"crs":{"properties":{"name":"EPSG:4326"},"type":"name"}},"id":"NTFjNDZjM2MyMjg1Y2FiNjMzMDAwMDAx"}}

Thanks

Eruption answered 21/6, 2013 at 12:22 Comment(2)
My guess would be that the service responds with either wrong or no DataServiceVersion and Content-Type headers. But to confirm that, could you please grab the response from the service including HTTP headers and post it here?Revareval
I edited the question inline to include the post request and response raw data including headers.Eruption
A
0

As discussed in the comments of the other thread, your server does not support V3 of OData, and it also doesn't seem to be failing appropriately when you request the new JSON format. In the request payload, you're saying that you only understand application/json;odata=minimalmetadata, but the server is ignoring the odata=minimalmetadata constraint and is responding with application/json;odata=verbose anyway.

Are you in control of the server? I would look into how that can be upgraded to work with v3 of OData.

As you already pointed out, the WCF Data Services client won't work with JSON Verbose. The problem is not just the "d" wrapper; there are tons of differences between the two formats, and the WCF DS Client simply can't understand the old format (and never has been able to).

If it's at all possible, I strongly recommend upgrading the server. If you can't upgrade the server, you can still use Atom with the WCF Data Services client and a v2 server. It'll mean more bytes on the wire, but if reducing payload size on the wire is something you're concerned about, that's even more reason to upgrade the server and use the new JSON format, which is much more concise than the old format.

Antineutrino answered 23/6, 2013 at 3:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.