I have two string values in a JSON object. I want to call this method in same class and use the values without using class.
I am using the following method:
public JsonResult Details()
{
return Json(new { Data = "DisplayName", result = "UniqueName" });
}
I need to use this data and result value in another method.
I am getting the value like:
var Details = JsonConvert.SerializeObject(Details());
My output is:
{
\"ContentEncoding\": null,
\"ContentType\": null,
\"Data\": {
\"Data\": \"DisplayName\",
\"result\": \"UniqueName\"
},
\"JsonRequestBehavior\": 1,
\"MaxJsonLength\": null,
\"RecursionLimit\": null
}
How do I get the data and result value from this?
The method which you are using (i.e:)
public JsonResult Details()
{
return Json(new { Data = "DisplayName", result = "UniqueName" });
}
returns a JsonResult object which has a property named Data, i.e Details().Data, which contains the data your object contains. So in order to get your object's Data and result values, you need to serialize it again.
This is the full solution:
JsonResult json = Details(); // returns JsonResult type object
string ser = JsonConvert.SerializeObject(json.Data); // serializing JsonResult object (it will give you json string)
object dec = JsonConvert.DeserializeObject(ser); // deserializing Json string (it will deserialize Json string)
JObject obj = JObject.Parse(dec.ToString()); // it will parse deserialize Json object
string name = obj["Data"].ToString(); // now after parsing deserialize Json object you can get individual values by key i.e.
string name = obj["Data"].ToString(); // will give Data value
string name = obj["result"].ToString(); // will give result value
Hope this helps.
By looking at JsonConvert.SerializeObject, I guess you are using NewtonSoft dll. In that you have JObject.Parse under Newtonsoft.Json.Linq which you can import (using Newtonsoft.Json.Linq;). You can parse that json string as
var details = JObject.Parse(your_json_string);
This will give you JObject and you can get the details as
var data = details["Data"].ToString();
JsonResult already stores the object for you, under Data. It has not been serialized yet, it simply indicates to the MVC framework to serialize it to JSON when responding to a web request.
var details = Details().Data;
Of course, this will be typed as an object - which isn't too useful. You can cast it back to the anonymous type like this:
private T CastToAnonymous<T>(object obj, T anonymousType)
{
return (T)obj;
}
var details = CastToAnonymous(Details().Data,
new { Data = string.Empty, result = string.Empty });
And then you can use it like...
var data = details.Data;
var result = details.result;
And it will be type-safe.
Related
I'm trying to pass a ViewData object from a controller that's returning JSON data, but unable to access it from the frontend.
public ActionResult GLSearchView_Read([DataSourceRequest] DataSourceRequest request, DateTime? d = null, DateTime? d2 = null, int aid = 0)
{
bool creditMemo = true
ViewData["creditMemo"] = creditMemo;
var result = Json(GLResearch.Read(aid, d, d2).ToDataSourceResult(request));
result.MaxJsonLength = int.MaxValue;
return result;
}
I'm then supposed to use the value of that boolean from the ViewData object to render something conditionally on the frontend. However, I can't seem to access that ViewData object, am I doing something wrong here?
Setting a ViewData element here doesn't make any sense because this operation does not result in rendering a view. This operation is just returning data. So if you have additional data to return, return it.
For example, you might define an anonymous object to serialize as your JSON result:
public ActionResult GLSearchView_Read([DataSourceRequest] DataSourceRequest request, DateTime? d = null, DateTime? d2 = null, int aid = 0)
{
bool creditMemo = true
var result = Json(new {
Data = GLResearch.Read(aid, d, d2).ToDataSourceResult(request),
Memo = creditMemo
});
result.MaxJsonLength = int.MaxValue;
return result;
}
This would create a top-level object which has two properties, each of which being the two different data elements you are returning.
Of course this structure is only a guess. You can structure your data however you want. The overall point is that you would:
Define the structure of the data you want to return to the client.
Populate that structure with your data.
Serialize that structure as JSON sent back to the client.
I have a json return result like the following:
Json =
{
"Id":"12345",
"FirstName":"Bob",
"LastName":"Builder",
"Links":[]
}
Links can have a list of objects of type LinkService, i want to cast even if the array is empty , so in c# i get an empty array.
I do the following
var token = JObject.Parse(Json);
var Id = token.Value<string>("Id");
var fname = token.Value<string>("FirstName");
var lbname = token.Value<bool>("LastName");
var links = JsonSerializer.Deserialize<List<LinkService>>(token.Value<Array>("Links"));
Issue is that it says cant convert System.Array to Newtonsoft.Json.JsonReader
You can convert the jToken to an object using the ToObject method:
var links = token["Links"].TObject<List<LinkService>>();
The GetValue method below receives the data for the passed in symbol in JSON format and uses the Newtonsoft.Json library to convert the data into a dynamic object. The TryGetValue method is to get the value of the field name, passed in as a parameter, from the JSON data. Finally, I return the data if the field is valid, but if the field is not valid, I return an error message.
private string GetValue(string symbol, string field)
{
string json = HttpGet(symbol, field);
dynamic obj = JsonConvert.DeserializeObject(json);
var quote = obj.query.results.quote;
JToken returnValue = null;
quote.TryGetValue(field, out returnValue);
if (returnValue != null)
return returnValue.Value();
return field + " is not a valid field name.";
}
My problem is in the line below, I get the error "There is no argument given that corresponds to the required formal parameter 'key' of 'JToken.Value(object)":
return returnValue.Value();
How can I fix this error?
I think this article is a little bit outdated. The Newtonsoft.Json library did have updates over the past years. The function value in JToken became generic. From string JToken.Value(); to T JToken.Value<T>();. You basically say to the compiler that the return value is a string.
In your case your can fix your code with:
private string GetValue(string symbol, string field)
{
string json = HttpGet(symbol, field);
dynamic obj = JsonConvert.DeserializeObject(json);
var quote = obj.query.results.quote;
JToken returnValue = null;
quote.TryGetValue(field, out returnValue);
if (returnValue != null)
return returnValue.Value<string>();
return field + " is not a valid field name.";
}
I tested this code while I was assuming that the following json came back from HttpGet(symbol, field)
string field = "Test";
string json = "{ \"query\": { \"results\": { \"quote\": { \"Test\": \"Random\" } } } }";
Given the code:
dynamic foo = new ExpandoObject();
foo.Bar = "something";
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
The output is below:
"{\"Bar\":\"something\"}"
When debugging a large json document it is hard to read - using the built in features of Newtonsoft.Json (not regex or hacks that could break things) is there any way to make the output a string with the valie:
{Bar: "something"}
If this happens to you while returning the value from a WebApi method, try returning the object itself, instead of serializing the object and returning the json string. WebApi will serialize objects to json in the response by default; if you return a string, it will escape any double quotes it finds.
So instead of:
public string Get()
{
ExpandoObject foo = new ExpandoObject();
foo.Bar = "something";
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
return json;
}
Try:
public ExpandoObject Get()
{
ExpandoObject foo = new ExpandoObject();
foo.Bar = "something";
return foo;
}
Try the JToken.Parse method. I've found that even though when I view JSON objects in the debugger and they are correct, when I go to manipulate them they end up being converted to literals (i.e. backslashes are added). The JToken.Parse method seems to avoid this.
var token = JToken.Parse(text);
So in the case of the original question it would be something like:
dynamic foo = new ExpandoObject();
foo.Bar = "something";
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
var token = JToken.Parse(json);
//Do stuff with token -- not json string
In my case specifically the issue was that using JObject.Add(json) would not recognize that my string was json and just insert the entire string as a single property. Once converted into a Jtoken however the JSON was interpreted correctly.
What you see in debugger when looking at the json value is the string value that you should use in a C# file to obtain the same value.
Indeed you could replace
dynamic foo = new ExpandoObject();
foo.Bar = "something";
string json = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
with
string json = "{\"Bar\":\"something\"}";
without changing the program's behaviour.
Thus, to obtain a different value, you should change how JsonConvert works, but JsonConvert conforms to the JSON standard, thus forget it!
If you are not actually serializing ExpandoObject (nor any other sealed class out of your control), you can use the DebuggerDisplayAttribute on the types that you are serializing in json, to define how the object will be shown during debug (in your code, the foo instance).
But a string is a string and VisualStudio is right: double-quotes must be escaped.
Old question but I found this,
In my case, I was looking at the JSON string in a debugger and I found that was adding the escaping.
And when I printed JSON to console, it was without escape characters. Hope it helps.
Instead of using Newstonsoft.Json you should employ the JavaScriptSerializer.Serialize Method:
dynamic foo = new ExpandoObject();
foo.Bar = "something";
var js = new JavaScriptSerializer( );
string json = js.Serialize(foo);
This method produces exactly the output you are looking for. I read about it here.
Its Just simple make the return IHttpActionResult and return the object
public IHttpActionResult Get()
{
ExpandoObject foo = new ExpandoObject();
foo = //query result
return ok(foo)
}
Hey I Just simply write out put to a file
using (System.IO.StreamWriter file =
new System.IO.StreamWriter(#"jsonGonna.txt", true))
{
file.WriteLine(json);
}
now just run the program and you will get without black slash and it good for big programs where you need to save JSON multiple times
Actually it has nothing to do with serializer. It's just because c# don't have single and double quotes concept like Javascipt does. So it can't show string with double quotes without escaping them.
But if you want to put string into html/ cshtml without any escapes you just need to tell compliler that like so:
window.MYVAR = JSON.parse('#Html.Raw(ViewBag.MyStringFromCSharp)');
In case you're getting your data from a controller view method in such a format and finding it difficult to work with in JavaScript. Below is an easy work around:
const CleanUpDifficultJSonData = difficultJSonData => {
const dummyElement = document.createElement('div');
dummyElement.innerHtml = difficultJSonData;
const cleanJSonData = JSON.parse(dummyElement.innerHtml);
return cleanJSonData;
};
const difficultJSonData = "{\"Bar\":\"something\"}";
console.log('cleanJSonData: ',
CleanUpDifficultJSonData(difficultJSonData));
[HttpGet]
public object Get(int id)
{
object result = "";
var db = new dbEntities();
var EO = new System.Dynamic.ExpandoObject() as IDictionary<string, Object>; //needed to return proper JSON without escape slashes
try
{
IEnumerable<usp_GetComplaint_Result> aRow = db.usp_GetComplaint(id);
string DBL_QUOTE = new string(new char[] { '"' });
result = "{";
foreach (usp_GetComplaint_Result oneRow in aRow)
{
System.Reflection.PropertyInfo[] properties = typeof(usp_GetComplaint_Result).GetProperties();
foreach(System.Reflection.PropertyInfo property in properties)
{
var vValue = property.GetValue(oneRow) == null ? "null" : property.GetValue(oneRow);
EO.Add(property.Name,vValue);
}
break;
}
}
catch (Exception ex)
{
result = ex.Message;
EO.Add("Error", result);
}
finally
{
db.Dispose();
}
return Ok(EO);
}
I have a json string that I want to parse into an object[]:
{ "Thing":"Thing","That":{"Item1":15,"Item2":"Moo","Item3":{"Count":27,"Type":"Frog"}}}
The resulting anonymous object array needs to contain each of the properties of the original json object. My issue is that JsonConvert.DeserializeObject returns a type of JContainer or JObject. I have not been able to identify a way to return a plain vanilla c# object.
This is my current non-functional code from an array of previous attempts. I do not have to use JSON.net but I would like to if possible to ensure compatibility wiith the code generating the json.
JObject deserialized = JsonConvert.DeserializeObject<JObject>(dataString);
object[] data =
deserialized.Children().Where(x => x as JProperty != null).Select(x => x.Value<Object>()).ToArray();
Update
I am using the produced object array to invoke methods via reflection. The types of the parsed json objects are not known at runtime. The problem sticking point is that JObject or JContainer object types do not match the signatures of the methods being invoked. Dynamic has this same side-effect. Methods are being invoked like this:
Type _executionType = typeof(CommandExecutionDummy);
CommandExecutionDummy provider = new CommandExecutionDummy();
var method = _executionType.GetMethod(model.Command,
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
if (method == null)
throw new InvalidCommandException(String.Format("Invalid Command - A command with a name of {0} could not be found", model.Command));
return method.Invoke(provider, model.CommandData);
you can deserialize by example, using an anonymous type like this:
string jsonString = "{name:\"me\",lastname:\"mylastname\"}";
var typeExample = new { name = "", lastname = "",data=new int[]{1,2,3} };
var result=JsonConvert.DeserializeAnonymousType(jsonString,typeExample);
int data1=result.data.Where(x => 1);
Other way in Json.Net it's using a dynamic object like this:
dynamic result2=JObject.Parse(jsonString);
A slightly different use case in which the JSON string is an array of anonymous types the following will work. Essentially it just wraps the anonymous types within an array.
string json = "[{\"Type\":\"text/xml\",\"Allowed\":\"true\"},{\"Type\":\"application/pdf\",\"Allowed\":\"true\"},{\"Type\":\"text/plain\",\"Allowed\":\"true\"}]";
JsonConvert.DeserializeAnonymousType(json, new[] { new { Type = "", Allowed = true } });
This results in the following as visualized by Linqpad.
string jsonString = "{ "Thing":"Thing","That":{"Item1":15,"Item2":"Moo","Item3":{"Count":27,"Type":"Frog"}}}"
Object[] data = JsonConvert.DeserializeObject<Object>(jsonString);
?
JObject.Parse(jsonString).ToObject<MyType>()
?