The solution may be exist, but I tried few things online but i am not able to find relevant solution. Here is my scenario. I wanted to pass two models to Serialize(I user Json.JsonConvert.SerializeObject) In order to send to my API. What I done so far
On the Client: I have mOrder (Order Model) and mOPLog (Log Model). Both I have combined in to one and Send to Json Serializer then to my API
var data = new
{
DataTable1 = mOrder,
DataTable2 = mOPLog
};
string sUrl = GlobalParameters.Host + "api/Order/UpdateOrderWithLog";
string sResult = HttpHelper.httpPut(sUrl, Newtonsoft.Json.JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.Indented));
Then on the Api Controller side I have declare Like this.
public Models.ApiResult UpdateOrderWithLog(dynamic data)
{
Models.Order model = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.Order>(data.ChildrenTokens[0].First);
Its throws the error when I deserialize and bind with my model. I can receive the Data on API Controller. Here is the data, how is looks like.
{{
"DataTable1": {
"OrderID": "0000006915",
"GroupID": "0000000001",
"GroupCode": "WG01",
"GroupName": "MatGroup",
"ShiftID": "0000000001",
"ShiftCode": "WS01",
"ShiftName": "DayShift",
"OrderDate": "2019-03-08T10:25:09.243",
"OrderNO": "0000006915",
"Memo": "Test123",
"OrderDetail": [
{
"OrderDetailID": "0000007103",
"OrderID": "0000006915",
"SourceType": "IQR",
"SourceID": "0000126061",
"Memo": "",
"Accept": false
},
{
"OrderDetailID": "0000007104",
"OrderID": "0000006915",
"SourceType": "IQR",
"SourceID": "0000126062",
"Memo": "",
"Accept": false
}
]
},
"DataTable2": {
"LogID": null,
"LogType": "Update",
"OperatorName": "admin",
"OperatingTime": "2019-03-13T05:53:43.5940133+08:00",
"OperationType": "Order",
"Operation": "0000006915",
"OperationContent": "",
"OperatingSystem": "Win10",
"TerminalName": "DH01",
"IPAddress": "192.168.16.124"
}
}}
But systems throws "The remote server returned an error: (500) Internal Server Error" I am not sure, where I am making mistake. If anyone come across Json Serializing and De serializing multiple object. Any help will greatly appreciated. Thanks
Update:
I Created a class with dynamic model, then send that one to API Controller.
public class LogDyModel
{
public dynamic m1 { get; set; }
public dynamic m2 { get; set; }
}
on my Client i bind my model with this dynamic and send to my API Controller
Models.LogDyModel data = new Models.LogDyModel();
data.m1 = mOrder;
data.m2 = mOPLog;
On my API Controller
public Models.ApiResult UpdateOrderWithLog(Models.LogDyModel data)
{
var deserial = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.LogDyModel>(Newtonsoft.Json.JsonConvert.SerializeObject(data));
Models.Order model = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.Order>(Newtonsoft.Json.JsonConvert.SerializeObject(deserial.m1));
Models.OpLog mLog = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.OpLog>(Newtonsoft.Json.JsonConvert.SerializeObject(deserial.m2));
Now all is sorted as I wanted. Hope this will help someone looking similar issue. Thanks for the support whoever trying to check and help me out.
Related
I have a NodeJS Server and a C# Unity Client. The NodeJS server sends an object to the C# client.
SERVER
var obj = new Object();
obj.name = data.name;
obj.position = data.position;
var jsonString= JSON.stringify(obj);
C# Client
try
{
Debug.Log(response.ToString()); // WORKS the result is
/*
[
{
"name": "Peter",
"position": "(13.6, 1.5, 2.3)"
}
]
*/
Debug.Log(response.GetValue(1).ToString()); // Don't work, receive in console (ERROR).
}
catch
{
Debug.Log("Error");
}
Output
[
{
"name": "Peter",
"position": "(13.6, 1.5, 2.3)"
}
]
So I try to read the JSON to get the Value Name and Position.
I have already tried the following:
string resVal1 = response.GetValue<string>();
Enemy resVal2 = response.GetValue<Enemy>(1);
string enemyName= response.GetValue(1).Value<string>("name");
Source:
https://github.com/doghappy/socket.io-client-csharp
I also only get "Error" here. What am I doing wrong? How do I get name and position from the JSON string. I have not much experience with JSON.
The JSON returned is an array with a single element, that element is an object with 2 properties - one of which is name so I suspect he correct code to read that would be:
string enemyName= response.GetValue(0).Value<string>("name");
I'm working on a project that involves automating API calls using a Swagger Definition. I download the swagger.json file. The structure of the JSON Object I need to parse is not consistent. When parsing paths, there are a list of objects, then within that they have the methods that can be used for that specific path. I can retrieve just the path using various string methods but my question was, is there a good way to parse json if the JSON is structured in such a way that it does not have a firm key? Here is an example of what I mean:
{"/user": {
"post": {
"tags": [
"user"
],
"summary": "Create user",
"description": "This can only be done by the logged in user.",
"operationId": "createUser",
"consumes": [
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Created user object",
"required": true,
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
}
If I wanted to just parse that path and retrieve the method object how could I go about that considering sometimes the object will be "post" or sometimes it will be "get", "put", etc depending on what is allowable for the path.
JObject jsonResp = swaggerDownload();
JObject paths = (JObject)jsonResp["paths"];
foreach (var i in paths)
{
string pathToString = i.ToString();
var shaveSomethings = pathToString.Substring(1, something.Length - 2);
var pathAndJson = shaveSomethings.Split(new[] { ',' }, 2);
string correctJsonStructure = "{\"" + pathAndJson[0] + "\":" + pathAndJson[1] + "}";
JObject bd = JObject.Parse(correctJsonStructure);
//dynamic pathsTest = JsonConvert.DeserializeObject<dynamic>(correctJsonStructure);
//JObject result = JsonConvert.DeserializeObject<JObject>(correctJsonStructure);
//Console.WriteLine(bd["/user"]);
}
The swagger.json file should have full definition of each entity that endpoints return. You can follow How to create Rest API client to get a working client.
I've dealt with an API where responses didn't always match the definition. I saved all responses to a store/log first and then would try to de-serialize JSON. In case of an exception I would go back to store/log and see what was different and update my code to accommodate for the change. After few iterations there were no new changes and the ordeal was over.
Hope that helps.
I'm trying to return a json file from a HTTP POST request from Slack. I am using netcoreapp3.1 along with the Newtonsoft.Json NuGet. Right now my HTTP POST function looks like this.
public async Task<ActionResult> SlashCommand([FromForm] SlackSlashCommand request)
{
var retVal = new JsonResult(GetBlock());
return retVal;
}
GetBlock() is a function that returns a class that I created. This works currently, but everytime I want to modify the json that it returns, I have to modify that class. I would really love to just have a json in string format that I can copy and paste into my code and then return to Slack in json format.
Is there a way to do this? I've been trying to use JsonConvert.DeserializeObject(str); but I'm using it incorrectly. From what I understand, that function takes in an string and converts it to an object. I need to take in a string and convert it to a Microsoft.AspNetCore.Mvc.ActionResult json.
Any help? Thanks.
An alternative option is to use an anonymous type, which will be less vulnerable to becoming invalid JSON (a simple typo in your JSON string could render the entire block of JSON unreadable):
var data = new
{
blocks = new object[] {
new {
type = "section",
text = new {
type = "plain_text",
text = "Hello!",
emoji = true
}
},
new {
type = "divider"
},
new {
type = "actions",
elements = new object[] {
new {
type = "button",
text = new {
type = "plain_text",
text = "Help"
},
value = "helpButton"
}
}
}
}
};
return new JsonResult(data);
Produces:
{
"blocks": [
{
"type": "section",
"text":
{
"type": "plain_text",
"text": "Hello!",
"emoji": true
}
},
{
"type": "divider"
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text":
{
"type": "plain_text",
"text": "help"
},
"value": "helpButton"
}
]
}
]
}
Try it online
I found an answer.
This is my JSON in string format:
string str = "{\"blocks\": [{\"type\": \"section\",\"text\": {\"type\": \"plain_text\",\"text\": \"Hello!\",\"emoji\": true}},{\"type\": \"divider\"},{\"type\": \"actions\",\"elements\": [{\"type\": \"button\",\"text\": {\"type\": \"plain_text\",\"text\": \"Help\"},\"value\": \"helpButton\"}]}]}";
And then this is my function:
public async Task<ActionResult> SlashCommand([FromForm] SlackSlashCommand request)
{
var retVal = new JsonResult(JsonConvert.DeserializeObject<object>(str));
return retVal;
}
This works quite well. Sorry if I didn't give too much info.
I have two asp.net mvc apps that am trying to get to communicate with each other by sending a complex serialized object from one of the app to the other.
But when the data reaches the other end, the object comes in as a list of array of key-value pair. Below are the details of the what am trying to send/recieve.
Here is the code that am using to send the json object
using (var hc = new HttpClient())
{
hc.DefaultRequestHeaders.Accept.Clear();
hc.DefaultRequestHeaders.Accept.Add(Media);
var dict = new Dictionary<string, DejaVuObject> {{"Entity", obj}};
var strinified = JsonConvert.SerializeObject(dict);
var stringContent = new StringContent(strinified, Encoding.UTF8, "application/json");
var response = await hc.PostAsync(url, stringContent);
return response;
}
The receiving method signature
[HttpPost]
public ActionResult RecieveEntity(Dictionary<string, object> post)
Here is what am sending
{
"Main Service ID": "1",
"Node ID": "",
"Parameters": [
{
"Name": "firstname",
"Validation": {
"Entity": 0,
"EntityListFilter": "",
"IsNotEditable": false,
"IsPrimaryIdentifier": false,
"IsRequired": true,
"IsUnique": false,
"Parameter Format": 0,
"ParameterMode": ""
}
}
],
"CustomEvents": [
{
"Description": "event description",
"Message": "new message",
"MilestoneCondition": "milestone information.",
"Name": "new message",
"TheFields": []
}
],
"Processings String": "Action failed.[TN01-31:Action failed]"
}
Here is what am receiving
{
"Processings String": "Action failed.[TC01-71:Action failed while processing the request.]::Action succeeded.[TC01-54:Processing this command was successful.]",
"Parameters": "[Name, Firstname][Validation, ][Key, 2e431711-2ba9-40ef-985e-dbfa8c13a932][isrequired, True][fieldname, ][Name, Lastname][Validation, ][Key, be4de2d6-d39e-44fa-8f31-b4b0964f82da]",
"CustomEvents": "[Description, Processing this command was successful][Message, Action suceeded][MilestoneCondition, When command processing suceeds.][Name, Action suceeded][TheFields, System.Collections.Generic.List`1[System.Dynamic.DejaVuObject]]",
"Main Service ID": "1"
}
If you look properly in what comes into the other system, you will find that the of most of the inner object is an array of key/value pair instead of ordinary array of objects that was sent. What am I doing wrong, and how do i go about correcting it?
Its the fact that you're using a dictionary type to receive the content. At the point the data packet is sent from the app1 its as per your definition. So updating app1 isn't going to help you.
As #Krishna has suggested update the signature to use dynamic, or you can extend your current app2 method to deal with the new interface.
Do you have an example of the data packet from one of the existing integrated apps?
So i'm trying to deserialise a JSON response implicitly back into a object instance using the following code.
DataContractJsonSerializer jsonSerialiser = new DataContractJsonSerializer(responseType);
responseBase = jsonSerialiser.ReadObject(responseStream);
The response if piped out as a string looks as follows
{
"20170317112739": {
"start": {
"SQ": 4577,
"TS": "2017-03-17T11:26:59",
"FisCode": "_R1-AT1_001/1_SQ4577_2017-03-17T11:26:59_0,00_0,00_0,00_0,00_0,00_vr1zl86Y_49e862eb_rNvvLM3FKh4=_DGZt+z+A3fY8zLlt2E55R8zCD/wf7yw9q/VivAiaNtxNpaTkhlTONAsD6yc+8Vcxwnm/lBalIwEI6GswC04kqg=="
},
"close": {
"SQ": 4667,
"TS": "2017-03-17T11:27:39",
"FisCode": "_R1-AT1_001/1_SQ4667_2017-03-17T11:27:16_0,00_0,00_0,00_0,00_0,00_r/82sV+w_49e862eb_FD/gDnivnes=_LKmvkk5OEoL7EFIebQU73VDVfPGzRGOyKNLlIW1mJkvPpqS0oVdWmqiNGR0cnpT35ArF++XzO1D/q7keTJe4cA=="
}
},
"current": {
"start": {
"SQ": 4670,
"TS": "2017-03-17T11:27:39",
"FisCode": "_R1-AT1_0/1_SQ4670_2017-03-17T11:27:39_0,00_0,00_0,00_0,00_0,00_/agx6rsw_49e862eb_qTh1/lCawvo=_f7yNP/+WUWZCojerZ9fe/wID1gll0I37swEKsauV8h7g8gSCFZ2Ykg45JjkO7BrChCBkl0ewohuGdbP4haLbrQ=="
},
"2017-03": {
"SQ": 4673,
"TS": "2017-03-17T11:27:39",
"FisCode": "_R1-AT1_0/1_SQ4670_2017-03-17T11:27:39_0,00_0,00_0,00_0,00_0,00_/agx6rsw_49e862eb_qTh1/lCawvo=_f7yNP/+WUWZCojerZ9fe/wID1gll0I37swEKsauV8h7g8gSCFZ2Ykg45JjkO7BrChCBkl0ewohuGdbP4haLbrQ=="
}
},
"lic": "0SvXs"
}
Simple responses from the JSON service are no problem i can simply decorate these with [DataContract] and [DataMember].
The problem with this particular service response is that item names such as "2017-03" will change depending on when the call is made to during other months/years.
How do i deal with this in C#?, can someone supply an example of how my class should look?
For the life of me i cannot get this data into my object class!
You can have a dynamic dictionary as suggested in this post Deserialize JSON into C# dynamic object?
Or you can implement something like this with the help of System.Web.Helpers
using (StreamReader r = new StreamReader("sample.json"))
{
string json = r.ReadToEnd();
dynamic data = Json.Decode(json);
Console.WriteLine(data["20170317112739"].start.sq);
}
Here sample.json contains your sample JSON response.