C# - Remove multiple backslash from JSON data [duplicate] - c#

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);
}

Related

how to get the request_id from the below json string in C#

Please help, I'm stuck with this
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.WriteLine(result);
}
output :
{
"request_number":"REQ0010201",
"request_id":"b1c8ba46db3ffa807ea0f4e9bf9619ca",
"sys_id":"35c8ba46db3ffa807ea0f4e9bf9619ca"
}
But I want output as only request_id to be printed : b1c8ba46db3ffa807ea0f4e9bf9619ca
if the return data is a json you can two options:
Using substring and indexof in a string for search the data after request_id":"
Serealize the json into a class and use in a class. For this you could use the classes of microsoft or newtonsoft . I prefer this option
see this link
Hope I help you
create a class like this:
public class myresultclass
{
public string request_number {get;set;}
public string request_id {get;set;}
public string sys_id {get;set;}
}
then you chango your function so:
using System.Web.Script.Serialization;
using System.IO;
public string mymethod()
{
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(result)))
{
// Deserialization from JSON
DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(myresultclass));
myresultclass obj = (myresultclass)deserializer.ReadObject(ms);
}
Console.WriteLine(result);
Console.WriteLine(myresultclass.request_id);
}
}
Note: I write this with notepad if doesn't work get me the error :)
You can easy do it via JSON.NET
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
var jObject = JObject.Parse(result);
var value = (string)jObject["request_id"];
Console.WriteLine(value);
}
if You Are Sure That The Request Id Will Always By The Second Attr in The Json Object Then You Can Do Some String Manipulation
string.Split(',') Will Return Array Of Strings Split By The Comma , Now We Know That The Request Id Is The Second Eelment In This Array So string.Split(',')[1] Should return The Following String "request_id":"b1c8ba46db3ffa807ea0f4e9bf9619ca"
if U Chain Another Split But this Time With Colon and Got The Second Member Of The Out Put Array It Will Be The Id Value string.Split(':')[1]
If You Don't Want The Quotation Mark You Can Do String.Replace("\"",string.Empty)
So Your Code Should be
JsonObject.Split(',')[1].Split(':')[1].Replace("\"",string.Empty)
You Could Split By The Colon From The First Time But I Want To Explain More
if You Don't Like That You Can Use NewtonSoft.Json Package To Deserialize The Json Object To Previously Created R

Double Label for Json Property C#

I need to pass a Json object to an API, but the API requires the Json properties to have a double label of sorts, such as:
{
"name:id":"1234"
}
However, using Newtonsoft.Json.Linq, I can't get this to format the label exactly. Here is what I've tried so far (which throws an error)
dynamic json= new JObject();
json.name.id = "1234";
Doing
json.id = "1234";
Works just fine. I have also tried
json.name = new JProperty("id", "1234");
Which also throws an error. I have also tried hard coding the json file as a single string and converting that to a JObject, which also threw an error. Is what I'm trying to do possible or am I missing something? Is there another Json package I could use that would support what I want to do?
Use JObject's string indexer notation.
dynamic json = new JObject();
json["name.id"] = "1234";
Since the json is essentially built as a key/value pair, using a string indexer can allow you to overcome atypical property names.
There multiple ways to achieve that.
You can use JsonProperty attribute and specify the property name as name:id like:
class MyClass
{
[JsonProperty("name:id")]
public string Name_Id { get; set; }
}
and then you can do:
MyClass obj = new MyClass();
obj.Name_Id = "1234";
var strJson = JsonConvert.SerializeObject(obj);
and you will get back:
{"name:id":"1234"}

How to modify a deserialized object

I have a JSON string as follows
string str = "{"Id":["1799"],"Type":1,"Date":null,"Group":null,"Ids":1799}";
I want to covert it to the following format
{"Id":1799,"Type":1,"Date":null,"Group":null }
In short I want to remove the "Ids" and convert "Id" value to string.
For this I tried deserializing this string as follows-
object yourOjbect = new JavaScriptSerializer().DeserializeObject(str);
But here I am stuck. How Can I remove/change a value from this object.
I tried converting this object to array and list but could not find remove/modify option in it.
Maybe you can use the JSON framework for .NET from http://www.newtonsoft.com/json (also available as a nuget package)
Then you can use the following to Deserialize into your object
string str = "{"Id":["1799"],"Type":1,"Date":null,"Group":null,"Ids":1799}";
MyObject myObj = JsonConvert.DeserializeObject<MyObject>(json);
Then maybe create a different object for your output, and have a constructor that will accept the original object as input, and then serialise it to Json. The constructor must then do any internal conversions/changes that you require.
OtherObject other = new OtherObject(myObj); //Create new object from original.
string json = JsonConvert.SerializeObject(other);
Expando Object.
string str = "{"Id":["1799"],"Type":1,"Date":null,"Group":null,"Ids":1799}";
Initially, deserialize the json using NewtonJson lib
dynamic parsedJson = JsonConvert.DeserializeObject<dynamic>(str);
Dynamic newStr = new ExpandoObject();
newStr.Id = parsedJson.Id.ToString();
newStr.Type = parsedJson.Type;
...
then serilize the newStr:
str newJson = JsonConvert.SerializeObject(newStr);
Output :
{"Id":1799,"Type":1,"Date":null,"Group":null }

Json request failing because of backslashes in request body? [duplicate]

I am trying to serialize a list to json string using Json.NET but the return string has backslash within it, which in turn is failing a json parsing.
var x = from d in entities.Books.ToList()
select new
{
ID = d.ID,
BookName = d.BookName
};
return JsonConvert.SerializeObject(x.ToList());
The above code returns
"[{\"ID\":1,\"BookName\":\"MVC Music Store - Tutorial - v3.0\"},{\"ID\":2,\"BookName\":\"Pro.ASP.NET.MVC.3.Framework\"},{\"ID\":3,\"BookName\":\"Application Architecture Guide v2\"},{\"ID\":4,\"BookName\":\"Gang of Four Design Patterns\"},{\"ID\":5,\"BookName\":\"CS4 Pocket Reference\"}]"
which fails all JSON parsing. How can I remove these.
No. it doesn't
class Program
{
class Book
{
public int ID;
public string BookName;
}
static void Main()
{
var books = new List<Book> { new Book { ID = 1, BookName = "A" }, new Book { ID = 2, BookName = "B" } };
var x = from d in books
select new
{
ID = d.ID,
BookName = d.BookName
};
string str = JsonConvert.SerializeObject(x.ToList());
Console.WriteLine(str);
}
}
There could be two problems:
A) You are looking at the result from the debugger. To check for this, Put the JsonConvert in a temporary variable (like I did) and look at it with the debugger. Click on the arrow right of the hourglass and select Text Visualizer.
or
B) The calling method is transforming the object again to Json, so escaping everything.
string str = "Your string with slashes";
str = JToken.Parse({your string here}).ToString();
The JSON object is serialized twice.
I solved by:
Declaring the operation contract of the method response format to return JSON.
I changed the method to return an object instead of a string.
The serializing of Jason will be done automatically behind the scenes.
I was getting the same result, but with doubled escape shashes while I was unit testing some json serialization. Looking at my code I realized I am serializing the "expected" json string instead of the actual .net object. So, passing a json string to JsonConvert.SerializeObject(expectedJsonString) will simply escape it once over. This is how I came here, and this is the answer I wrote, when I realized I just did a coding mistake... Did you just realize yours?

Get value of c# dynamic property via string

I'd like to access the value of a dynamic c# property with a string:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
How can I get the value of d.value2 ("random") if I only have "value2" as a string? In javascript, I could do d["value2"] to access the value ("random"), but I'm not sure how to do this with c# and reflection. The closest I've come is this:
d.GetType().GetProperty("value2") ... but I don't know how to get the actual value from that.
As always, thanks for your help!
Once you have your PropertyInfo (from GetProperty), you need to call GetValue and pass in the instance that you want to get the value from. In your case:
d.GetType().GetProperty("value2").GetValue(d, null);
public static object GetProperty(object target, string name)
{
var site = System.Runtime.CompilerServices.CallSite<Func<System.Runtime.CompilerServices.CallSite, object, object>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, name, target.GetType(), new[]{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0,null)}));
return site.Target(site, target);
}
Add reference to Microsoft.CSharp. Works also for dynamic types and private properties and fields.
Edit: While this approach works, there is almost 20× faster method from the Microsoft.VisualBasic.dll assembly:
public static object GetProperty(object target, string name)
{
return Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(target, name, CallType.Get);
}
Dynamitey is an open source .net std library, that let's you call it like the dynamic keyword, but using the a string for the property name rather than the compiler doing it for you, and it ends up being equal to reflection speedwise (which is not nearly as fast as using the dynamic keyword, but this is due to the extra overhead of caching dynamically, where the compiler caches statically).
Dynamic.InvokeGet(d,"value2");
The easiest method for obtaining both a setter and a getter for a property which works for any type including dynamic and ExpandoObject is to use FastMember which also happens to be the fastest method around (it uses Emit).
You can either get a TypeAccessor based on a given type or an ObjectAccessor based of an instance of a given type.
Example:
var staticData = new Test { Id = 1, Name = "France" };
var objAccessor = ObjectAccessor.Create(staticData);
objAccessor["Id"].Should().Be(1);
objAccessor["Name"].Should().Be("France");
var anonymous = new { Id = 2, Name = "Hilton" };
objAccessor = ObjectAccessor.Create(anonymous);
objAccessor["Id"].Should().Be(2);
objAccessor["Name"].Should().Be("Hilton");
dynamic expando = new ExpandoObject();
expando.Id = 3;
expando.Name = "Monica";
objAccessor = ObjectAccessor.Create(expando);
objAccessor["Id"].Should().Be(3);
objAccessor["Name"].Should().Be("Monica");
var typeAccessor = TypeAccessor.Create(staticData.GetType());
typeAccessor[staticData, "Id"].Should().Be(1);
typeAccessor[staticData, "Name"].Should().Be("France");
typeAccessor = TypeAccessor.Create(anonymous.GetType());
typeAccessor[anonymous, "Id"].Should().Be(2);
typeAccessor[anonymous, "Name"].Should().Be("Hilton");
typeAccessor = TypeAccessor.Create(expando.GetType());
((int)typeAccessor[expando, "Id"]).Should().Be(3);
((string)typeAccessor[expando, "Name"]).Should().Be("Monica");
Much of the time when you ask for a dynamic object, you get an ExpandoObject (not in the question's anonymous-but-statically-typed example above, but you mention JavaScript and my chosen JSON parser JsonFx, for one, generates ExpandoObjects).
If your dynamic is in fact an ExpandoObject, you can avoid reflection by casting it to IDictionary, as described at http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx.
Once you've cast to IDictionary, you have access to useful methods like .Item and .ContainsKey
The GetProperty/GetValue does not work for Json data, it always generate a null exception, however, you may try this approach:
Serialize your object using JsonConvert:
var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));
Then access it directly casting it back to string:
var pn = (string)z["DynamicFieldName"];
It may work straight applying the Convert.ToString(request)["DynamicFieldName"], however I haven't tested.
d.GetType().GetProperty("value2")
returns a PropertyInfo object.
So then do
propertyInfo.GetValue(d)
To get properties from dynamic doc
when .GetType() returns null, try this:
var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)doc);
var val = keyValuePairs["propertyName"].ToObject<YourModel>;
This is the way i ve got the value of a property value of a dinamic:
public dynamic Post(dynamic value)
{
try
{
if (value != null)
{
var valorCampos = "";
foreach (Newtonsoft.Json.Linq.JProperty item in value)
{
if (item.Name == "valorCampo")//property name
valorCampos = item.Value.ToString();
}
}
}
catch (Exception ex)
{
}
}
Some of the solutions were not working with a valuekind object that I obtained from a json string, maybe because I did not have a concrete type in my code that was similar to the object that I would obtain from the json string, so how I went about it was
JsonElement myObject = System.Text.Json.JsonSerializer.Deserialize<JsonElement>(jsonStringRepresentationOfMyObject);
/*In this case I know that there is a property with
the name Code, otherwise use TryGetProperty. This will
still return a JsonElement*/
JsonElement propertyCode = myObject.GetProperty("Code");
/*Now with the JsonElement that represents the property,
you can use several methods to retrieve the actual value,
in this case I know that the value in the property is a string,
so I use the GetString method on the object. If I knew the value
was a double, then I would use the GetDouble() method on the object*/
string code = propertyCode.GetString();
That worked for me
In .Net core 3.1 you can try like this
d?.value2 , d?.value3
Similar to the accepted answer, you can also try GetField instead of GetProperty.
d.GetType().GetField("value2").GetValue(d);
Depending on how the actual Type was implemented, this may work when GetProperty() doesn't and can even be faster.
In case you have a dynamic variable such as a DapperRow for example you can first build up an ExpandoObject, then cast the Expando into an IDictionary<string, object>. From then on, getting a value via the name of a property is possible.
Helper method ToExpandoObject:
public static ExpandoObject ToExpandoObject(object value)
{
IDictionary<string, object> dapperRowProperties = value as IDictionary<string, object>;
IDictionary<string, object> expando = new ExpandoObject();
if (dapperRowProperties == null)
{
return expando as ExpandoObject;
}
foreach (KeyValuePair<string, object> property in dapperRowProperties)
{
if (!expando.ContainsKey(property.Key))
{
expando.Add(property.Key, property.Value);
}
else
{
//prefix the colliding key with a random guid suffixed
expando.Add(property.Key + Guid.NewGuid().ToString("N"), property.Value);
}
}
return expando as ExpandoObject;
}
Sample usage, I have marked in bold the casting which gives us access in the example, I have marked the important bits with the ** letters:
using (var transactionScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
foreach (var dynamicParametersForItem in dynamicParametersForItems)
{
var idsAfterInsertion = (await connection.QueryAsync<object>(sql, dynamicParametersForItem)).ToList();
if (idsAfterInsertion != null && idsAfterInsertion.Any())
{
**var idAfterInsertionDict = (IDictionary<string, object>) ToExpandoObject(idsAfterInsertion.First());**
string firstColumnKey = columnKeys.Select(c => c.Key).First();
**object idAfterInsertionValue = idAfterInsertionDict[firstColumnKey];**
addedIds.Add(idAfterInsertionValue); //we do not support compound keys, only items with one key column. Perhaps later versions will return multiple ids per inserted row for compound keys, this must be tested.
}
}
}
In my example, I look up a property value inside a dynamic object DapperRow and first convert the Dapper row into an ExpandoObject and cast it into a dictionary property bag as shown and mentioned in other answers here.
My sample code is the InsertMany method for Dapper extension I am working on, I wanted to grab hold of the multiple ids here after the batch insert.
Use dynamic with Newtonsoft.Json.JsonConvert.DeserializeObject:
// Get JSON string of object
var obj = new { value1 = "some", value2 = "random", value3 = "value" };
var jsonString = JsonConvert.SerializeObject(obj);
// Use dynamic with JsonConvert.DeserializeObject
dynamic d = JsonConvert.DeserializeObject(jsonString);
// output = "some"
Console.WriteLine(d["value1"]);
Sample:
https://dotnetfiddle.net/XGBLU1

Categories

Resources