Deserialize json c# with CRM 365 API - c#

So, I've made classes like this:
public class Values
{
public string odata_context { get; set; }
public List<ContactsDeserialize> keyValues { get; set; }
}
public class ContactsDeserialize : IDisposable
{
public string odata_etag { get; set; }
public Guid contactid { get; set; }
public string crimson_title { get; set; }
public string firstname { get; set; }
public string lastname { get; set; }
public DateTime? createdon { get; set; }
public DateTime? birthdate { get; set; }
public string emailaddress1 { get; set; }
public string mobilephone { get; set; }
public string address1_line1 { get; set; }
public string address1_line2 { get; set; }
public string address1_line3 { get; set; }
public string address1_city { get; set; }
public string address1_postalcode { get; set; }
public string address1_telephone1 { get; set; }
}
but when I try to deserialise
this by using
Values ContactData = JsonConvert.DeserializeObject<Values>(jsonstring);
it's return null.
Can not find out the reason
Thanks

Your class fields a little bit differ to original json fields, so if you want to use this you need to put attributes to your fields to provide correct json fields i.e
[JsonProperty("#odata.etag")]
public string odata_etag { get; set; }
for more details see the documentation article

Could be that you need to intialise the keyValues list in a constructor.
public class Values
{
public Values()
{
keyValues = new List<ContactsDeserialize>();
}
public string odata_context {get; set; }
public List<ContactsDeserialize> keyValues { get; set; }
}
Alos the names of you objects should match exactly what the json return unless you define what it maps to in an attribute. Both odata_context and keyValues are named slightly different to how they are returned in the json.

You declare public List<ContactsDeserialize> keyValues { get; set; } in Class Values,but the node of your json is value.

Related

C# deserialize with special characters like $

Hello I have one json text inside this text there is one key which starts with $
string jsonText="{\"Version\":\"1.1\",\"Documents\":[{\"DocumentState\":\"Correct\",\"DocumentData\":{\"Name\":\"test\",\"$type\":\"Document\",\"Fields\":[{\"Name\":\"CustomerFullName\",\"$type\":\"Text\",\"SuspiciousSymbols\":\"0\",\"RecognizedValue\":\"\",\"Value\":\"\"},{\"Name\":\"CustomerBirthDate\",\"$type\":\"Text\",\"Value\":\"\"},{\"Name\":\"DocumentNumber\",\"$type\":\"Text\",\"SuspiciousSymbols\":\"0000000000\",\"RecognizedValue\":\"\",\"Value\":\"\"},{\"Name\":\"CustomerIsMarried\",\"$type\":\"Checkmark\",\"IsSuspicious\":false,\"Value\":true},{\"Name\":\"CustomerCounty\",\"$type\":\"Text\",\"Value\":\"\"},{\"Name\":\"CustomerArea\",\"$type\":\"Text\",\"Value\":\"\"},{\"Name\":\"CustomerAddress\",\"$type\":\"Text\",\"SuspiciousSymbols\":\"11000000\",\"RecognizedValue\":\"\",\"Value\":\"\"},{\"Name\":\"DocumentGUID\",\"$type\":\"Text\",\"Value\":\"\"},{\"Name\":\"DocumentProposalID\",\"$type\":\"Text\",\"Value\":\"\"},{\"Name\":\"DocumentCountry\",\"$type\":\"Text\",\"SuspiciousSymbols\":\"000\",\"RecognizedValue\":\"FRA\",\"Value\":\"FRA\"},{\"Name\":\"DocumentCurrency\",\"$type\":\"Text\",\"SuspiciousSymbols\":\"000\",\"RecognizedValue\":\"EUR\",\"Value\":\"EUR\"},{\"Name\":\"DocumentTo\",\"$type\":\"Text\",\"Value\":\"\"},{\"Name\":\"DocumentFrom\",\"$type\":\"Text\",\"Value\":\"\"},{\"Name\":\"DocumentTotalNumberOfPages\",\"$type\":\"Text\",\"SuspiciousSymbols\":\"0\",\"RecognizedValue\":\"1\",\"Value\":\"1\"}]}}]}";
Console.WriteLine(jsonText);
var documentResult = JsonConvert.DeserializeObject<DocumentDTO>(jsonText);
and my class objects are below
public class DocumentDTO
{
public string Version { get; set; }
public List<DocumentInfo> Documents { get; set; }
}
public class DocumentInfo
{
public string DocumentState { get; set; }
public DocumentData DocumentData { get; set; }
public string DocumentAsBase64 { get; set; }
}
public class DocumentData
{
public string Name { get; set; }
[JsonPropertyName("$type")]
public string type { get; set; }
public List<DocumentField> Fields { get; set; }
}
public class DocumentField
{
public string Name { get; set; }
[JsonPropertyName("$type")]
public string type { get; set; }
public string SuspiciousSymbols { get; set; }
public string RecognizedValue { get; set; }
public string Value { get; set; }
}
but it is not working not converting $type to type. How can I solve this problem ?
Thanks in advance
Kind Regards
That's because you're using JsonConvert from Newtonsoft.Json library and are marking property with JsonPropertyName attribute from System.Text.Json.Serialization. The two just don't play well together. Try replacing your JsonPropertyName with JsonProperty attribute from Newtonsoft.Json and it should work.
public class DocumentData
{
public string Name { get; set; }
[JsonProperty("$type")]
public string Type { get; set; }
public List<DocumentField> Fields { get; set; }
}
public class DocumentField
{
public string Name { get; set; }
[JsonProperty("$type")]
public string Type { get; set; }
public string SuspiciousSymbols { get; set; }
public string RecognizedValue { get; set; }
public string Value { get; set; }
}

REST Api returning different object names for the same object, how to handle with RestSharp?

I'm programming a C# implementation for the Qualtrics API (v 2.5) using RestSharp. When calling the method getUserIds, it returns a list of users in JSON format (see the example output below).
The problem/question I face is that for each user object (the list of objects under Result) it generates a different id, starting with URH_. When using json2csharp it assumes ofcourse that it's always a different class, while in fact it's absolutely the same one as you can see in the output, and as is stated in the documentation of the api. How can I best resolve this - so that I can make a class UserData that I can reuse? Because now I obviously always see these random URH_ prefixed classes in each response.
NOTE: I was thinking I could try to massage the response first, and when I get the response replace each URH_ prefixed object under the root Result object with a "UserData" string - but I feel this is breaking the rules a bit, and thought the community would have a better solution?
Below is the raw JSON output (note that I removed sensitive information):
{"Meta":{"Status":"Success","Debug":""},"Result":{"URH_3wpA9pxGbE0c7Xu":{"DivisionID":null,"UserName":"user.name#domain.com","UserFirstName":"x","UserLastName":"x","UserAccountType":"UT_4SjjZmbPphZGKDq","UserEmail":"x.x#x.x","UserAccountStatus":"Active"},"URH_57vQr8MVXgpcPUo":{"DivisionID":"DV_XXXXXXXX","UserName":"jxxxx#xx.xxx","UserFirstName":"X","UserLastName":"X","UserAccountType":"UT_BRANDADMIN","UserEmail":"xxxx#xxg.xxx","UserAccountStatus":"Active"},"URH_6ujW1EP0QJOUaoI":{"DivisionID":"DV_XXXXXXXYZ","UserName":"x.xckx#xxx.xyz","UserFirstName":"x","UserLastName":"x","UserAccountType":"UT_XXXXXABCD","UserEmail":"c.c#cc.com","UserAccountStatus":"Active"}}}
This is what I get when generating a model using json2csharp:
public class Meta
{
public string Status { get; set; }
public string Debug { get; set; }
}
public class URH3wpA9pxGbE0c7Xu
{
public object DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}
public class URH57vQr8MVXgpcPUo
{
public string DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}
public class URH6ujW1EP0QJOUaoI
{
public string DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}
public class Result
{
public URH3wpA9pxGbE0c7Xu URH_3wpA9pxGbE0c7Xu { get; set; }
public URH57vQr8MVXgpcPUo URH_57vQr8MVXgpcPUo { get; set; }
public URH6ujW1EP0QJOUaoI URH_6ujW1EP0QJOUaoI { get; set; }
}
public class RootObject
{
public Meta Meta { get; set; }
public Result Result { get; set; }
}
It's simple - just use Dictionary<string, UserData> generic type for Result field:
public class Response
{
public Meta Meta { get; set; }
public Dictionary<string, UserData> Result { get; set; }
}
public class Meta
{
public string Status { get; set; }
public string Debug { get; set; }
}
public class UserData
{
public string DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}

Object reference error while reading specific JSON string?

I have used JSON to C# Class Converter and it generates the following Class:
JSON
{"ios_info":{"serialNumber":"F2LLMBNJFFF","imeiNumber":"01388400413235","meid":"","iccID":"8901410427640096045","firstUnbrickDate":"11\/27\/13","lastUnbrickDate":"11\/27\/13","unbricked":"true","unlocked":"false","productVersion":"7.1.2","initialActivationPolicyID":"23","initialActivationPolicyDetails":"US AT&T Puerto Rico and US Virgin Islands Activation Policy","appliedActivationPolicyID":"23","appliedActivationDetails":"US AT&T Puerto Rico and US Virgin Islands Activation Policy","nextTetherPolicyID":"23","nextTetherPolicyDetails":"US AT&T Puerto Rico and US Virgin Islands Activation Policy","macAddress":"ACFDEC6C988A","bluetoothMacAddress":"AC:FD:EC:6C:98:8B","partDescription":"IPHONE 5S SPACE GRAY 64GB-USA"},"fmi":{"#attributes":{"version":"1","deviceCount":"1"},"fmipLockStatusDevice":{"#attributes":{"serial":"F2LLMBNJFFFQ","imei":"013884004132355","isLocked":"true","isLost":"false"}}},"product_info":{"serialNumber":"F2LLMBNJFFF","warrantyStatus":"Apple Limited Warranty","coverageEndDate":"11\/25\/14","coverageStartDate":"11\/26\/13","daysRemaining":"497","estimatedPurchaseDate":"11\/26\/13","purchaseCountry":"United States","registrationDate":"11\/26\/13","imageURL":"http:\/\/service.info.apple.com\/parts\/service_parts\/na.gif","explodedViewURL":"http:\/\/service.info.apple.com\/manuals-ssol.html","manualURL":"http:\/\/service.info.apple.com\/manuals-ssol.html","productDescription":"iPhone 5S","configDescription":"IPHONE 5S GRAY 64GB GSM","slaGroupDescription":"","contractCoverageEndDate":"11\/25\/15","contractCoverageStartDate":"11\/26\/13","contractType":"C1","laborCovered":"Y","limitedWarranty":"Y","partCovered":"Y","notes":"Covered by AppleCare+ - Incidents Available","acPlusFlag":"Y","consumerLawInfo":{"serviceType":"","popMandatory":"","allowedPartType":""}}}
From Above JSON all the data is read but only the line at which i get error is in reading the JSON is:
fmi":{"#attributes":{"version":"1","deviceCount":"1"},"fmipLockStatusDevice":{"#attributes":{"serial":"F2LLMBNJFFFQ","imei":"013884004132355","isLocked":"true","isLost":"false"}}},
Error:
Object Reference not set to an instance of object.
public class AppleAPI
{
public IosInfo ios_info { get; set; }
public ProductInfo product_info { get; set; }
public Fmi fmi { get; set; }
public class IosInfo
{
public string serialNumber { get; set; }
public string imeiNumber { get; set; }
public string meid { get; set; }
public string iccID { get; set; }
public string firstUnbrickDate { get; set; }
public string lastUnbrickDate { get; set; }
public string unbricked { get; set; }
public string unlocked { get; set; }
public string productVersion { get; set; }
public string initialActivationPolicyID { get; set; }
public string initialActivationPolicyDetails { get; set; }
public string appliedActivationPolicyID { get; set; }
public string appliedActivationDetails { get; set; }
public string nextTetherPolicyID { get; set; }
public string nextTetherPolicyDetails { get; set; }
public string macAddress { get; set; }
public string bluetoothMacAddress { get; set; }
public string partDescription { get; set; }
}
public class ConsumerLawInfo
{
public string serviceType { get; set; }
public string popMandatory { get; set; }
public string allowedPartType { get; set; }
}
public class ProductInfo
{
public string serialNumber { get; set; }
public string warrantyStatus { get; set; }
public string coverageEndDate { get; set; }
public string coverageStartDate { get; set; }
public string daysRemaining { get; set; }
public string estimatedPurchaseDate { get; set; }
public string purchaseCountry { get; set; }
public string registrationDate { get; set; }
public string imageURL { get; set; }
public string explodedViewURL { get; set; }
public string manualURL { get; set; }
public string productDescription { get; set; }
public string configDescription { get; set; }
public string slaGroupDescription { get; set; }
public string contractCoverageEndDate { get; set; }
public string contractCoverageStartDate { get; set; }
public string contractType { get; set; }
public string laborCovered { get; set; }
public string limitedWarranty { get; set; }
public string partCovered { get; set; }
public string notes { get; set; }
public string acPlusFlag { get; set; }
public ConsumerLawInfo consumerLawInfo { get; set; }
}
public class Fmi
{
public Attributes invalid_nameattribute { get; set; }
public FmipLockStatusDevice fmipLockStatusDevice { get; set; }
}
public class FmipLockStatusDevice
{
public Attributes2 invalid_nameattribute2 { get; set; }
}
public class Attributes
{
public string version { get; set; }
public string deviceCount { get; set; }
}
public class Attributes2
{
public string serial { get; set; }
public string imei { get; set; }
public string isLocked { get; set; }
public string isLost { get; set; }
}
}
Reading JSON:
string responseText = string.Empty;
AppleAPI appobj = new AppleAPI();
responseText = appobj.VerifyAppleESN(newEsn);
var resobj = JsonConvert.DeserializeObject<AppleAPI>(responseText.Replace("#",string.Empty));
lblSerialNumber.Text = resobj.product_info.serialNumber;
.
.
lblappliedActivationDetails.Text = resobj.ios_info.appliedActivationDetails;
.
.
//getting here error below line: Object ref notset to instance of object
lblfmiVersion.Text = resobj.fmi.invalid_nameattribute.version;
Any Idea?
If you're getting Object Reference not set to an instance of object. that means that you're trying to access properties on an object that is null. Since you said it happens on this line:
lblfmiVersion.Text = resobj.fmi.invalid_nameattribute.version;
that could mean that any of resobj, resobj.fmi, or resobj.fmi.invalid_nameattribute are null. Ignoring the fact that you should have proper null checks in your code to help avoid this situation, let's ask the question, why would any of these objects be null if deserialization succeeded? Perhaps some of the data was not deserialized correctly after all.
When deserializing using Json.Net, it is important to know that if any members of a class do not have matching properties in the JSON, those members will be skipped by Json.Net and thus retain their default values, e.g. null. So one possible reason that you have a null is that the name of a property in your class does not match what is in the JSON.
If we take a look at your Fmi class, one thing that jumps out right away is that it has a suspiciously named property called invalid_nameattribute. In the JSON, there is no such property. Instead, there is a property called #attributes. Your FmipLockStatusDevice class has the same problem. Since they didn't match up, these properties did not get populated during deserialization, so they are null.
So how can we fix this?
This is simple enough: add a [JsonProperty] attribute to your class properties to map them to the right JSON properties. (While you're at it, you might also consider changing the names of those properties in your C# class to something that actually makes sense, like "Attributes".)
public class Fmi
{
[JsonProperty("#attributes")]
public Attributes invalid_nameattribute { get; set; }
public FmipLockStatusDevice fmipLockStatusDevice { get; set; }
}
public class FmipLockStatusDevice
{
[JsonProperty("#attributes")]
public Attributes2 invalid_nameattribute2 { get; set; }
}
OK, now that you have a solution, you should ask yourself, how did you get into this situation in the first place, and how can you avoid it in the future?
You said you used json2csharp.com to generate your classes. You need to be aware that this tool is not foolproof, and will not always be able to generate correct classes to work with your JSON. This is true whenever the JSON property names contain punctuation characters or spaces or start with numbers, because these cannot be turned into valid C# property names. In these cases, json2csharp.com will generate a property name that starts with "invalid". You need to look for these, and make manual adjustments to your classes to fix the issues. Do not just blindly use the generated classes and assume they are correct.
Hope this helps.

Custom JSON, convert to object

I have the result of an API call which looks like:
{"Operations":[{"OperationId":"2","OperationObjectId":"Application","OperationName":"UnlockSession","OperationParameters":[{"Name":"viewModel","Value":"model"},{"Name":"returnUrl","Value":"https://"}],"OperationCaller":{"UserPrincipalName":"bob","ClientIPAddress":""},"OperationResult":"Succeeded","OperationStatus":200,"OperationRequest":{"Method":"POST","Url":""},"OperationStartedTime":"2013-08-20T12:04:17.5462357Z","OperationCompletedTime":"2013-08-20T12:04:17.9979469Z"}],"ContinuationToken":null}
Ideally I want to convert it to an object so I can do stuff like:
object.OperationObjectID; // gives Application
object.Method; // gives POST
object.OperationResult; // gives Succeeded
Does any one know how that is done? Does the JSON parse need to be aware of the format?
Thanks,
Andrew
you can use Json.Net as below
dynamic object = JObject.Parse(yorjsonstring);
object.Operations[0].OperationObjectID;
object.Operations[0].Method;
object.Operations[0].OperationResult;
rather than using dynamic object you can generate classes for your json and serialize to those classes like below.
you can get help of http://json2csharp.com/ site for generate classes
public class OperationParameter
{
public string Name { get; set; }
public string Value { get; set; }
}
public class OperationCaller
{
public string UserPrincipalName { get; set; }
public string ClientIPAddress { get; set; }
}
public class OperationRequest
{
public string Method { get; set; }
public string Url { get; set; }
}
public class Operation
{
public string OperationId { get; set; }
public string OperationObjectId { get; set; }
public string OperationName { get; set; }
public List<OperationParameter> OperationParameters { get; set; }
public OperationCaller OperationCaller { get; set; }
public string OperationResult { get; set; }
public int OperationStatus { get; set; }
public OperationRequest OperationRequest { get; set; }
public string OperationStartedTime { get; set; }
public string OperationCompletedTime { get; set; }
}
public class RootObject
{
public List<Operation> Operations { get; set; }
public object ContinuationToken { get; set; }
}
then
RootObject obj = JsonConvert.DeserializeObject<RootObject>(jsonstring);
obj.Operations[0].OperationObjectID;
Try to use JavaScriptSerializer class: http://msdn.microsoft.com/ru-ru/library/system.web.script.serialization.javascriptserializer.aspx.

Unable to deserialize the JSON string to object

Guyz
I am trying to parse a JSON string into object. I have the below entity in which I am parsing the JSON string
public class Room : BaseEntity
{
public string Name { get; set; }
public string EmailAddress { get; set; }
public string RoomListEmailAddress { get; set; }
public string MinimumXCoordinateInMap { get; set; }
public string MinimumYCoordinateInMap { get; set; }
public string MaximumXCoordinateInMap { get; set; }
public string MaximumYCoordinateInMap { get; set; }
public string RoomCapacity { get; set; }
public List<RoomImage> RoomImage { get; set; }
public string FloorName { get; set; }
public string CreatedDate { get; set; }
public string CreatedId { get; set; }
public string LastUpdatedDate { get; set; }
public string LastUpdatedId { get; set; }
public InternalOnly InternalOnly { get; set; }
//public List<Equipment> Equipment { get; set; }
public override string ToString()
{
return this.Name;
}
}
public class RoomImage : BaseEntity
{
public string ImagePath { get; set; }
public string ImageType { get; set; }
public string CreatedDate { get; set; }
public string CreatedId { get; set; }
public string LastUpdatedDate { get; set; }
public string LastUpdatedId { get; set; }
public InternalOnly InternalOnly { get; set; }
}
public class InternalOnly : BaseEntity
{
public string RoomId { get; set; }
public string FloorId { get; set; }
}
public class BaseEntity
{
}
I am using below method to parse the string into object
public static T ParseObjectToJSON<T>(string responseText)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(responseText)))
{
var rootObject = serializer.ReadObject(stream);
//return Convert.ChangeType(rootObject,typeof(T),System.Globalization.CultureInfo.CurrentCulture.TextInfo);
return (T)rootObject;
}
}
Below is the JSON string which I am trying to parse
https://docs.google.com/document/d/1k81M_UxIrXpHUPQNDUCHDfNw1wY7LM4mAaXjwpYMshk/edit?usp=sharing
The below json string is working
https://docs.google.com/document/d/1uQNwMmSyEZSolyxUVJl6gXzZPr6aRAf_WAogmUvVqt4/edit?usp=sharing
While parsing I get below error
The data contract type 'GAP.Entities.Room' cannot be deserialized because the member 'RoomImage' is not public. Making the member public will fix this error. Alternatively, you can make it internal, and use the InternalsVisibleToAttribute attribute on your assembly in order to enable serialization of internal members - see documentation for more details. Be aware that doing so has certain security implications.
Note- RoomImage is marked public in the entity class. I get this error only when JSON string contains RoomImage array string otherwise no erro.
Any help is highly appreciated.
Thanks
Vinod
You can download and deserialize an JSON using Newtonsoft.
You have to reference the following DLL, and after that you can try this:
List<Room> deserializedObj = (List<Room>)Newtonsoft.Json.JsonConvert.DeserializeObject(responseText, typeof(List<Room>));
The problem with your json is that if RoomImage has a single element, your service returns it as an object {} not as an array of objects [{}].
So If you want to use type-safe classes in your code(since dynamically accessing is also possible) you should pre-process your json before deserializing. Below code works (of course, as everybody says, using Json.Net)
string json = your__json__string
//PreProcess
var jobj = JObject.Parse(json);
foreach (var j in jobj["ObjectList"])
{
if (!(j["RoomImage"] is JArray))
{
j["RoomImage"] = new JArray(j["RoomImage"]);
}
}
var obj = JsonConvert.DeserializeObject<RootObject>(jobj.ToString());
public class InternalOnly
{
public string RoomId { get; set; }
public string FloorId { get; set; }
}
public class RoomImage
{
public string ImagePath { get; set; }
public string ImageType { get; set; }
public string CreatedDate { get; set; }
public string CreatedId { get; set; }
public string LastUpdateDate { get; set; }
public string LastUpdateId { get; set; }
}
public class ObjectList
{
public string Name { get; set; }
public string EmailAddress { get; set; }
public string RoomListEmailAddress { get; set; }
public string MinimumXCoordinateInMap { get; set; }
public string MinimumYCoordinateInMap { get; set; }
public string MaximumXCoordinateInMap { get; set; }
public string MaximumYCoordinateInMap { get; set; }
public string RoomCapacity { get; set; }
public RoomImage[] RoomImage { get; set; }
public string FloorName { get; set; }
public string CreatedDate { get; set; }
public string CreatedId { get; set; }
public string LastUpdatedDate { get; set; }
public string LastUpdatedId { get; set; }
public string IsRestrictedRoom { get; set; }
public InternalOnly InternalOnly { get; set; }
public object Equipment { get; set; }
}
public class RootObject
{
public List<ObjectList> ObjectList { get; set; }
}
The property RoomImage is public but your class probably isn't.
Make sure the RoomImage class is also marked public. That should solve the problem.
Alternatively use a library like JSON.NET that can do this deserialization without the need for public classes.

Categories

Resources