DataContractSerializer could not de-serialize all properties in Net Core 2 - .net-core

i am trying to de-serialize xml into known object using DataContractSerializer in .NET Core 2.
Here is my xml. ( I do not have control over xml. This is how i get the XML as response to some api method). For testing purpose i have captured the xml and put in xml file.
<Response>
<ClientID>TestClient</ClientID>
<FileName>E:\MyData\20180223084535390PM.xml</FileName>
<UploadStatus>Succeeded</UploadStatus>
<UploadMessage>Imported Successfully</UploadMessage>
<ConfirmationNumber>0abcb25f2675</ConfirmationNumber>
<ImportTime>2018-02-23T15:48:01.887</ImportTime>
<StartTime>2018-02-23T15:48:03.113</StartTime>
<EndTime>2018-02-23T15:53:14.76</EndTime>
<Count>6</Count>
<Amount>3446.3500</Amount>
<Messages />
</Response>
My corresponding C# object
[DataContract(Name = "Response", Namespace = "")]
public class MyResponse
{
[DataMember]
public string ClientID { get; set; }
[DataMember]
public string FileName { get; set; }
[DataMember]
public string UploadStatus { get; set; }
[DataMember]
public string UploadMessage { get; set; }
[DataMember]
public string ConfirmationNumber { get; set; }
[DataMember]
public DateTime? ImportTime { get; set; }
[DataMember]
public DateTime? StartTime { get; set; }
[DataMember]
public DateTime? EndTime { get; set; }
[DataMember]
public int? Count { get; set; }
[DataMember]
public decimal? Amount { get; set; }
[DataMember]
public string Messages { get; set; }
}
De-serialization code
[Fact]
public void TestDeSerialize()
{
var file = AppDomain.CurrentDomain.BaseDirectory + "Data\\test.xml";
var serializer = new System.Runtime.Serialization.DataContractSerializer(typeof(MyResponse));
MyResponse result = null;
using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
{
result = (MyResponse)serializer.ReadObject(fs);
}
}
However when it de-serializes the xml into object, most of the object properties are NULL even though they have corresponding values in XML file. See quickwatch below.
I am not sure what i am missing here??
Update 1
Note that, When i replace DataContract and DataMember attributes with XmlRoot and XmlElement respectively, and then de-serialize the xml using XmlSerializer then the resultant object has all the properties populated.
So it works with XmlSerializer but not with DataContractSerializer.
I would like to use DataContractSerializer

For DataContractSerializer, it is default to use Alphabetical ordering; and expects XML elements to arrive in that order; Out of order elements are discarded usually.
It seems the XML is received, and you could not change the XML elements order, you could use Order property like below.
[DataContract(Name = "Response", Namespace = "")]
public class MyResponse
{
[DataMember(Order =1)]
public string ClientID { get; set; }
[DataMember(Order = 2)]
public string FileName { get; set; }
[DataMember(Order = 3)]
public string UploadStatus { get; set; }
[DataMember(Order = 4)]
public string UploadMessage { get; set; }
[DataMember(Order = 5)]
public string ConfirmationNumber { get; set; }
[DataMember(Order = 6)]
public DateTime? ImportTime { get; set; }
[DataMember(Order = 7)]
public DateTime? StartTime { get; set; }
[DataMember(Order = 8)]
public DateTime? EndTime { get; set; }
[DataMember(Order = 9)]
public int? Count { get; set; }
[DataMember(Order = 10)]
public decimal? Amount { get; set; }
[DataMember(Order = 11)]
public string Messages { get; set; }
}

Related

Is it possible to get List<T> without some objects?

Need to get all data from List without status and date
public class Locations
{
public string CompanyCode { get; set; }
public string SupplierId { get; set; }
public string LocationName { get; set; }
public int Status { get; set; }
public DteTime date{ get; set; }
public int ResultCode { get; set; }
public string ResultMessage { get; set; }
}
I getting all locations in below list, I want to avoid status and date from the results
List<Locations> results
You could make use Anonymous Types
results.Select(x=>new{x.CompanyCode,x.SupplierId,x.LocationName,x.ResultCode,x.ResultMessage})
Alternatively, you could create a Custom class with only the desired property and project it using Linq as shown in the example with Anonymous Types
or you can use deriving from class/interface and then cast to it ;)
you can do something like this:
public interface ILocationsPoorData
{
public string CompanyCode { get; set; }
public string SupplierId { get; set; }
public string LocationName { get; set; }
public int ResultCode { get; set; }
public string ResultMessage { get; set; }
}
class Locations:ILocationsPoorData
{
public string CompanyCode { get; set; }
public string SupplierId { get; set; }
public string LocationName { get; set; }
public int Status { get; set; }
public DteTime date{ get; set; }
public int ResultCode { get; set; }
public string ResultMessage { get; set; }
}
and in the end, when you'll have list of locations, you can do sth like this:
var newList = locationsList.select(x=> x as ILocationsPoorData)
or
var newList = locationsList.Cast<ILocationsPoorData>();
or you can create class instead of interface and do the same ;)
or you can use anonymous types like in previous answer
or you can create some value tuple instead of anonymous types ;)

Error while deserilizing json in C#

I am getting response in json like this
data={"Id": "234", "Name": "pinky", "MobileNumber": "", "ClassName": "Class1_Physics", "DOBTime": "1990-04-11 15:46:38", "Landline": "", "Status": "Unmarried"}
I want to deserilize json and insert into table.
I have created 2 classes for it and using dll of Newtonsoft for deserilization.
public class JsonResult
{
public string Id { get; set; }
public string Name { get; set; }
public string MobileNumber { get; set; }
public string ClassName { get; set; }
public string DOBTime { get; set; }
public string Landline { get; set; }
public string Status { get; set; }
}
public class JsonResultRoot
{
[JsonProperty(PropertyName = "data")]
public string Data { get; set; }
public JsonResult JsonResult
{
get { return JsonConvert.DeserializeObject<JsonResult>(Data); }
}
}
Code :
decodedUrl : store actual json data/string
var JsonData = JsonConvert.DeserializeObject(decodedUrl).JsonResult;
If your JSON contains this data= part, then it is invalid JSON. You cannot deserialize it using JSON.NET library.
In order to deserialize this, you can simply clean this part out:
public class JsonResult
{
public string Id { get; set; }
public string Name { get; set; }
public string MobileNumber { get; set; }
public string ClassName { get; set; }
public string DOBTime { get; set; }
public string Landline { get; set; }
public string Status { get; set; }
}
// Usage:
jsonString = jsonString.Replace("data=").Trim();
var jsonObject = JsonConvert.DeserializeObject<JsonResult>(jsonString);
Of course, in general it looks bad. You should only do it if "you are getting response in json like this" and you can do nothing about it.
If there is any possibility to make incoming format correct, then better do it.

Newtonsoft serialization

I need some help with custom serialization using Newtonsoft Json (Json.Net). I have classes like below:
public class Person
{
[JsonProperty(PropertyName = "PersonName")]
public string Name { get; set; }
[JsonIgnore]
public int Age { get; set; }
public Address PersonAddress { get; set; }
}
public class Address
{
[JsonProperty(PropertyName = "Address1")]
public string Address1 { get; set; }
[JsonIgnore]
public string Address2 { get; set; }
[JsonProperty(PropertyName = "City")]
public string City { get; set; }
[JsonProperty(PropertyName = "State")]
public string State { get; set; }
[JsonIgnore]
public string Country { get; set; }
}
When I serialize the above class it should return output like below:
{
"PersonName":"Name",
"Address1":"Address1",
"City":"City",
"State":"state"
}
How can I do it using Newtonsoft?
You can create a third class as follows:
public class Rootobject
{
public string PersonName { get; set; }
public string Address1 { get; set; }
public string City { get; set; }
public string State { get; set; }
}
Then, an object out of it like this:
var rootObject = new Rootobject()
{
PersonName = person.Name,
Address1 = address.Address1,
City = address.City,
State = address.State
};
And finally serialize it using JsonCovert:
var result = JsonConvert.SerializeObject(rootObject);

property is null when using xml serialization in webapi

I'm trying to send the below xml
<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.uisol.com/model">
<extAlert SendFrom="SendFrom" Target="Target" OID="0" UrgentFlag="0" />
</dataset>
as a post to a webapi request
HttpResponseMessage Post([FromBody]SendNotificationRequest dataset)
with the classes defined as below
[XmlRoot(Namespace = "http://www.uisol.com/model",
ElementName = "dataset",
DataType = "string",
IsNullable = true)]
public class SendNotificationRequest
{
[XmlElement(
ElementName = "extAlert",
Namespace = "http://www.uisol.com/model")]
public DRMSAlertRequest ExtAlert { get; set; }
}
}
and
public class DRMSAlertRequest : IDRMSAlert
{
[XmlAttribute]
public string SendFrom { get; set; }
[XmlAttribute]
public string Target { get; set; }
[XmlAttribute]
public string SendTo { get; set; }
[XmlAttribute]
public string BlindTo { get; set; }
[XmlAttribute]
public string ReplyTo { get; set; }
[XmlAttribute]
public string FailureTo { get; set; }
[XmlAttribute]
public int OID { get; set; }
[XmlAttribute]
public string Subject { get; set; }
[XmlAttribute]
public string Message { get; set; }
[XmlAttribute]
public char UrgentFlag { get; set; }
}
i have also made the xmlmedia formatter as below
var formatter = new XmlMediaTypeFormatter {UseXmlSerializer = true};
config.Formatters.Add(formatter);
var xmlFormatter = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xmlFormatter.UseXmlSerializer = true;
xmlFormatter.SetSerializer<SendNotificationRequest>(new XmlSerializer(typeof(SendNotificationRequest)));
xmlFormatter.SetSerializer<DRMSAlertRequest>(new XmlSerializer(typeof(DRMSAlertRequest)));
}
I'm receiving the ExtAlert as null on the webapi controller. What might be the reason?
httpRequest.ContentType = "application/x-www-form-urlencoded";
changed this to
httpRequest.ContentType = "application/xml";

getting json byte array in list

I got null value for byte array in json web service when deserializing.but it returns byte array when invoked from browser.
C# Code:
var url = re.DownloadString("XXXX/ListService.svc/lstFooddtl/1/21");
var a = JsonConvert.DeserializeObject<FooddtlResult>(url);
In a i got null for food_photo...when i deserialize...
c# Class:
public class photo
{
public byte[] food_photo { get; set; }
}
public class Food
{
public int food_id { get; set; }
public string food_name { get; set; }
public photo[] food_photo { get; set; }
public string unitcost { get; set; }
}
public class FooddtlResult
{
public Food[] Result { get; set; }
}
{"Result":[{"food_id":"61","food_name":"Idli","food_photo":[255,216,255,224,0,....217],"unitcost":null}]}
Your model does not match the JSON. For correct deserialization change your Food class to
public class Food
{
public int food_id { get; set; }
public string food_name { get; set; }
public byte[] food_photo { get; set; }
public string unitcost { get; set; }
}
and remove the photo class.
Otherwise, if you want to keep the model structure, then correct JSON should be:
{"Result":[{"food_id":"61","food_name":"Idli","food_photo":[{"food_photo":[255,216,255,224,0,....217]},{"food_photo":[255,...]},...],"unitcost":null}]}

Resources