C# Json to custom class - c#

I have json:
[
{
"Name" : "SHA of timestamp",
"ProjectURL" : "URL to Proj",
"AccountIdentifier" : "Account Identifier",
"Repositories":
{
"GitLink1":
{
"Login" : "login1",
"Password" : "pas1"
},
"GitLink2":
{
"Login" : "login2",
"Password" : "pas2"
},
...
"GitLink999":
{
"Login" : "login999",
"Password" : "pass999"
}
}
},
...
{
Same entry
}
]
I need to fill it in IEnumerable of my created classes
public class Git
{
public string Login { get; set; }
public string Password { get; set; }
}
public class Repositories
{
public Git git { get; set; }
}
public class ConfigEntry
{
public string Name { get; set; }
public string ProjectURL { get; set; }
public string AccountIdentifier { get; set; }
public Repositories Repositories { get; set; }
}
Using
IEnumerable<ConfigurationEntry> config = JsonConvert.DeserializeObject<IEnumerable<ConfigurationEntry>>(CONFIGJSON);
Where CONFIGJSON contains frst json file.
Gives me this data of ConfigEntry class :
Name : "filled with some data"
ProjectURL : same
AccountIdentifier : same
Repositories : NULL
How i can fill Repositories field with all data i have in config JSON?
Is there any ideas.

It looks like you probably shouldn't have a Repositories class - instead, change your ConfigEntry.Repositories property to:
public Dictionary<string, Git> Repositories { get; set; }
Then you'll get a dictionary where the key of "GetLink1" has a value with Login of "login1" etc.

Your class definitions aren't quite right.
Your "repositories" class only contains a single Git, but needs to be a Dictionary.
I think if you use this you will be close:
public class Git
{
public string Login { get; set; }
public string Password { get; set; }
}
public class ConfigEntry
{
public string Name { get; set; }
public string ProjectURL { get; set; }
public string AccountIdentifier { get; set; }
public Dictionary<string,Git> Repositories { get; set; }
}
you may also need a non-generic IEnumerable, so it knows which objects to actually create:
JsonConvert.DeserializeObject<List<ConfigurationEntry>>(CONFIGJSON);

Related

Deserializing uncertain values in c#

I have a json as deined below ,
{
"ApplicationOne": {
"Version": "1.0",
"Owner": "coderClan"
},
"ApplicationTwo": {
"Version": "2.0",
"Owner": "gamers"
}
}
I am trying to implement a method such that when an application ID (ApplicationOne , ApplicationTwo) is passed as a parameter , the owner will be returned
public static string GetOwner(string applicationID)
{
string owner = ""; //Deserialized Owner Name
return owner;
}
The problem I have is that I have no way of being certain of the application ID as that can be changed ? hence I cannot create the POCO classes as below,
public class ApplicationOne
{
public string Version { get; set; }
public string Owner { get; set; }
}
public class ApplicationTwo
{
public string Version { get; set; }
public string Owner { get; set; }
}
public class RootObject
{
public ApplicationOne ApplicationOne { get; set; }
public ApplicationTwo ApplicationTwo { get; set; }
}
Is it still possible to deserialize this ? Would really appreciate an example of how I can implement this
You can do this with Newtonsoft.Json using dynamic:
dynamic deserialized = JsonConvert.DeserializeObject(json);
var result = deserialized["ApplicationOne"]?.Owner?.ToObject<string>();
And the method:
public static string GetOwner(string applicationID)
{
return deserialized[applicationID]?.Owner?.ToObject<string>();
}

How to get the value from JSON

I have the API like below.
[
{
"name":"test1",
"commit":{
"id":"8595fad8cd84c7a630c5d7a78414f9c",
"short_id":"8595fad8",
"title":"title 1",
"created_at":"2017-05-29T07:18:36.000+00:00",
"parent_ids":[
"74956b0bcd370f3ddc75d7db00336099cce20501"
],
"message":"Update README.md",
"author_name":"Administrator",
"author_email":"email.com",
"authored_date":"2017-05-29T07:18:36.000+00:00",
"committer_name":"Administrator",
"committer_email":"email.com",
"committed_date":"2017-05-29T07:18:36.000+00:00"
},
"merged":true,
"protected":false,
"developers_can_push":false,
"developers_can_merge":false
},
......
]
My class is
protected class BranchData
{
public string Name { get; set; }
public string Merged { get; set; }
public string Protected { get; set; }
public string Authored_Date { get; set; }
}
I tried to get all the above valve. But I did not get the value for authored_date.
My code is
var jSONString = reader.ReadToEnd();
branchDetails = JsonConvert.DeserializeObject<List<BranchData>>(jSONString);
I get all the class value in branchDetails list except authored_date(null).
How could I get rid from this?
As #willaien already mentioned, you should create dedicated Commit object, in order to get Authored_Data information.
protected class BranchData
{
public string Name { get; set; }
public string Merged { get; set; }
public string Protected { get; set; }
public CommitData Commit { get; set; }
}
protected class CommitData
{
[JsonProperty(PropertyName = "authored_date")]
public string AuthoredDate { get; set; }
//...other Commit object properties
}
Authored_Date is a property of "commit".
Create a Commit class, and put Authored_Date as it's property.
Then in BranchData, add a Commit property.

How to convert two json properties that have same name into properties in same class

I have a json object:
{
"user": {
"id": "xxx"
},
"session": {
"id": "xxx"
}
}
now I need to convert json into a class,
my default answer is to write properties as UserID,sessionID
but I wish something like User.ID & session.ID(which is not possible) from readability point of view.
Make a base class:
public class BaseId //Come up with a better name
{
public string Id { get; set; }
}
Then inherit it from these classes:
public class User : BaseId
{
//Other stuff if you want
}
public class Session : BaseId
{
//Other stuff if you want
}
However you should only do this if User and Session have unique differences from one another (but obviously share the ID property).
If you just want two different variables, then parse them into two different instances of the BaseId class named user and session (obviously no need for the concrete classes this way)
I'm not sure I understand the question entirely. If I were to do this, it would look like this:
public class Foo
{
[JsonProperty("user")]
public User UserIdentity { get; set; }
[JsonProperty("session")]
public Session CurrentSession { get; set; }
}
public class User
{
[JsonProperty("id")]
string Id { get; set; }
}
public class Session
{
[JsonProperty("id")]
string Id { get; set; }
}
You can use JsonProperty class of Newtonsoft.Json
public class Model
{
[JsonProperty(PropertyName = "UserId")]
public int ID { get; set; }
[JsonProperty(PropertyName = "SessionId")]
public int ID1 { get; set; }
}
public class User
{
[JsonProperty("id")]
public string id { get; set; }
}
public class Session
{
[JsonProperty("id")]
public string id { get; set; }
}
public class MyJson
{
[JsonProperty("user")]
private User user { get; set; }
[JsonProperty("session")]
private Session session { get; set; }
public string UserID { get { return user.id; } }
public string SessionID { get { return session.id; } }
}
You Can Write the Model of This type, You can Get the Data As You Request Type of UserID and SessionID.
In Below Sample Code For Testting
var teststring = JsonConvert.DeserializeObject<JObject>("{\"user\": {\"id\": \"xxx\"},\"session\": {\"id\": \"xxx\"}");
var data = JsonConvert.DeserializeObject<MyJson>(teststring.ToString());
var session = data.SessionID;
var userId = data.UserID;
I Was Checked Properly. It Working fine.

Web API - Error in sample generation

I'm facing a strange problem in ASP.NET web api. I made a generic class to be the returned model for all web methods. This is the model's code :-
public class RequestResponse<T>
{
public bool Sucess { get; set; }
public string Message { get; set; }
public T ReturnedData { get; set; }
public List<T> ReturnedDataList { get; set; }
}
Whenever I try using it in HTTP method like this :
public RequestResponse<BillsModel> CreateBill([FromBody] BillsModel billToAdd, MainHelpers.UserType userType)
This is BillsModel class :
public class BillsModel
{
public Guid Id { get; set; }
public DateTime BillDate { get; set; }
public long Number { get; set; }
public Guid OrderId { get; set; }
public int OrderType { get; set; }
public Guid PlaceId { get; set; }
public double TaxPercentage { get; set; }
public double? DiscountPercentage { get; set; }
public Guid CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public Guid? ModifiedBy { get; set; }
public DateTime? ModifiedOn { get; set; }
}
And then running the api to see the methods and choosing a method, I see the below :
{
"Sucess" : true,
"Message" : "sample string 2",
"ReturnedData" : {
"$id" : "2",
"Id" : "14b479ec-c128-4916-8ed5-c0067c20fd9f",
"BillDate" : "2016-05-20T21:57:32.530957+02:00",
"Number" : 3,
"OrderId" : "dd266c00-0167-49e8-a8f0-0996aca21490",
"OrderType" : 5,
"PlaceId" : "98059b6e-acfb-4c89-8c6a-72ef30cce4d6",
"TaxPercentage" : 7.1,
"DiscountPercentage" : 1.1,
"CreatedBy" : "ba106082-44be-4a53-9d32-40bf4ee32bde",
"CreatedOn" : "2016-05-20T21:57:32.530957+02:00",
"ModifiedBy" : "3d164ffd-aa1c-40d4-a646-9d6ca91615db",
"ModifiedOn" : "2016-05-20T21:57:32.530957+02:00"
},
"ReturnedDataList" : {
"$id" : "3",
"$values" : [{
"$ref" : "2"
}, {
"$ref" : "2"
}
]
}
}
As you can see, it works fine when it's about an object but when it comes to a list, an unidentified object is shown "$ref". The same for "$id" and "$values".
Can you help me with that please ?
You can disable this behavior by adding this at the end of your Application_Start() method Global.asax:
GlobalConfiguration
.Configuration
.Formatters
.JsonFormatter
.SerializerSettings
.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
I created the following web service and am using a generic type to return the packaged data and I'm not getting what you're getting. Can you run this on a separate project and see what JSON data is being returned?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
public class Account
{
public int AccountID { get; set; }
}
public class BusinessAccount : Account
{
public string BusinessAddress { get; set; }
}
public class Package<T>
{
public T Data { get; set; }
}
/// <summary>
/// using fiddler, I made a request to http://localhost/api/account
/// and got
///
/// {"Data":{"BusinessAddress":"ABC","AccountID":123}}
///
/// without making any configuration.
///
///
/// </summary>
namespace test
{
public class AccountController : ApiController
{
// GET api/<controller>
public Package<BusinessAccount> Get()
{
return new Package<BusinessAccount>()
{
Data = new BusinessAccount()
{
AccountID = 123,
BusinessAddress = "ABC"
}
};
}
}
}

asp.net mvc default model binder for model that has inheritance

I have a form that I binding to that has the following structure:
public class Status
{
public List<ABCAttachment> ABCAttachments_Files { get; set; }
}
public class Attachment
{
public string Id { get; set; }
}
public class ABCAttachment : Attachment
{
string Name { get; set; }
}
My action looks like this:
public ActionResult SaveAttachment(Status status)
{
....
}
The data is coming over in the form
ABCAttachments_Files[0].Id="0", ABCAttachments_Files[0].Name="test"
When I access status in my SaveAttachments action the Id is there, but the Name is not. I see it correctly being posted, but why is it not binding properly?
Looks like the Name property needs to be public or it won't be bounded to:
public class ABCAttachment : Attachment
{
string Name { get; set; }
}
should be
public class ABCAttachment : Attachment
{
public string Name { get; set; }
}

Categories