I want to return a particular type of JSON format from my sp.
Below is the JSON format I want:
I am using the dataset to fetch from Query.
I have looped in the data row from the table.
I have used the KeyValuPair type to fetch the data.
But unable to get the desired format, I only get the format key value but how to get that in the metadata.
My desired JSON output
{
"Metadata": [
{
"Key": "FirstName",
"Value": "ABC"
},
{
"Key": "LastName",
"Value": "XYZ"
}
],
"Length": 25,
"Type": "application/mp3"
}
C# code to fetch the data from sp
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
List<Class> objList = new List<Class>();
List<KeyValuePair<string, string>> keyvalList = new List<KeyValuePair<string, string>>();
foreach (DataRow t in ds.Tables[0].Rows)
{
Class obj1 = new Class();
obj1.FirstName = Convert.ToString(t["FirstName "]);
obj1.LastName= Convert.ToString(t["LastName"]);
objList.Add(obj1);
keyvalList.Add(new KeyValuePair<string, string>("FirstName ", Convert.ToString(t["FirstName"])));
keyvalList.Add(new KeyValuePair<string, string>("LastName", Convert.ToString(t["LastName"]);
}
string JSONresult = JsonConvert.SerializeObject(keyvalList);
return JSONresult;
My Class Structure
public class Class
{
public string FirstName{ get; set; }
public string LastName{ get; set; }
}
JSON format which I get
[{\"key":\"FirstName\", \"Value\":\"ABC\"},{\"key":\"LastName\", \"Value\":\"XYZ\"}]
I get the key-value JSON but it does not get inside the metadata array.
Update
var data = new
{
Metadata = dt.AsEnumerable()
.Select(m => new Header
{
key= m.Field<string>("AgentId"),
Value= m.Field<string>("LastName"),
FirstName = m["FirstName"].ToString(),
LastName = m["LastName"].ToString()
}).ToList(),
Length = "25",
Type = "application/mp3"
};
string JSONreult = JsonConvert.SerializeObject(data);
return JSONreult;
Output what I get
{
"Metadata": [
[
{
"Key": "FirstName",
"Value": "ABC"
},
{
"Key": "LastName",
"Value": "DEF"
}
],
[
{
"Key": "FirstName",
"Value": "GEH"
},
{
"Key": "LastName",
"Value": "IJK"
}
]
],
"Length": 25,
"Type": "application/json"
}
Output How I want
{
"Metadata": [
{
"Key": "FirstName",
"Value": "ABC"
},
{
"Key": "LastName",
"Value": "XYZ"
}
],
"Length": 25,
"Type": "audio/mp3",
}
The Difference
The extra [] inside MetaData while I only need one Array.
You have to create a class
public class Data {
public IList<KeyPairValue<string,string>> Metadata{ get; set; }
}
fill it with your values and then serialize that to Json.
You don't need to make many hops like that. You could say use LinqToSQL or LinqToEF, along with Newtonsoft's Json.Net from NuGet and your code would simply be like:
var data = new
{
MetaData = db.TableName
.Select(row => new { Key = row.FieldForKey, Value = row.FieldForValue }),
Length = 25,
Type = "application/mp3"
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
If you still want to use ADO.Net instead, you still could do it like:
var tbl = new DataTable();
new SqlDataAdapter(cmd, "your connection string here").Fill(tbl);
var data = new
{
MetaData = tbl.AsEnumerable()
.Select(t => new { Key = t.Field<string>("KeyColumn"), Value = t.Field<string>("ValueColumn")}),
Length = 25,
Type = "application/mp3"
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
EDIT: Although I find it weird, here is a full sample using Northwind sample database:
var tbl = new DataTable();
new SqlDataAdapter(#"Select t.*
from Customers c1
cross apply (select 'FirstName', customerId from customers c2 where c1.CustomerId = c2.CustomerId
union
select 'LastName', CompanyName from customers c2 where c1.CustomerId = c2.CustomerId) t([Key], [Value])
",#"server=.\SQLExpress2012;Database=Northwind;Trusted_Connection=yes").Fill(tbl);
var data = new
{
MetaData = tbl.AsEnumerable()
.Select(t => new {
Key = t.Field<string>("Key"),
Value = t.Field<string>("Value") } ),
Length = 25,
Type = "application/mp3"
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
Answer is updated based on comments
Your question consists of two parts:
1.How to populate DataTable
2.How to serialize it to json (in a custom look)
First of all, Change your class structure like below:
public class Metadata
{
public string FirstName { get; set; }
public string LasstName { get; set; }
}
public class Data
{
public IList<Metadata> Metadata { get; set; }
public int Length { get; set; }
public string Type { get; set; }
}
Then you should populate dt with database query results using Linq:
DataTable dt = new DataTable();
da.Fill(dt);
var listOfData = new Data
{
Metadata = dt.AsEnumerable()
.Select(m => new FullName
{
Key = m["FirstName"].ToString(),
Value = m["LastName"].ToString()
}).ToList(),
Length = 25,
Type = "application/mp3"
};
After serializing listOfData to json using var json = JsonConvert.SerializeObject(listOfData); command, the output would be like this:
{
"Metadata":[
{
"Key":"John",
"Value":"Smith"
},
{
"Key":"Adele",
"Value":"Jones"
}
],
"Length":25,
"Type":"application/mp3"
}
But it differs from your desired output:
{
"Metadata":[
{
"Key":"FirstName",
"Value":"John"
},
{
"Key":"LastName",
"Value":"Smith"
}
],
"Length":25,
"Type":"application/mp3"
}
If you like to change the face of your json and serialize it in custom way, you have to implement a Custon JsonConverter, because JsonSerializer cannot change your model by itself. To do so, you have to create a class and derive it from JsonConverter and override its methods to shape your nodes as you like:
class CustomMetadataConverter<T> : JsonConverter where T : class
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(T);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject obj = new JObject(
JArray.Load(reader)
.Children<JObject>()
.Select(jo => new JProperty((string)jo["Key"], jo["Value"]))
);
T result = Activator.CreateInstance<T>();
serializer.Populate(obj.CreateReader(), result);
return result;
}
public override bool CanRead
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JArray array = new JArray(
JObject.FromObject(value)
.Properties()
.Select(jp =>
new JObject(
new JProperty("Key", jp.Name),
new JProperty("Value", jp.Value)
)
)
);
array.WriteTo(writer);
}
}
And then call JsonObject.SerializeObject this way instead of calling it as always:
var json = JsonConvert.SerializeObject(listOfData, Formatting.Indented /* set it depend on your need */, new CustomMetadataConverter<Metadata>());
You can desrialize it in the same way:
var deserializedObject = JsonConvert.DeserializeObject<JObject>(json, new CustomMetadataConverter<Metadata>());
Here is the output:
{
"Metadata": [
[
{
"Key": "FirstName",
"Value": "John"
},
{
"Key": "LastName",
"Value": "Smith"
}
],
[
{
"Key": "FirstName",
"Value": "Adele"
},
{
"Key": "LastName",
"Value": "Jones"
}
]
],
"Length": 25,
"Type": "application/json"
}
Related
I am using NewtonJson for serializing object. I want to serlize a object which has two properties one is normal string and the second property is dictionary of some items.
I am expecting a result something like this:
"Company": {
"Id": "1393",
"emp1": {
"email": "test1#example.com",
"firstName": "test1",
"lastName": "test1",
"title": "Mr"
},
"emp2": {
"email": "test2#example.com",
"firstName": "test2",
"lastName": "test2",
"title": "Ms"
}
}
but I am getting output like below:
"Company": {
"Id": "1393",
"employees": {
"emp1": {
"email": "test1#example.com",
"firstName": "test1",
"lastName": "test1",
"title": "Mr"
},
"emp2": {
"email": "test2#example.com",
"firstName": "test2",
"lastName": "test2",
"title": "Ms"
}
}
}
Here is my Code:
public string GetCompany(Dictionary<string, Employee> employees)
{
var company = JsonConvert.SerializeObject(new
{
Id = "1393",
employees
});
return company;
}
By creating the anonymous object, your adding another property named employees.
Why not just append Id to the dictionary?
e.g.
var employeesCopy = employees
.ToDictionary(kvp => kvp.Key, kvp => (object)kvp.Value);
employeesCopy["Id"] = "1393";
var company = JsonConvert.SerializeObject(employeesCopy);
This makes a copy of employees and adds a new key "Id" before serialising.
Create a Poco (Plain Old C# Object). Make sure to add [JsonExtensionData] attribute.
public class Poco
{
public string Id { get; set; } = string.Empty;
[JsonExtensionData]
public Dictionary<string, object> Employees { get; set; } = new();
}
And then serialize it
var employees = new Dictionary<string, object>()
{
{ Path.GetRandomFileName(), new Employee() },
{ Path.GetRandomFileName(), new Employee() }
};
var company = JsonConvert.SerializeObject(new Poco { Id = "1393", Employees = employees });
Unfortunately it is not clear what is your goal. If you just need a json string , you can try this code
public string GetCompany(string id, Dictionary<string, Employee> employees)
{
var e = JObject.FromObject(employees);
e.AddFirst(new JProperty( "Id", id));
return e.ToString();
}
but probably you need something bigger, so maybe it makes some sense to create a JObject in order to add it to another part of you data. In the end you can serialize it calling ToString() function
public JObject GetCompany(string id, Dictionary<string, Employee> employees)
{
JObject jo = JObject.FromObject(employees);
jo.AddFirst(new JProperty( "Id", id));
return jo;
}
We have a project which using System.Text.Json in .NET 5 instead of Newtonsoft JObject. Using Newtonsoft, it is pretty easy to replace dynamic JSON data e.g. as shown below:
siteDataObject["student"] = JArray.FromObject(studentservice.GetStudents());
When studentservice.GetStudents() is return List as below structure
internal class Student {
public int Id { get; set; }
public string Name { get; set; }
public string ContactPhone { get; set; }
public IEnumerable<MedicalRecord> MedicalRecords { get; set; }
}
internal class MedicalRecord {
public int Id { get; set; }
public string Name { get; set; }
public DateTime RecordDate { get; set; }
public IEnumerable<DiseaseLog> DiseaseLogs{ get; set; }
}
internal class DiseaseLog {
public int Id { get; set; }
public string Name { get; set; }
public DateTime LogDate { get; set; }
}
but in System.Text.Json
foreach (var element in doc.RootElement.EnumerateObject()) {
if (element.Name == "student") {
writer.WritePropertyName(element.Name);
}
else {
element.WriteTo(writer);
}
}
I don't know how to convert List<student> into JSON array data, when student class have many properties with multi collection inside.
Can anyone advise how to convert it ?
To clarify, I need to propose the full code for this, I have a dynamic json string and want to replace element : students into new record, the code will be
var dynamicJson = #"{'roomid':1,'roomcode':'Code001','students':[1],'contentdata':'say hello','footerdata':'cookie policy'}";
using MemoryStream stream = new MemoryStream();
using Utf8JsonWriter writer = new Utf8JsonWriter(stream);
using var dynamicDocument = JsonDocument.Parse(dynamicJson);
writer.WriteStartObject();
foreach (var element in dynamicDocument.RootElement.EnumerateObject())
{
if (element.Name == "students")
{
// unknown how to modify the student record into array
}
else
element.WriteTo(writer);
}
writer.WriteEndObject();
stream.Flush();
var modifyJson = Encoding.UTF8.GetString(stream.ToArray());
I know how to modify student value , if student element is string, but I don't know how to modify it into array, by using simple code. As student have multi class inside.
My expected result should be
{
"roomid": 1,
"roomcode": "Code001",
"students": [
{
"id": 1,
"Name": "Wilson",
"ContactPhone": "123-122-3311",
"MedicalRecords": [
{
"id": 101,
"Name ": "Medial record 101011",
"RecordDate": "2021-12-31",
"DiseaseLogs": [
{
"id": 18211,
"Name ": "Patient Log 19292",
"LogDate": "2020-1-31"
},
{
"id": 18212,
"Name ": "Patient Log 2911w",
"LogDate": "2020-3-31"
}
]
}
]
}
],
"contentdata": "say hello",
"footerdata": "cookie policy"
}
In .NET 5 there is no modifiable JSON Document Object Model built into to System.Text.Json. JsonDocument is read-only, and System.Text.Json.Nodes was only introduced in .NET 6. Thus, the easiest way to deserialize, modify and re-serialize free-form JSON in .NET 5 is to deserialize to some partial data model, with unknown values bound into a dictionary.
If you do not care about the order of properties at the root level, you could deserialize to a model with a public object students { get; set; } property, and bind the remaining elements to a JsonExtensionData overflow dictionary:
public class RootObject
{
public object students { get; set; }
[System.Text.Json.Serialization.JsonExtensionDataAttribute]
public IDictionary<string, object> ExtensionData { get; set; }
}
Then deserialize, modify and re-serialize as follows:
var students = new List<Student> { /* Initialize these as required... */ };
var dynamicJson = #"{""roomid"":1,""roomcode"":""Code001"",""students"":[1],""contentdata"":""say hello"",""footerdata"":""cookie policy""}";
var root = JsonSerializer.Deserialize<RootObject>(dynamicJson);
root.students = students;
var modifyJson = JsonSerializer.Serialize(root, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true });
Which results in
{
"students": [
{
"id": 1,
"name": "Wilson",
"contactPhone": "123-122-3311",
"medicalRecords": [
{
"id": 101,
"name": "Medial record 101011",
"recordDate": "2021-12-31T00:00:00",
"diseaseLogs": [
{
"id": 18211,
"name": "Patient Log 19292",
"logDate": "2020-01-31T00:00:00"
},
{
"id": 18212,
"name": "Patient Log 2911w",
"logDate": "2020-03-31T00:00:00"
}
]
}
]
}
],
"roomid": 1,
"roomcode": "Code001",
"contentdata": "say hello",
"footerdata": "cookie policy"
}
the students property must be declared as object because the input JSON already has an array containing a single integer value; declaring it as public List<Student> students { get; set; } would result in a deserialization when initially loading the JSON.
Demo fiddle #1 here.
If you do care about the order of properties at the root level, you could deserialize to an OrderedDictionary (an old order-preserving non-generic dictionary dating from .NET Framework 2.0 which is still around and supported), overwrite the "students" value, and re-serialize:
var students = new List<Student> { /* Initialize these as required... */ };
var dynamicJson = #"{""roomid"":1,""roomcode"":""Code001"",""students"":[1],""contentdata"":""say hello"",""footerdata"":""cookie policy""}";
var root = JsonSerializer.Deserialize<OrderedDictionary>(dynamicJson);
root["students"] = students;
var modifyJson = JsonSerializer.Serialize(root, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true });
Which results in
{
"roomid": 1,
"roomcode": "Code001",
"students": [
{
"id": 1,
"name": "Wilson",
"contactPhone": "123-122-3311",
"medicalRecords": [
{
"id": 101,
"name": "Medial record 101011",
"recordDate": "2021-12-31T00:00:00",
"diseaseLogs": [
{
"id": 18211,
"name": "Patient Log 19292",
"logDate": "2020-01-31T00:00:00"
},
{
"id": 18212,
"name": "Patient Log 2911w",
"logDate": "2020-03-31T00:00:00"
}
]
}
]
}
],
"contentdata": "say hello",
"footerdata": "cookie policy"
}
Demo fiddle #2 here.
In .NET 6 this all becomes easier through use of the System.Text.Json.Nodes editable JSON Document Object Model:
var dynamicJson = #"{""roomid"":1,""roomcode"":""Code001"",""students"":[1],""contentdata"":""say hello"",""footerdata"":""cookie policy""}";
var nodes = JsonSerializer.Deserialize<JsonObject>(dynamicJson);
nodes["students"] = JsonSerializer.SerializeToNode(students, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
var modifyJson = nodes.ToString();
But in .NET 5 this is not possible. Demo fiddle #3 here.
I think this is what you want (array or single nested object):
var student = new Student()
{
Name = "Student",
ContactPhone = "contact",
Id = 1,
MedicalRecords = new List<MedicalRecord>()
{
new MedicalRecord()
{
Name = "Medical Record 1",
RecordDate= DateTime.Now ,
Id = 1 ,
MedicalRecords = new List<DiseaseLog>()
{
new DiseaseLog(){ Name = "some disease" ,
LogDate = DateTime.Now, Id =1 }
}
}
}
};
var data = System.Text.Json.JsonSerializer.Serialize(student);
Console.WriteLine(data);
var list = new List<Student>();
list.Add(student);
var arrayData = System.Text.Json.JsonSerializer.Serialize(list);
Console.WriteLine(arrayData);
I have a challenge where I need to take any object and flatten into a key value pair format
This is working really well for simple classes, and even classes where I have other classes within it
Looking at an example,
public class Buyer
{
[JsonProperty("name")]public string Name { get; set; }
[JsonProperty("address")]public string Address { get; set; }
[JsonProperty("lastPurchase")]public Purchase LastPurchase { get; set; }
public Buyer()
{
Name = "Joe Bloggs";
Address = "An adddress somewhere";
AllPurchases = new List<Purchase>()
{
new Purchase() {PurchaseAmount = 100, PurchaseDateTime = Convert.ToDateTime("2017-01-01")},
new Purchase() {PurchaseAmount = 100, PurchaseDateTime = Convert.ToDateTime("2018-01-01")}
};
LastPurchase = new Purchase() {PurchaseAmount = 100, PurchaseDateTime = Convert.ToDateTime("2018-01-01")};
}
[JsonIgnore]
public List<Purchase> AllPurchases { get; set; }
}
public class Purchase
{
public DateTime PurchaseDateTime { get; set; }
public double PurchaseAmount { get; set; }
}
I have the code below which is my current implementation
var buyer = new Buyer();
var json = JsonConvert.SerializeObject(buyer);
var obj = JObject.Parse(json);
var result = obj.Descendants()
.OfType<JProperty>()
.Where(s => s.Value.Type != JTokenType.Object)
.Select(p => new KeyValuePair<string, string>(p.Path,
p.Value.Type == JTokenType.Array || p.Value.Type == JTokenType.Object
? null : p.Value.ToString()));
var serializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ContractResolver = new CamelCasePropertyNamesContractResolver(),
};
var newJson = JsonConvert.SerializeObject(result, serializerSettings);
Console.WriteLine(newJson);
This generates the Json below which is perfect
[
{
"key": "name",
"value": "Joe Bloggs"
},
{
"key": "address",
"value": "An adddress somewhere"
},
{
"key": "lastPurchase.PurchaseDateTime",
"value": "01/01/2018 00:00:00"
},
{
"key": "lastPurchase.PurchaseAmount",
"value": "100"
}
]
Things get tricky when I introduce serialising the list by removing JsonIgnore
Now I get
[
{
"key": "name",
"value": "Joe Bloggs"
},
{
"key": "address",
"value": "An adddress somewhere"
},
{
"key": "lastPurchase.PurchaseDateTime",
"value": "01/01/2018 00:00:00"
},
{
"key": "lastPurchase.PurchaseAmount",
"value": "100"
},
{
"key": "allPurchases",
"value": null
},
{
"key": "allPurchases[0].PurchaseDateTime",
"value": "01/01/2017 00:00:00"
},
{
"key": "allPurchases[0].PurchaseAmount",
"value": "100"
},
{
"key": "allPurchases[1].PurchaseDateTime",
"value": "01/01/2018 00:00:00"
},
{
"key": "allPurchases[1].PurchaseAmount",
"value": "100"
}
]
This has obviously happened because my logic doesnt have anything specific in it for processing lists
How can I change my logic so that AllPurchases is a key value pair collection with the key being allPurchases[0], allPurchases[1] and the value is separate key value collection, which would avoid key names like allPurchases[0].PurchaseAmount etc?
I need to keep the solution generic so that it will flatten any object into this structure
Paul
From what I can see you want the following.
Values and objects not in the array to be transferred to json objects in form of {key:"propertyPath", value:"valueTostring"}
Sub Objects to arrays of of key value pairs.
Arrays to indexed {key:"property[index]", value:"valueTostringOrObjectKeyValueArray"}
The following
var result = GetItmes(obj);
IEnumerable<KeyValuePair<string,object>> GetItmes(in JToken token, string path = "")
{
return token switch
{
JObject jObject => from prop in token.Children<JProperty>()
from child in GetItmes(prop.Value, string.IsNullOrEmpty(path) ? prop.Name : $"{path}.{prop.Name}")
select child,
JArray jArray => from item in jArray.Select((t, i) => (t, i))
select new KeyValuePair<string, object>($"{path}[{item.i}]",GetItmes(item.t)),
JValue jValue => new[] {
new KeyValuePair<string, object>(path, (object)jValue?.ToString())
},
_ => Enumerable.Empty<KeyValuePair<string, object>>(),
};
}
Will create
[
{
"key": "name",
"value": "Joe Bloggs"
},
{
"key": "address",
"value": "An adddress somewhere"
},
{
"key": "lastPurchase.PurchaseDateTime",
"value": "1/1/2018 12:00:00 AM"
},
{
"key": "lastPurchase.PurchaseAmount",
"value": "100"
},
{
"key": "AllPurchases[0]",
"value": [
{
"key": "PurchaseDateTime",
"value": "1/1/2017 12:00:00 AM"
},
{
"key": "PurchaseAmount",
"value": "100"
}
]
},
{
"key": "AllPurchases[1]",
"value": [
{
"key": "PurchaseDateTime",
"value": "1/1/2018 12:00:00 AM"
},
{
"key": "PurchaseAmount",
"value": "100"
}
]
}
]
This code is recursive and unoptimized I am sure there could be a much more efficient way to do this.
For
IEnumerable<KeyValuePair<string, object>> GetItmes(JToken token, string path = "")
{
switch (token)
{
case JObject jObject:
return from prop in token.Children<JProperty>()
from child in GetItmes(prop.Value, string.IsNullOrEmpty(path) ? prop.Name : $"{path}.{prop.Name}")
select child;
case JArray jArray:
return from item in jArray.Select((t, i) => (t, i))
select new KeyValuePair<string, object>($"{path}[{item.i}]", GetItmes(item.t));
case JValue jValue:
return new[] {
new KeyValuePair<string, object>(path, (object)jValue?.ToString())
};
default: return Enumerable.Empty<KeyValuePair<string, object>>();
};
}
code
public string getallcustomer()
{
DataTable dt = new DataTable();
CustomerService _customerService = new CustomerService();
dt = _customerService.Getallcustomer();
List<Dictionary<string, object>> lstPersons = _customerService.GetTableRows(dt);
// var json = JsonSerializer.Serialize(lstPersons);
//return Json(lstPersons, JsonRequestBehavior.AllowGet);
string json = JsonConvert.SerializeObject(lstPersons);
return json;
}
output:
"[{\"FirstName\":\"gateway\",\"PhoneNumber\":\"\",\"Balance\":-10.0000,\"CompanyName\":\"gateway\",\"Email\":\"1gateway#Sipkernel.com\",\"CustomerID\":1},{\"FirstName\":\"a-Office\",\"PhoneNumber\":null,\"Balance\":20.0000,\"CompanyName\":\"a-Office\",\"Email\":\"office#a.com\",\"CustomerID\":2}]"
i got the solution.successfully done.guys no need to serialize the list objects again.I can post the codes here.No need to return as string.
//controller
public List<getallaccountDto> getallcustomer()
{
DataTable dt = new DataTable();
CustomerService _customerService = new CustomerService();
dt = _customerService.Getallcustomer();
return _customerService.GetTableRows(dt);
}
//model dto
public class GetAllCustomersDto
{
public List<getallaccountDto> accounts { get; set; }
}
//business layer
//modified prince
public List<getallaccountDto> GetTableRows(DataTable dtData)
{
List<getallaccountDto> customerList = new List<getallaccountDto>();
getallaccountDto customer = null;
foreach (DataRow dr in dtData.Rows)
{
customer = new getallaccountDto();
customer.Name = dr["FirstName"].ToString();
customer.Phone = dr["PhoneNumber"].ToString();
customer.Balance = dr["Balance"].ToString();
customer.company = dr["CompanyName"].ToString();
customer.Email = dr["Email"].ToString();
customer.CustomerID = dr["CustomerID"].ToString();
customerList.Add(customer);
}
return customerList;
}
// this will return correct json responses.i have tested it with postman and swagger...successfully done;
[
{
"CustomerID": "1",
"Name": "gateway",
"Phone": "",
"Balance": "-10.0000",
"company": "gateway",
"Email": "1gateway#Sipkernel.com"
},
{
"CustomerID": "2",
"Name": "IPsmarx-Office",
"Phone": "",
"Balance": "20.0000",
"company": "IPsmarx-Office",
"Email": "office#ipsmarx.com"
},
{
"CustomerID": "3",
"Name": "khan",
"Phone": "",
"Balance": "23.0000",
"company": "Test",
"Email": "srk#king.com"
}]
That is because you are returning a string and the web api framework is serializing the string into JSON string literal so the entire thing is wrapped in double quotes (and quotes within are escaped using a backslash).
Fix
Change your action so it is returning IHttpActionResult: This is better anyways in case you wanted to return an error or something else.
public IHttpActionResult GetAllCustomers()
{
// code....
return Json(lstPersons);
}
I receive the error "Object serialized to Property. JObject instance expected." when trying to use the following:
SortedList<string,string> results = new SortedList<string,string>();
results.Add("BOBB", "Bob Brattwurst");
results.Add("DANG", "Dan Germany");
results.Add("KON", "Konrad Plith");
JObject output = JObject.FromObject(
new JProperty("suggestions",
new JArray(
from r in results
orderby r.Value
select new JObject(
new JProperty("value", r.Key),
new JProperty("data", r.Value)
)
)
)
);
The error occurs when setting the output variable.
This is placed in a Web service, and the expected Json result should look like:
{
"suggestions": [
{ "value": "BOBB", "data": "Bob Brattwurst" },
{ "value": "DANG", "data": "Dan Germany" },
{ "value": "KON", "data": "Konraid Plith" }
]
}
I've checked against an example i found here: http://www.newtonsoft.com/json/help/html/CreatingLINQtoJSON.htm
However i don't quite see the issue.
you could read your data into a custom data structure (or anonymous types if you prefer), which represents your json:
public class JsonContainer
{
[JsonProperty("suggestions")]
public List<JsonData> Suggestions { get;set; }
}
public class JsonData
{
[JsonProperty("value")]
public string Value { get; set; }
[JsonProperty("data")]
public string Data { get; set; }
}
// ...
var results = new SortedList<string, string>();
results.Add("BOBB", "Bob Brattwurst");
results.Add("DANG", "Dan Germany");
results.Add("KON", "Konrad Plith");
var container = new JsonDataContainer();
container.Suggestions = results.Select(r => new JsonData
{
Value = r.Key,
Data = r.Value
}).ToList();
var json = JsonConvert.SerializeObject(container);
A solution maybe to read the data into an anoymous object, following a similar take to heinzbeinz.
SortedList<string, string> results = new SortedList<string, string>();
results.Add("BOBB", "Bob Brattwurst");
results.Add("DANG", "Dan Germany");
results.Add("KON", "Konrad Plith");
var obj = new
{
Suggestions = results.Select(x => new { Value = x.Key, Data = x.Value }).ToList()
};
var jsonString = JsonConvert.SerializeObject(obj);