1

I am brand new to C# after working with PHP and Javascript for years and struggling with the arrays / lists.

I realize C# is a strongly typed language, but am still learning what that means. I am surprised there is no equivalent to PHP's print_r(), or var_dump() which I have always used extensively in development to verify things got the right values at the right time.

I am hitting some endpoints that return JSON from a URL shortener that looks like this:

[
 {
 "key": "WcoUC",
 "url": "https://www.shorty.com/WcoUC",
 "clicks": 17,
 "expires": "2017-12-22 15:30:00",
 "created_at": "2017-12-18 22:44:54",
 "updated_at": "2017-12-18 22:44:54",
 "redirect_to": "http://www.example2.com/"
 }
]

In my c# I have this method:

private static string start_get()
 {
 HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(string.Format("https://www.shorty.com/api/v1/urls"));
 WebReq.ContentType = "application/json; charset=utf-8";
 WebReq.Headers["Authorization"] = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOi7w8VePMIh5i3pZ-S329KifQ9TbWHfsqMfV-HXmhej_9KcQRReIbytrILzyopoXY7p7kKN6ZnZTrFO9P9-1y3ohFJCBxZXvW_iwbA9hsVTj9ZtFbJGxaaIlUZa19knuDirQ";
 WebReq.PreAuthenticate = true;
 HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
 Console.WriteLine(WebResp.StatusCode);
 Console.WriteLine(WebResp.Server);
 string jsonString;
 using (Stream stream = WebResp.GetResponseStream())
 {
 StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8);
 jsonString = reader.ReadToEnd();
 }
 List<Item> items = JsonConvert.DeserializeObject<List<Item>>(jsonString);
 return jsonString;
 }

With it's associated class:

public class Item
{
 public string key { get; set; }
 public string url { get; set; }
 public int clicks { get; set; }
 public string expires { get; set; }
 public string created_at { get; set; }
 public string updated_at { get; set; }
 public string redirect_to { get; set; }
}

This is all working, but I am a little confused about why I have to setup a class to access each item in the JSON. My concern is that if the API gets updated with new items, they won't show up. So for example, let's say there was a new key:value added of "referring_url":"http://www.stackoverflow.com". When I dump the value of item I won't see that there. I am so used to javascript where it would just be item.referring_url and could have as many nested objects as it wanted to have without needing to define every little part.

Is it possible during this declaration

List<Item> items = JsonConvert.DeserializeObject<List<Item>>(jsonString);

to automatically assign everything it knows how to from the class I defined, but then assign the leftover to something that gets logged to the console or something so I know to handle it?

Is there a better method that will autocreate the classes in a more familiar way to someone transitioning from javascript?

Daniel A. White
192k49 gold badges386 silver badges472 bronze badges
asked Jan 3, 2018 at 18:12
3
  • 1
    Consider looking into JsonSerializerSettings with MissingMemberHandling.Ignore, and a version with MissingMemberHandling.Error. With the latter, you can dump out any new objects found in the deserialization that are not yet covered in your existing class. I use a release version to ignore, and a debug version to dump the new fields, but that's just my own implementation. Commented Jan 3, 2018 at 18:18
  • Assigning to a predefined class is a good, option if you can guarantee the structure. Otherwise you may want to dump your Json into something more generalized that you can handle. Look into a c# Tuple msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx. Commented Jan 3, 2018 at 18:26
  • BTW, the issue you have is not really about c# being Strongly Typed (it's not, in the strict sense)blogs.msdn.microsoft.com/ericlippert/2012/10/15/… It's about the structure of your JSON wich is really just a string as far as c# is concerned. Commented Jan 3, 2018 at 18:29

5 Answers 5

1

JSON.Net has a way to receive errors from the process. Specify an Error delegate in the JsonSeralizerSettings. Read about it here.

answered Jan 3, 2018 at 18:16

Comments

1

You could choose to use Json.Net's Linq-to-Json API instead of writing classes. Then, all parts of the JSON will be available, similar to JavaScript. For example:

string json = @"
 [
 {
 ""key"": ""WcoUC"",
 ""url"": ""https://www.shorty.com/WcoUC"",
 ""clicks"": 17,
 ""expires"": ""2017-12-22 15:30:00"",
 ""created_at"": ""2017-12-18 22:44:54"",
 ""updated_at"": ""2017-12-18 22:44:54"",
 ""redirect_to"": ""http://www.example2.com/""
 }
 ]";
JArray array = JArray.Parse(json);
foreach (JObject obj in array.Children<JObject>())
{
 foreach (JProperty prop in obj.Properties())
 {
 Console.WriteLine(prop.Name + ": " + prop.Value.ToString()); 
 }
 Console.WriteLine();
}

Fiddle: https://dotnetfiddle.net/xyZvdO

answered Jan 3, 2018 at 18:31

Comments

1

First go first: Use System.Net.Http.HttpClient

When I usually request something to an API is because I need something and the API offers that to me... among a lot of other things I dont need. Hence, I only care about what I need, not about eveything it offers.

Anyway, if you need to know or log the raw content that is returned by the API, you simple get System.Net.HttpContent.ReadAsStringAsync().

PS: Thanks to attributes like JsonProperty, you can focus on what you need and how you need the entity to be

answered Jan 3, 2018 at 18:27

Comments

0

If you accept the losting intellisense, you can deserialize it a dictionary or dynamic;

string json = @"{'key' : 'k', 'url' : 'u', 'clicks' : 'c' }";
var keys = JObject.Parse(json).Properties();
//Dictionary
var keysDict = keys
 .ToDictionary(
 k => k.Name,
 v => v.Value.ToString());
//Dynamic
var dynamicObject = JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine(dynamicObject.key);
answered Jan 3, 2018 at 18:27

Comments

0

The application I am building is a Windows Form, so Console.Write that is part of so many tutorials / examples was not much help, but I configured a multiline textbox named DebugBoxTest and in the Form1.cs placed:

public void DebugBoxUpdate(string incomingString)
{
 JArray array = JArray.Parse(incomingString);
 DebugBoxTest.Text = JsonConvert.SerializeObject(array, Formatting.Indented);
}

Now I can dump formatted things into it using something like this from the Main area:

string results = start_get();
ThisForm.DebugBoxUpdate(results);

I know there are a lot of ways to skin a cat, and I am too new to properly upvote answers, but will accept whichever is at the top based off others feedback.

In the future I may augment this debug box into a button activated popout window with error handling for multiple data types, but this gets me started.

answered Jan 3, 2018 at 19:57

3 Comments

Just FYI, you only need 15 rep to upvote questions and answers. You currently have 521 rep. See Help Center -> Privileges
Also, you can dump the contents of the JArray as formatted JSON using array.ToString(). It is a little shorter than using JsonConvert.SerializeObject(array, Formatting.Indented).
Thanks Brian, I meant that from the 5 solutions, I don't know which is the "best" to vote on / accept. I know what worked for me, but it was kinda a combination effort. So to help the next user, I figured I would let more experienced .NET developers do the voting. I am using more of your solution than anyone else's at the moment though :)

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.