How to map JSON field to POCO using Automapper - c#

Is it possible to create mapping between POCO and JSON field using Automapper?
public class SomeObjectEntity
{
//JSON
public string TaskData { get; set; }
public GUID Id { get; set; }
public DateTime CreateTime { get; set; }
}
public class SomeObjectModel
{
public string Name { get; set; }
public string[] Emails { get; set; }
public GUID Id { get; set; }
public DateTime CreateTime { get; set; }
}
In TaskData i have this JSON string:
#"
{
""Name"": ""Denis"",
""EMails"": [
""someemail1#email.com"",
""someemail2#email.com""
]
}"
Is there any way to create map?
protected override void Configure()
{
Mapper.CreateMap<SomeObjectEntity, SomeObjectModel>() ...
Mapper.CreateMap<SomeObjectModel, SomeObjectEntity>() ...
}
Thanks.

From the code above, I see you want to turn the Name + Emails properties from the SomeObjectModel class and turn these into a JSON string and map this to the SomeObjectEntity.TaskData string property. This can be accomplished using a custom AutoMapper ValueResolver.
public class NameAndEmailResolver : ValueResolver<SomeObjectModel, string>
{
protected override string ResolveCore(SomeObjectModel source)
{
// need a quick and dirty list so we can perform linq query to isolate properties and return an anonymous type
var list = new List<SomeObjectModel>(){source};
return JsonConvert.SerializeObject(list.Select(x => new{x.Name, x.Emails});
}
}
And then call your mapper code:
Mapper.CreateMap<SomeObjectEntity, SomeObjectModel>()
.ForMember(x => x.TaskData, map => map.ResolveUsing<NameAndEmailResolver>());
This is only for one way binding. You'll have to write the code to go the opposite direction: SomeObjectModel --> SomeObjectEntity.

As mentioned by Jeroen, you need to first deserialize your json string to its corresponding type. And to do that, you can use the following. Assuming your type corresponding to the json is T, the following will deserialize it and gives you an object you can use it to map.
private async Task<T> ParseJsonToObjectAsync(string jsonValue)
{
var obj = await Task.Factory.StartNew(()=>JsonConvert.DeserializeObject<T>(jsonValue);
return obj;
}
You can also use http://json2csharp.com/ to help you generate the type corresponding your json string. It will save you time.
If SomeObjectEntity or TaskData in your description is the object representation of your json string, then that is what T is.
Once you have the json deserialized, you can either manually map or use https://github.com/AutoMapper/AutoMapper

Related

Deserialize an array inside a json object using JsonConvert.DeserializeObject()

I have a requirement where I have incoming json object of the following format:
{
"CustomerList": {
"Customer": [{
"CustomerCode" : "C123",
"CustomerName" : "Peter"
},
{
"CustomerCode" : "C456",
"CustomerName" : "John"
}]
}
}
And I have the my C# object of the following Format:
[System.Xml.Serialization.XmlArrayItemAttribute(IsNullable = "false")]
public Customer[] CustomerList
{
get; set;
}
[System.Xml.Serialization.XmlTypeAttribute()]
public class Customer
{
public string CustomerCode {get; set;}
public string CustomerName {get; set;}
}
During Deserialization using JsonConvert.DeserializeObject(), I get the following error:
Cannot deserialize the current JSON object into type Customer[], because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
On my side the limitation is that I cannot change the incoming JSON object and neither can I modify the C# object structure. So the ask is that, is there a way to map the Customer node in the incoming Json, to the CustomerList C# array directly, without needing to rename or change the structure of either?
Based on the JSON you have shared, you need to have following class structure.
public class Customer {
public string CustomerCode { get; set; }
public string CustomerName { get; set; }
}
public class CustomerList {
public List<Customer> Customer { get; set; }
}
public class RootObject {
public CustomerList CustomerList { get; set; }
}
and then you need to deserizalize the JSON as following.
RootObject obj = JsonConvert.DeserializeObject<RootObject>(jsonString);
Here jsonString is the string variable which has the JSON string.
I hope you this will help you resolve your issue.
To deserialize the JSON object you need to create a similar C# class.
public class JsonObjectTest {
[JsonPropertyName("CustomerList")]
public Customer CustomerPreList {get;set;}
}
public class Customer {
public List<CustomerObject> Customer {get;set;}
}
public class CustomerObject {
public string CustomerCode { get; set; }
public string CustomerName { get; set; }
}
Afterwards you deserialize the JSON object:
CustomerList xmlData = JsonConvert.DeserializeObject<JsonObjectTest>(jsonObjectString).Select(data =>
new CustomerList = data.CustomerPreList.toArray());
Unfortunately I could not ask you if you have a permission to create new classes (I need more points). If this is the case try AutoMapper to create a mapping policy for this specific case.
Happy coding :)
If you cannot (or do not want to) add new classes, the last two lines of GetCustomers() below should do what you want. Just assign it to the CustomerList property.
public class Customer
{
public string? CustomerCode { get; set; }
public string? CustomerName { get; set; }
}
public Customer[] GetCustomers()
{
string json = #"{
'CustomerList':
{
'Customer': [{
'CustomerCode' : 'C123',
'CustomerName' : 'Peter'
},
{
'CustomerCode' : 'C456',
'CustomerName' : 'John'
}]
}
}";
dynamic? contentObj = JsonConvert.DeserializeObject(json);
return (contentObj?.CustomerList.Customer.ToObject<IList<Customer>>())?.ToArray() ?? new List<Customer>().ToArray();
}
I am working with .NET 6.0 so working with string? but for earlier versions of c# string should do the same. Play with the null handling as required.

C# Web Api - NUnit Testing - Newtonsoft.Json.JsonSerializationException

I need to deserialize the following JSON string.
{"status":"success","data":[{"id":4,"domainTitle":"Java","isDeleted":true},{"id":5,"domainTitle":"PHP","isDeleted":true},{"id":6,"domainTitle":"Angular","isDeleted":true}]}
The test code for the same is:
[Test]
public async Task TestGetDeletedDomainsAsync_UserDomains_StatusCodeOK()
{
using (var adminController = new AdminController(_adminService.Object))
{
//act
var response = _adminController.GetDeletedDomainsAsync();
var successStatus = await response.Content.ReadAsAsync<SuccessStatus>();
var returnData = JsonConvert.DeserializeObject<List<Domain>>(successStatus.Data.ToString());
// assert
Assert.Multiple(() =>
{
Assert.That(response, Is.TypeOf<HttpResponseMessage>());
Assert.That(returnData, Is.TypeOf<List<Domain>>());
Assert.AreEqual(response.StatusCode, HttpStatusCode.OK);
Assert.IsNotNull(successStatus);
Assert.AreEqual("success", successStatus.Status);
Assert.IsNotNull(returnData);
//checking if same object goes to service and also if that service is called once
_adminService.Verify(s => s.GetDeletedDomains(), Times.Once);
});
}
}
But when I try using the de-serializer, it gives an exception.
Newtonsoft.Json.JsonSerializationException : Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[IMS_NL.Models.Domain]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
The line that displays the above error is --
var returnData = JsonConvert.DeserializeObject<List<Domain>>(successStatus.Data.ToString());
Help me with a solution. Thanks in advance.
You need to make a class which correspond your JSON string
public class Answer
{
public string Status { get; set; }
public List<Domain> Data { get; set; }
}
public class Domain
{
public int Id { get; set; }
public string DomainTitle { get; set; }
public bool IsDeleted { get; set; }
}
Then use
var returnData = JsonConvert.DeserializeObject<Answer>(successStatus.Data.ToString());
I think that your problem resides in the declaration of Domain class. You should define the below classes, according to the JSON you have posted:
public class Domain
{
public int id { get; set; }
public string domainTitle { get; set; }
public bool isDeleted { get; set; }
}
public class Result
{
public string status { get; set; }
public List<Domain> data { get; set; }
}
var returnData = JsonConvert.DeserializeObject<Result>(...);
You should replace the ... with the JSON you get from that you call.
Optionally, you could rename the above classes as you think that would be more suitable.

Deserialising json string to List<T>

I have a web service that is outputting JSON in the form
{"AppointmentList":[{"AppointmentList":{"id":"1","MeetingId":"1","MeetingName":"Test Meeting 1","Length":"90","Room":"B2C","DateTimeFrom":"1st Sept 2016","Venue":"The old pub","DateCreated":"2016-08-30 00:00:00","DateDue":"2016-09-01 00:00:00","UserId":"JohnsonPa"}},{"AppointmentList":{"id":"2","MeetingId":"2","MeetingName":"Test Meeting 2","Length":"60","Room":"B2C","DateTimeFrom":"11th Sept 2016","Venue":"The old pub","DateCreated":"2016-09-01 00:00:00","DateDue":"2016-09-12 00:00:00","UserId":"JohnsonPa"}...}]}
I am trying to deserialise this in to List. Normally, I would have a Base Class that would contain a property List AppointmentList {get; set;}, however, that would mean that I can't use type T and need a pile of duplicate code for each class.
I can certainly create BaseClass with a property public List Data {get; set;} however, as the JSON won't deserialise to Data (incorrect name) and the JSON PropertyName can't be set to the class name derived from typeof(T).ToString().
Is there a way to achieve what I'm trying to do without resorting to lots of code duplication?
I've tried casting the deserialiser to JArray and creating a reader from that, but this throws an exception.
Im not sure if this is exactly what you need, but maybe something like this would work? It allows you to successfully deserialize to a JArray like you state you tried at the end of your question.
JArray result = JsonConvert.DeserializeObject<dynamic>(json).AppointmentList;
Here how to convert it to List<object>
dynamic data = JsonConvert.DeserializeObject(json);
JArray array = data.AppointmentList;
List<object> objectList = array.ToObject<List<object>>();
What is wrong with generics? If you want a schemaless data structure use JObject or dynamic if not you can try this.
class Program
{
public const string json = #"{""AppointmentList"":[{""AppointmentList"":{""id"":""1"",""MeetingId"":""1"",""MeetingName"":""Test Meeting 1"",""Length"":""90"",""Room"":""B2C"",""DateTimeFrom"":""1st Sept 2016"",""Venue"":""The old pub"",""DateCreated"":""2016-08-30 00:00:00"",""DateDue"":""2016-09-01 00:00:00"",""UserId"":""JohnsonPa""}},{""AppointmentList"":{""id"":""2"",""MeetingId"":""2"",""MeetingName"":""Test Meeting 2"",""Length"":""60"",""Room"":""B2C"",""DateTimeFrom"":""11th Sept 2016"",""Venue"":""The old pub"",""DateCreated"":""2016-09-01 00:00:00"",""DateDue"":""2016-09-12 00:00:00"",""UserId"":""JohnsonPa""}}]}";
static void Main(string[] args)
{
var items = Newtonsoft.Json.JsonConvert.DeserializeObject<AppointmentItemList<Meeting1>>(json).GetList();
var items2 = Newtonsoft.Json.JsonConvert.DeserializeObject<AppointmentItemList<Meeting2>>(json).GetList();
Console.ReadLine();
}
public class AppointmentItemList<T>
{
public List<AppointmentItem> AppointmentList { get; set; }
public class AppointmentItem
{
public T AppointmentList { get; set; }
}
public IList<T> GetList()
{
return AppointmentList.Select(al => al.AppointmentList).ToList();
}
}
public class Meeting1
{
[Newtonsoft.Json.JsonProperty("id")]
public string Id { get; set; }
public string MeetingName { get; set; }
}
public class Meeting2
{
[Newtonsoft.Json.JsonProperty("id")]
public string Id { get; set; }
public string Room { get; set; }
}
}

Parsing nested json with n number of json objects in c#

i am a newbie to coding , I have a nested json coming from a external source the json format is looks something like this ..
{
"data":"data",
"data":
{
"data":"data",
//----------------e.t.c the internal objects could be in n number
}
}
so how do i deserialize the json object and use the data as a list in order to do my other operations like sql and posting the data??
You need to create a class that is appropriate with the Json, like that:
public someClass
{
public string data1 { get; set; }
public DataClass dataArr { get; set; }
}
public DataClass
{
public string insideData { get; set; }
}
after you do this you need the following code:
var jsonDto = JsonConvert.DeserializeObject<someClass>(yourJson);

How to parse JSON object in C#

I am getting following JSON data
[{"id":"1","text":"System Admin","target":{"jQuery1710835279177001846":12},"checked":true,"state":"open"},
{"id":"2","text":"HRMS","target":{"jQuery1710835279177001846":34},"checked":false,"state":"open"},
{"id":"3","text":"SDBMS","target":{"jQuery1710835279177001846":42},"checked":false},
{"id":"8","text":"Admin","target":{"jQuery1710835279177001846":43},"checked":false},
{"id":"9","text":"My test Admin","target":{"jQuery1710835279177001846":44},"checked":false,"state":"open"},
{"id":"24","text":"ModuleName","target":{"jQuery1710835279177001846":46},"checked":false,"state":"open"}]
which try to parsed using Json.Net using strongly type
this are my property class
public class testclass
{
public string id { get; set; }
public string text { get; set; }
public string #checked { get; set; }
public string state { get; set; }
public target jQuery1710835279177001846 { get; set; }
}
public class testclass2
{
public List<testclass> testclass1 { get; set; }
}
public class target
{
public string jQuery1710835279177001846 { get; set; }
}
and here i am trying to access the data i am getting exception
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'QuexstERP.Web.UI.Areas.SysAdmin.Controllers.testclass' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
My controller code look like
public void Test(string Name, object modeldata)
{
var obj = JsonConvert.DeserializeObject<testclass>(Name);
}
Any idea how to solve this issue in C#
Your Json string looks to have serialized array object in it because it contains [ ]. It means you have a Json string which is formed after serialization of array object. So you need to deserialized into array object, so try this
var obj = JsonConvert.DeserializeObject<List<testclass>>(jsonString);
you have Array of TestClass. so it should be like this.
var model= JsonConvert.DeserializeObject<List<testclass>>(Name);
why you are using JSonConvert ? in MVC3 you can do like this
return Json(yourmodel,JsonRequestBehavior.AllowGet);
Your json objects are like this
{
"id":"1",
"text":"System Admin",
"target":{
"jQuery1710835279177001846":12
},
"checked":true,
"state":"open"
}
It should be like this I guess
{
"id":"1",
"text":"System Admin",
"jQuery1710835279177001846":12,
"checked":true,
"state":"open"
}

Categories

Resources