having difficulties with c# to Json - c#

i am quite new to Json, i have a program which makes a put request with some json data.
i need to make the equivelant of this: { "project": { "date_closed":"2017-01-05"} }
and this is my code i need to adapt..
object instructionData = new { date_closed = DateTime.Now.ToString("yyyy-MM-dd") };
var instructionString = JsonConvert.SerializeObject(instructionData);
StringContent instruction = new StringContent(instructionString, Encoding.UTF8, "application/json");
which is currently more than i can seem to figure out...
i've looked at some converters, which just creates classes. And those i don't really know what to do with..
Hope there is someone willing to help.
Edit
i am creating a response which is being sent.
var response = instructions.GetPutResponse(instructions.GetCleanUpProjectsRequestUrl(projectId), instructions.GetJsonInstructions(instructionData), client);
GetPutResponse method:
public HttpResponseMessage GetPutResponse(string requestUrl, HttpContent httpContent, HttpClient client)
{
return client.PutAsync(requestUrl, httpContent).Result;
}

public class Project
{
public string date_closed { get; set;}
}
public class MyClass
{
public Project project { get; set;}
}
var obj = new MyClass();
obj.project = new Project();
obj.project.date_closed = DateTime.Now.ToString("yyyy-MM-dd");
var instructionString = JsonConvert.SerializeObject(obj);

Like one of comments above suggests using string concatenation which seems fair approach however if you don't want to go that route then you can use following snippet to achieve what you want. Replace below line
object instructionData = new { date_closed = DateTime.Now.ToString("yyyy-MM-dd") };
with
var instructionData = new { projects = new { date_closed = DateTime.Now.ToString("yyyy-MM-dd") } };

Related

Send object from python to C# using RestAPI

Newbie in this so sorry for the mistakes.
I have a C# app that is running and calling python functions. the functions is being called using POST method. In addition, I would like that this call will reply from python to C# object which include 4 arrays. I successfully did passing a simple string but when I am trying to pass an object, it doesnt work. Here is the code:
C# caller side
public class RootObject
{
public Array b1 { get; set; }
public Array cl { get; set; }
public Array sc { get; set; }
}
public static List<RootObject> post(string path, int Port)
{
var client = new RestClient("http://localhost:" +
Port.ToString());
var request = new RestRequest("/postmethod", Method.POST);
request.AddHeader("content-type", "application/form-data");
request.AddFile("file", path);
IRestResponse response = client.Execute(request);
var json = response.Content;
var content = response.Content; // raw content as string
List<RootObject> r;
r = JsonConvert.DeserializeObject<List<RootObject>>(json);
return r;
}
Python side
class myscoresobj:
def __init__(self):
self.b1
self.cl
self.sc
#app.route('/postmethod', methods=['POST'])
def index():
if 'file' not in request.files:
return "file not found"
file = request.files['file']
contents = file.read()
....
myscoresobj = worker(input_q, output_q)
return str(myscoresobj )
Any way how to solve this?

Odata Controller: How to convert Odata response to C# object at client

We have got a Odata response as below:
"{\r\n \"#odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}"
Now say we have a class:
public class myValidationResult
{
public myValidationResult()
{
Messages = new List<string>();
}
public List<string> Messages { get; set; }
public bool IsValidEntity { get; set; }
}
This class used in MyOdataController class as below:
public class MyODataController : ODataController
{
[Authorize(Roles = "Admin")]
public async Task<IHttpActionResult> Post(T entity)
{
myValidationResult vResult = new myValidationResult();
vResult.Messages.Add("message 1");
vResult.Messages.Add("message 2");
vResult.Messages.Add("message 3");
vResult.Messages.Add("message 4");
vResult.IsValidEntity = false;
var strResult = JsonConvert.SerializeObject(vResult);
var resp = Content(HttpStatusCode.BadRequest, strResult );
return resp;
}
}
For the client Consuming this, we created below Class:
public class OData<T>
{
[JsonProperty("odata.context")]
public string Metadata { get; set; }
public T value { get; set; }
}
In the method where we call the Odata method & store response in 'msg':
var resp = msg.Result.Content.ReadAsStringAsync().Result;
resp is:
"{\r\n \"#odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}"
var odatares = JsonConvert.DeserializeObject<OData<myValidationResult>>(resp);
But the above line giving error:
Can not convert value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false} to <.....namespace......>myValidationResult
Please suggest accordingly.
The OData response contains a string, not an instance of myValidationResult. Also, the response looks like it's missing some backslashes. (Are you sure the response shown is exactly what you received from the service?)
You can either fix the serialization of myValidationResult on the service:
// Don't serialize vResult yourself. OData will do it for you.
var resp = Content(HttpStatusCode.BadRequest, vResult );
Or deserialize in two steps as follows.
var data = "{\r\n \"#odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}";
var outer = Newtonsoft.Json.JsonConvert.DeserializeObject<OData<string>>(data);
var inner = Newtonsoft.Json.JsonConvert.DeserializeObject<myValidationResult>(outer.value);
One more thing: The JsonProperty on OData<T> should be named #odata.context.
In my case the OData response did not contain a string but an object array which contains the data string as its first element. So in this case reading the data should look like this:
var outer = Newtonsoft.Json.JsonConvert.DeserializeObject<OData<object[]>>(data);
var inner = Newtonsoft.Json.JsonConvert.DeserializeObject<myValidationResult>(outer.value[0].ToString());

JSON with dynamic Root-Object

problably I'm not experienced enought and my question is kind of dumb:
For learning purposes I'm trying to connect to a REST-Service, which delivers JSON-Data.
From what I've learned, the purpose of JSON is to deliver the same data to any possible client without having a State of itself.
My code is looking like this:
public static void DoSomething()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("SomeUrl"));
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// List data response.
HttpResponseMessage response = client.GetAsync("").Result;
if (response.IsSuccessStatusCode)
{
Task<Stream> readTask = response.Content.ReadAsStreamAsync();
readTask.ContinueWith(task =>
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(RootObject));
using (Stream result = task.Result)
{
result.Position = 0;
RootObject obj = (RootObject)ser.ReadObject(result);
}
});
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
}
public class Sum
{
public int id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public int summonerLevel { get; set; }
public long revisionDate { get; set; }
}
public class RootObject
{
public Sum khalgor { get; set; }
}
But here's my Problem: I've created this classes "Sum" and "RootObject" by using the Website http://json2csharp.com/, the JSON-String is looking like this:
{"khalgor":{"id":23801741,"name":"Khalgor","profileIconId":7,"summonerLevel":30,"revisionDate":1396876104000}}
The Problem: The Name "Khalgor" seems to be used as a Root-Object, but it's a Name. So if I'd like to user for another Name, I'd have to user another RootObject.
It does not make that much sense to create such a Structure, so my question: What's the best practice here? Do I map this RootObject/Property to another object manually? Do I use some Reflection to dynamically create an Property or rename it?
As usual, thanks a lot for all Responses
Matthias
Edit:
I tinkered arround a bit and that's my first idea of a solution:
public static class LOLObjectFactory
{
public static ILOLObject Create(string jsonString)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
Dictionary<String, object> entry = (jss.Deserialize<dynamic>(jsonString) as Dictionary<string, object>).First().Value as Dictionary<String, object>;
Type selectedType = null;
List<string> fieldNames = entry.Select(f => f.Key).OrderBy(f => f).ToList();
Type[] types = typeof(ILOLObject).Assembly.GetTypes();
foreach(var type in types)
{
List<string> typeProperties = type.GetProperties().Select(f => f.Name).OrderBy(f => f).ToList();
if (fieldNames.SequenceEqual(typeProperties) && typeof(ILOLObject).IsAssignableFrom(type))
{
selectedType = type;
break;
}
}
ILOLObject result = System.Activator.CreateInstance(selectedType) as ILOLObject;
foreach(var prop in result.GetType().GetProperties())
{
prop.SetValue(result, entry.First(f => f.Key == prop.Name).Value);
}
return result;
}
}
So all the objects I have have the ILOLObject implemented. I'm sure it's not working for everything, but I guess that would be a good approach?
Edit2: Just by looking at it I see I'll have a lot of work to do, but I think the idea behind it is quite clear.
I think your best bet for json "fragments" is to deserialize into a dynamic object:
dynamic stuff = JsonConvert.DeserializeObject(inputData);
Then you can deserialize parts that make sense into proper .NET objects.
SomeObject o = JsonConvert.DeserializeObject<SomeObject>(stuff["someProperty"].ToString());
If you want to ignore the root altogether (e.g. it changes its name everytime) use Json.NET to parse it into an object and ignore the topmost element. Example:
JObject obj = JObject.Parse(json);
if (obj != null)
{
var root = obj.First;
if (root != null)
{
var sumJson = root.First;
if (sumJson != null)
{
var sum = sumJson.ToObject<Sum>();
}
}
}

Returning anonymous types with Web API

When using MVC, returning adhoc Json was easy.
return Json(new { Message = "Hello"});
I'm looking for this functionality with the new Web API.
public HttpResponseMessage<object> Test()
{
return new HttpResponseMessage<object>(new { Message = "Hello" }, HttpStatusCode.OK);
}
This throws an exception as the DataContractJsonSerializer can't handle anonymous types.
I have replaced this with this JsonNetFormatter based on Json.Net.
This works if I use
public object Test()
{
return new { Message = "Hello" };
}
but I don't see the point of using Web API if I'm not returning HttpResponseMessage, I would be better off sticking with vanilla MVC. If I try and use:
public HttpResponseMessage<object> Test()
{
return new HttpResponseMessage<object>(new { Message = "Hello" }, HttpStatusCode.OK);
}
It serializes the whole HttpResponseMessage.
Can anyone guide me to a solution where I can return anonymous types within a HttpResponseMessage?
This doesn't work in the Beta release, but it does in the latest bits (built from http://aspnetwebstack.codeplex.com), so it will likely be the way for RC. You can do
public HttpResponseMessage Get()
{
return this.Request.CreateResponse(
HttpStatusCode.OK,
new { Message = "Hello", Value = 123 });
}
This answer may come bit late but as of today WebApi 2 is already out and now it is easier to do what you want, you would just have to do:
public object Message()
{
return new { Message = "hello" };
}
and along the pipeline, it will be serialized to xml or json according to client's preferences (the Accept header). Hope this helps anyone stumbling upon this question
In web API 2 you can use the new IHttpActionResult which is a replacement for HttpResponseMessage and then return a simple Json object: (Similiar to MVC)
public IHttpActionResult GetJson()
{
return Json(new { Message = "Hello"});
}
you can use JsonObject for this:
dynamic json = new JsonObject();
json.Message = "Hello";
json.Value = 123;
return new HttpResponseMessage<JsonObject>(json);
You could use an ExpandoObject. (add using System.Dynamic;)
[Route("api/message")]
[HttpGet]
public object Message()
{
dynamic expando = new ExpandoObject();
expando.message = "Hello";
expando.message2 = "World";
return expando;
}
You may also try:
var request = new HttpRequestMessage(HttpMethod.Post, "http://leojh.com");
var requestModel = new {User = "User", Password = "Password"};
request.Content = new ObjectContent(typeof(object), requestModel, new JsonMediaTypeFormatter());
In ASP.NET Web API 2.1 you can do it in a simpler way:
public dynamic Get(int id)
{
return new
{
Id = id,
Name = "X"
};
}
You can read more about this on https://www.strathweb.com/2014/02/dynamic-action-return-web-api-2-1/
public IEnumerable<object> GetList()
{
using (var context = new DBContext())
{
return context.SPersonal.Select(m =>
new
{
FirstName= m.FirstName ,
LastName = m.LastName
}).Take(5).ToList();
}
}
}
You should be able to get this to work if you use generics, as it will give you a "type" for your anonymous type. You can then bind the serializer to that.
public HttpResponseMessage<T> MakeResponse(T object, HttpStatusCode code)
{
return new HttpResponseMessage<T>(object, code);
}
If there are no DataContract or DataMebmer attributes on your class, it will fall back on serializing all public properties, which should do exactly what you're looking for.
(I won't have a chance to test this until later today, let me know if something doesn't work.)
You can encapsulate dynamic object in returning object like
public class GenericResponse : BaseResponse
{
public dynamic Data { get; set; }
}
and then in WebAPI; do something like:
[Route("api/MethodReturingDynamicData")]
[HttpPost]
public HttpResponseMessage MethodReturingDynamicData(RequestDTO request)
{
HttpResponseMessage response;
try
{
GenericResponse result = new GenericResponse();
dynamic data = new ExpandoObject();
data.Name = "Subodh";
result.Data = data;// OR assign any dynamic data here;//
response = Request.CreateResponse<dynamic>(HttpStatusCode.OK, result);
}
catch (Exception ex)
{
ApplicationLogger.LogCompleteException(ex, "GetAllListMetadataForApp", "Post");
HttpError myCustomError = new HttpError(ex.Message) { { "IsSuccess", false } };
return Request.CreateErrorResponse(HttpStatusCode.OK, myCustomError);
}
return response;
}

Convert JSON String To C# Object

Trying to convert a JSON string into an object in C#. Using a really simple test case:
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
object routes_list = json_serializer.DeserializeObject("{ \"test\":\"some data\" }");
The problem is that routes_list never gets set; it's an undefined object. Any ideas?
Or, you can use the Newtownsoft.Json library as follows:
using Newtonsoft.Json;
...
var result = JsonConvert.DeserializeObject<T>(json);
Where T is your object type that matches your JSON string.
It looks like you're trying to deserialize to a raw object. You could create a Class that represents the object that you're converting to. This would be most useful in cases where you're dealing with larger objects or JSON Strings.
For instance:
class Test {
String test;
String getTest() { return test; }
void setTest(String test) { this.test = test; }
}
Then your deserialization code would be:
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
Test routes_list =
(Test)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");
More information can be found in this tutorial:
http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx
You probably don't want to just declare routes_list as an object type. It doesn't have a .test property, so you really aren't going to get a nice object back. This is one of those places where you would be better off defining a class or a struct, or make use of the dynamic keyword.
If you really want this code to work as you have it, you'll need to know that the object returned by DeserializeObject is a generic dictionary of string,object. Here's the code to do it that way:
var json_serializer = new JavaScriptSerializer();
var routes_list = (IDictionary<string, object>)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");
Console.WriteLine(routes_list["test"]);
If you want to use the dynamic keyword, you can read how here.
If you declare a class or struct, you can call Deserialize instead of DeserializeObject like so:
class MyProgram {
struct MyObj {
public string test { get; set; }
}
static void Main(string[] args) {
var json_serializer = new JavaScriptSerializer();
MyObj routes_list = json_serializer.Deserialize<MyObj>("{ \"test\":\"some data\" }");
Console.WriteLine(routes_list.test);
Console.WriteLine("Done...");
Console.ReadKey(true);
}
}
Using dynamic object with JavaScriptSerializer.
JavaScriptSerializer serializer = new JavaScriptSerializer();
dynamic item = serializer.Deserialize<object>("{ \"test\":\"some data\" }");
string test= item["test"];
//test Result = "some data"
Newtonsoft is faster than java script serializer. ... this one depends on the Newtonsoft NuGet package, which is popular and better than the default serializer.
one line code solution.
var myclass = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Jsonstring);
Myclass oMyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<Myclass>(Jsonstring);
You can accomplished your requirement easily by using Newtonsoft.Json library. I am writing down the one example below have a look into it.
Class for the type of object you receive:
public class User
{
public int ID { get; set; }
public string Name { get; set; }
}
Code:
static void Main(string[] args)
{
string json = "{\"ID\": 1, \"Name\": \"Abdullah\"}";
User user = JsonConvert.DeserializeObject<User>(json);
Console.ReadKey();
}
this is a very simple way to parse your json.
Here's a simple class I cobbled together from various posts.... It's been tested for about 15 minutes, but seems to work for my purposes. It uses JavascriptSerializer to do the work, which can be referenced in your app using the info detailed in this post.
The below code can be run in LinqPad to test it out by:
Right clicking on your script tab in LinqPad, and choosing "Query
Properties"
Referencing the "System.Web.Extensions.dll" in "Additional References"
Adding an "Additional Namespace Imports" of
"System.Web.Script.Serialization".
Hope it helps!
void Main()
{
string json = #"
{
'glossary':
{
'title': 'example glossary',
'GlossDiv':
{
'title': 'S',
'GlossList':
{
'GlossEntry':
{
'ID': 'SGML',
'ItemNumber': 2,
'SortAs': 'SGML',
'GlossTerm': 'Standard Generalized Markup Language',
'Acronym': 'SGML',
'Abbrev': 'ISO 8879:1986',
'GlossDef':
{
'para': 'A meta-markup language, used to create markup languages such as DocBook.',
'GlossSeeAlso': ['GML', 'XML']
},
'GlossSee': 'markup'
}
}
}
}
}
";
var d = new JsonDeserializer(json);
d.GetString("glossary.title").Dump();
d.GetString("glossary.GlossDiv.title").Dump();
d.GetString("glossary.GlossDiv.GlossList.GlossEntry.ID").Dump();
d.GetInt("glossary.GlossDiv.GlossList.GlossEntry.ItemNumber").Dump();
d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef").Dump();
d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso").Dump();
d.GetObject("Some Path That Doesnt Exist.Or.Another").Dump();
}
// Define other methods and classes here
public class JsonDeserializer
{
private IDictionary<string, object> jsonData { get; set; }
public JsonDeserializer(string json)
{
var json_serializer = new JavaScriptSerializer();
jsonData = (IDictionary<string, object>)json_serializer.DeserializeObject(json);
}
public string GetString(string path)
{
return (string) GetObject(path);
}
public int? GetInt(string path)
{
int? result = null;
object o = GetObject(path);
if (o == null)
{
return result;
}
if (o is string)
{
result = Int32.Parse((string)o);
}
else
{
result = (Int32) o;
}
return result;
}
public object GetObject(string path)
{
object result = null;
var curr = jsonData;
var paths = path.Split('.');
var pathCount = paths.Count();
try
{
for (int i = 0; i < pathCount; i++)
{
var key = paths[i];
if (i == (pathCount - 1))
{
result = curr[key];
}
else
{
curr = (IDictionary<string, object>)curr[key];
}
}
}
catch
{
// Probably means an invalid path (ie object doesn't exist)
}
return result;
}
}
As tripletdad99 said
var result = JsonConvert.DeserializeObject<T>(json);
but if you don't want to create an extra object you can make it with Dictionary instead
var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(json_serializer);
add this ddl to reference to your project: System.Web.Extensions.dll
use this namespace: using System.Web.Script.Serialization;
public class IdName
{
public int Id { get; set; }
public string Name { get; set; }
}
string jsonStringSingle = "{'Id': 1, 'Name':'Thulasi Ram.S'}".Replace("'", "\"");
var entity = new JavaScriptSerializer().Deserialize<IdName>(jsonStringSingle);
string jsonStringCollection = "[{'Id': 2, 'Name':'Thulasi Ram.S'},{'Id': 2, 'Name':'Raja Ram.S'},{'Id': 3, 'Name':'Ram.S'}]".Replace("'", "\"");
var collection = new JavaScriptSerializer().Deserialize<IEnumerable<IdName>>(jsonStringCollection);
Copy your Json and paste at textbox on json2csharp and click on Generate button.
A cs class will be generated use that cs file as below
var generatedcsResponce = JsonConvert.DeserializeObject(yourJson);
Where RootObject is the name of the generated cs file;
Another fast and easy way to semi-automate these steps is to:
take the JSON you want to parse and paste it here: https://app.quicktype.io/ . Change language to C# in the drop down.
Update the name in the top left to your class name, it defaults to "Welcome".
In visual studio go to Website -> Manage Packages and use NuGet to add Json.Net from Newtonsoft.
app.quicktype.io generated serialize methods based on Newtonsoft.
Alternatively, you can now use code like:
WebClient client = new WebClient();
string myJSON = client.DownloadString("https://URL_FOR_JSON.com/JSON_STUFF");
var myClass = Newtonsoft.Json.JsonConvert.DeserializeObject(myJSON);
Convert a JSON string into an object in C#. Using below test case.. its worked for me. Here "MenuInfo" is my C# class object.
JsonTextReader reader = null;
try
{
WebClient webClient = new WebClient();
JObject result = JObject.Parse(webClient.DownloadString("YOUR URL"));
reader = new JsonTextReader(new System.IO.StringReader(result.ToString()));
reader.SupportMultipleContent = true;
}
catch(Exception)
{}
JsonSerializer serializer = new JsonSerializer();
MenuInfo menuInfo = serializer.Deserialize<MenuInfo>(reader);
First you have to include library like:
using System.Runtime.Serialization.Json;
DataContractJsonSerializer desc = new DataContractJsonSerializer(typeof(BlogSite));
string json = "{\"Description\":\"Share knowledge\",\"Name\":\"zahid\"}";
using (var ms = new MemoryStream(ASCIIEncoding.ASCII.GetBytes(json)))
{
BlogSite b = (BlogSite)desc.ReadObject(ms);
Console.WriteLine(b.Name);
Console.WriteLine(b.Description);
}
Let's assume you have a class name Student it has following fields and it has a method which will take JSON as a input and return a string Student Object.We can use JavaScriptSerializer here Convert JSON String To C# Object.std is a JSON string here.
public class Student
{
public string FirstName {get;set:}
public string LastName {get;set:}
public int[] Grades {get;set:}
}
public static Student ConvertToStudent(string std)
{
var serializer = new JavaScriptSerializer();
Return serializer.Deserialize<Student>(std);
}
Or, you can use the System.Text.Json library as follows:
using System.Text.Json;
...
var options = new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true
});
var result = JsonSerializer.Deserialize<List<T>>(json, options);
Where T is your object type that matches your JSON string.
System.Text.Json is available in:
.NET Core 2.0 and above
.NET Framework 4.6.1 and above

Categories

Resources