Json with a strange name field cannot be parsed - c#

I have this JSON container that has a strange field called "48x48" for a photoUrl.
using Newtonsoft.Json;
(...)
dynamic issuesJson = JsonConvert.DeserializeObject(responseIssues.Content);
foreach (dynamic issue in issuesJson.issues){
Console.WriteLine(issue.name); //works properly
Console.WriteLine(issue.48x48); //error -> expected;
}
For some reason Visual Studio doesn't accept the access to this runtime field of this dynamic object. How can I work around this problem?
Note: I cannot change the field name.
Thanks anyway.

For some reason Visual Studio doesn't accept the access to this runtime field of this dynamic object.
Well what you've provided is simply not valid C#. An identifier can't start with a digit. That's still enforced even when you're trying to resolve a member of dynamic.
We don't know what type you're using for issues, but basically you'll need to handle it as a key/value map which you can access by string. Quite how you do that will depend on the implementation of issue. It doesn't look like Json.NET guarantees anything there - you may be able to cast it to JObject, for example:
foreach (JObject issue in issuesJson.issues) {
Console.WriteLine(issue["48x48"]);
}

Field names cannot start with a number. Sorry, no way around it.
You'll have to consult the documentation of your deserializer to see how it takes care of cases like that. It may be as simple as renaming the field "_48x48".

EDIT: actually, based on your code, you probably don't have a class representing this JSON object; I'm leaving my answer anyway, in case it helps someone else.
As others have mentioned, a C# identifier can't start with a digit. You just need to rename 48x48 to a valid name in your class, and map it to the actual JSON name using the [JsonProperty] attribute:
[JsonProperty("48x48")]
public string _48x48 { get; set; }

Related

C# Dynamic List Class

I have a bit of a weird issue. Working in C# script with SSIS I have developed a need to build a List based off Dynamic Data.
Background
To explain it, a script task is fired that has a variable API URL, this goes off and pulls a JSON string back and then throws it into a strongly typed list using the following code.
var listobject = get_APIData<ApplicationOneDataSet>(url)
The class that does this is long winded and not really needed in the context of this issue.
ApplicationOneDataSet is a strongly typed match to one of the possible JSON results returned by get_APIData.
Now I have a need to change ApplicationOneDataSet to ApplicationTwoDataSet dynamically based on which API URL I pass to the script.
So what I have done is send through a second variable to the script called class name which contains the string "ApplicationDataSetOne" or "ApplicationDataSetTwo" based on which context I call it under.
The Question
My question is how can I dynamically vary this line:
var listobject = get_APIData<ApplicationOneDataSet>(url)
With the string variable passed into the script.
My original thinking was something along the lines of this:
var ClassType = (string) Dts.Variables["AppClassName"].Value;
Type type = Type.GetType(ClassType);
var listobject = get_APIData<type>(url)
Though it doesn't seem to like that. Any tips would be great!
As long as there is exactly two types you can use and you know them at compile time, I would not look further than a simple if. It works, it's easy, everyone understands it.
You can do it totally dynamic at runtime, but that's a huge pain in the... where you don't want it to be. If you really want to go down that rabbit hole, you can find more information here.
I'm not sure I fully understood what you are trying to do, but how about writing an interface ApplicationDataSet and then making a list of it? This way your list is going to be able to contain both types of data.

Deserializing JSON object to runtime type in WinRT (C#)

I have a small WinRT client app to my online service (Azure Web Service). The server sends a JSON encoded object with (with potential additional metadata) to the client and the client's responsibility would be to deserialize this data properly into classes and forward it to appropriate handlers.
Currently, the objects received can be deserialized with a simple
TodoItem todo = JsonConvert.DeserializeObject<TodoItem>(message.Content);
However, there can be multiple types of items received. So what I am currently thinking is this:
I include the type info in the header serverside, such as "Content-Object: TodoItem"
I define attributes to TodoItem on the client side (see below)
Upon receiving a message from the server, I find the class using the attribute I defined.
I call the deserialization method with the resolved type
(Example of the attribute mentioned in 2.)
[BackendObjectType="TodoItem"]
public class TodoItem
My problem with this approach however is the Type to Generics in the deserialization as I can't call:
Type t = ResolveType(message);
JsonConvert.DeserializeObject<t>(message.Content);
I tried finding some solutions to this and getting method info for the DeserializeObject and calling it using reflection seemed to be the way to go. However, GetMethod() does not exist in WinRT and I was not able to find an alternative I could use to retrieve the generic version of the DeserializeObject (as fetching by the name gives me the non-generic overload). I don't mind using reflection and GetMethod as I can cache (?) the methods and call them every time a message is received without having to resolve it every time.
So how do I achieve the latter part and/or is there another way to approach this?
Alright, I feel like this was not really a problem at all to begin with as I discovered the DeserializeObject(string, Type, JsonSerializerSettings) overload for the method. It works splendidly. However, I would still like to hear some feedback on the approach. Do you think using attributes as a way to resolve the type names is reasonable or are there better ways? I don't want to use the class names directly though, because I don't want to risk any sort of man-in-the-middle things be able to initialize whatever.
Just a few minutes ago we have posted the alternative way to do what you want. Please look here, if you will have any questions feel free to ask:
Prblem in Deserialization of JSON
Try this
http://json2csharp.com/
Put your Json string here it will generate a class
then
public static T DeserializeFromJson<T>(string json)
{
T deserializedProduct = JsonConvert.DeserializeObject<T>(json);
return deserializedProduct;
}
var container = DeserializeFromJson<ClassName>(JsonString);

How to rename and remap fields with illegal json field names

I have used json2csharp to produce some nice c# class into which I can deserialize json.
It is actually working as expected EXCEPT that json2csharp named some of the fields invalid_name . I renamed those to valid csharp names but when serialized those class are null.
I found this other SO post... where one of the answerers said the following...
Keep in mind the class I have pasted below will not work directly,
because of the naming of some of the fields in the json. You may have
to rename them manually and map them.
This exactly describes my problem. Unfortunately, the answer gives no clues on actually HOW to "map them." So can someone tell me how to manually map some json arrays to c# classes.
I am using RestSharp deserializers, btw.
Any ideas?
If you are using JSON.NET as the basis or JSON parsing, you can rename your properties and then decorate them with attributes to align them back to the original JSON object.
An example is a property in JSON called 1 which is invalid in C#. This can be corrected using the following:
[JsonProperty("1")]
public int? One { get; set; }
There is also a JsonObject attribute if you want to edit at the class level, and also a JsonIgnore object to ignore serialisation of properties.

Deserialize the EventValidation object

I am trying to serialize and deserialize the event validation store. I have used code on MSDN to do the same with the viewstate. I cannot seem to get the data out of the EventValidation object.
System.Web.UI.LosFormatter los = new System.Web.UI.LosFormatter();
var t = los.Deserialize("/wEdAAXD48AAvF6Ff7P5UOQbT3VqkrDKlMWdnNXfGOHHYL4xn7VF+rYDddmo2pWyOYlEzR9ytSa0+vS8Kw5xkFTTwf/ogY5mU3PIFIVTnINRkldVDi8fjE6FJuo5OYrccfM1phFxAalSeL3MjHSQK44wYPDs")
HashSet<object> h = new HashSet<object>();
foreach (object d in t)
{
DoSomething()
}
System.Web.UI.EventValidationStore is the object type (?)
I have tried to use a hash set, a list, etc. I am new to this, and it is was out of what I know how do do, but would love to learn it.
The error I get is: "foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public definition for 'GetEnumerator'"
I could not find anything on MSDN about the System.Web.UI.EventValidationStore.
I apologize if this is a confusing post, I am just not sure how to ask it.
Update: I successfully deserialized one EventValidation base64 string, but others are proving to be elusive. The one in the code segment does not seem to work.
Summary:
I need to be able to decode/deserialize and encode/serialize the eventvalidation base64 string in .NET.
The __EVENTVALIDATION field structure is internal to ASP.NET and is subject to change. Trying to deserialize / serialize it is unsupported. The supported ways of interacting with it are via the Page's ValidateEvent and RegisterForEventValidation APIs.
What exactly are you trying to accomplish? Perhaps we can find a supported way of doing it.

Deserialize to type whose namespace has changed

Using .NET 4/C#...
I need to deserialize old config files that contain the serialized representation of a type named, say, ns1.X . The serialization has been done using BinaryFormatter.
The problem is, after a round of refactoring, the type X has been moved to a different namespace, say ns2.X .
I have tried creating a new empty ns1.X type that derives from ns2.X, and while this circumvents the 'Can't find type ns1.X' error, the properties in the deserialized object are all null. Also, no ctors get called in the process.
Any suggestions?
You're going to need to use an ISerializationSurregate to make this happen. It's not too difficult and Jeff Richter explains it really well. I recommend his book CLR Via c# 3.

Categories