• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1443
  • Last Modified:

c# consume json webservice and turn it into a list

I have found a lot of examples of creating a web service in C# to return a json representation of a list.  I want to do the opposite.  I have a json webservice that I would like to consume in my application and turn it into a list so that I can work with it.
0
jackjohnson44
Asked:
jackjohnson44
1 Solution
 
RobOwner (Aidellio)Commented:
What language are you working in? ajax or c#?
0
 
PryratesCommented:
Have a look here:
http://www.codeproject.com/KB/webservices/ConsumeJson.aspx
A lot of useful hints, tips and tricks. Links where you can find class-generators for deserializing json structures to c# classes. and a working sample.

A Javascript Serializer / json.net might be helpful as well:
http://stackoverflow.com/questions/401756/parsing-json-using-json-net
http://stackoverflow.com/questions/2071097/call-external-json-webservice-from-asp-net-c-sharp
 
Hope that helps.
0
 
Bob LearnedCommented:
JSON Deserialization into a class structure, and LINQ would be a place to look.  .NET 3.5 or higher has the DataContractJsonSerializer natively.  Older versions have a different JSON serializer.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
jackjohnson44Author Commented:
Thanks, but I can't figure this out at all.  I made this function below.  I am getting the error below on the ReadObject call.

The file that I am trying to deserialize is the output from a json web service.  I went to the url directly and saved the output to the file.  Basically it is a dictionary object with parametes,and the last parameter being an array.  I will post the file below.


FUNCTION:
private static Dictionary<string, string> DeSerializeObject(string filename)
{
    Dictionary<string, string> objectToSerialize;
    Stream stream = File.Open(filename, FileMode.Open);
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Dictionary<string, string>));
    Dictionary<string, string> deserialized = (Dictionary<string, string>)ser.ReadObject(stream);
    stream.Close();
    return deserialized;
}


ERROR:
System.Runtime.Serialization.SerializationException was unhandled
  Message=Expecting state 'Element'.. Encountered 'Text'  with name '', namespace ''.
  Source=System.Runtime.Serialization
  StackTrace:
       at ReadArrayOfKeyValueOfstringstringFromJson(XmlReaderDelegator , XmlObjectSerializerReadContextComplexJson , XmlDictionaryString , XmlDictionaryString , CollectionDataContract )
       at System.Runtime.Serialization.Json.JsonCollectionDataContract.ReadJsonValueCore(XmlReaderDelegator jsonReader, XmlObjectSerializerReadContextComplexJson context)
GetLocationSelectorGridData.txt
0
 
Bob LearnedCommented:
How does the JSON text compare to the class structure, and the data contract?
0
 
jackjohnson44Author Commented:
The data contract is dictionary<string, string>

The last element is in the dictionary called rows is another array of dictionary objects.
From the example I attached:

totalpages=2
currpage=1
totalrecords=1012
filteredrecords=None
recordcount=1012
rows=
Array or dictionary ojbects
{GroupByDesc=
Name=The Name<br> 2701 Ming Avenue
Address=2701 Ming Avenue
City=Bakersfield
State=California
Country=United States of America
IndexRecordNum=null
LatestInspDate=
CbiId=277605}
etc....
0
 
Bob LearnedCommented:
Was the JSON string created by something other than the DataContractJsonSerializer?
0
 
jackjohnson44Author Commented:
I really don't know and can't change the output.  I went to the url directly using firefox and saved the file which I posted above.  That is all that I have.  It seems pretty simple, there is just a dictionary and array.
0
 
Bob LearnedCommented:
Can you show me an example of the JSON string that you are working with, please?
0
 
jackjohnson44Author Commented:
Yes, I attached the file in my second comment, please look above and click the file.
This is the exact output from hitting the web service directly from the url.  I went to the url and a save dialogue pop-ed up and I saved the output.
0
 
Bob LearnedCommented:
If I look at this representation of a subset of JSON string, I can see this:

{
    "totalpages": "2",
    "currpage": "1",
    "totalrecords": "1012",
    "filteredrecords": "None",
    "recordcount": "1012",
    "rows": [
        {
            "GroupByDesc": "",
            "Name": "The Name<br> 2701 Ming Avenue",
            "Address": "2701 Ming Avenue",
            "City": "Bakersfield",
            "State": "California",
            "Country": "United States of America",
            "IndexRecordNum": null,
            "LatestInspDate": "",
            "CbiId": "277605"
        },
        {
            "GroupByDesc": "",
            "Name": "The Name<br> 1233 W Avenue P",
            "Address": "1233 W Avenue P",
            "City": "Palmdale",
            "State": "California",
            "Country": "United States of America",
            "IndexRecordNum": null,
            "LatestInspDate": "",
            "CbiId": "277607"
        }
    ]
}

Open in new window


I would have a different data contract like this:

public class GroupBy
{
  [DataMember]
  public string GroupByDesc { get; set; }
  [DataMember]
  public string Name { get; set; }
  [DataMember]
  public string Address { get; set; }
  [DataMember]
  public string City { get; set; }
  [DataMember]
  public string State { get; set; }
  [DataMember]
  public string Country { get; set; }
  [DataMember]
  public string IndexRecordNum { get; set; }
  [DataMember]
  public string LatestInspDate { get; set; }
  [DataMember]
  public string CbiId { get; set; }
}

Open in new window

0
 
jackjohnson44Author Commented:
Thanks, but I'm not sure if I am being clear with my question.

I have the file that is attached.  I can't change it.  I need to turn that into a C# object.
0
 
Bob LearnedCommented:
Were you able to find a solution?  My previous post was showing a partial example of a different class that you could use to deserialize the JSON text.  You need to find a class structure that matches that JSON representation.  Dictionary<string, string> didn't sound like a good match.
0
 
jackjohnson44Author Commented:
Thanks for checking back.  I posted a similar question which was more narrowly focused because I think that this qustion was too leading.  Instead of focusing on web services and json, I just said I have a string as input and need a dictionary<string, string> returned.  The input that I have is a black box and I have no way to change it, view code, look at contracts, so I tried to take that out of the question.  http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_27423543.html
0
 
Bob LearnedCommented:
Rather than pollute another question, can you describe why you need a Dictionary<string, string> of elements?
0
 
jackjohnson44Author Commented:
Sorry for polluting another question.  In my experience, once a question gets too long, it doesn't get answered.  I really, really need this answered.  I believe it is because I wasn't clear.

I am working with a team and my requirements are extremely strict.  I need to create a function that returns a dictionary, and the input is a string.  There is no room to change this in any way.  I need a function with this signature.  Any solution that does not address this will not work for me.  Other functionality was already written with Dictionary<string, string> as input using sample data.

private static Dictionary<string, string> DoSomethign(string myInputString)

Again, I have no flexibility.

Thanks for your help.
0
 
Bob LearnedCommented:
No problem from my side, but remember that I usually try to stick to a question, no matter how long it gets.  I am not questioning your requirements, just trying to understand them.  If you have a list of business objects, you can turn that into a dictionary with a Lambda expression with the ToDictionary operator.

Here is an example using a Lambda expression with DataSet extensions:

var dictionary = db
    .Table
    .Select(p => new { p.Key, p.Value })
    .AsEnumerable()
    .ToDictionary(kvp => kvp.Key, kvp => kvp.Value)

Open in new window


"There are many ways to skin a cat"
0
 
jackjohnson44Author Commented:
Thanks, I appreciate your help, but again, this is my requirement:

private static Dictionary<string, string> DoSomethign(string myInputString (example in file above))

I really don't have the knowledge to make that work from your answer.

Thanks again for your help.  I hope this isn't coming across negatively.  I just don't think I am being clear at all.   Feel free to abandon this discussion, I don't think we are getting anywhere.

Have a good one!



0
 
Bob LearnedCommented:
You are having errors with the JSON deserialization, since it doesn't meet the contract defined by Dictionary<string, string>, and I don't believe that you will have success with your current course.  I wish you all the best of luck getting an answer.  If you would like to experiment with a different process, I would be willing to try to help.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now