Deserializing string of format "property=whatever&property2=whatever" to an object - c#

I am taking an HttpRequest and reading it to a string
var body = request.Content.ReadAsStringAsync().Result;
This body gives me a string that looks like the following:
"To=Jim&From=Dan+Bailey"
I want to serialize body to aumatically bind to an object that looks like
public class Letter
{
[JsonProperty("To")]
public string To { get; set; }
[JsonProperty("From")]
public string From { get; set; }
}
Any ideas? I tried using JsonSerializer and Newtonsoft.Json.Convert but both require a different format

Json deserializers would only work on Json strings
You may convert the querystring to a NameValueCollection directly using the utility ParseQueryString
var body = request.Content.ReadAsStringAsync().Result;
var parameters = HttpUtility.ParseQueryString(body);
For most purposes, using a NameValueCollection should suffice, but if you still need a strongly-typed object, I would suggest using either reflection, or first serialize to a json string then use Newtonsoft deserializer
var dict = new Dictionary<string, string>();
foreach (var key in parameters.Keys)
{
dict.Add(key, parameters[key]);
}
var json = JsonConvert.SerializeObject(dict);
var obj = JsonConvert.DeserializeObject<Letter>(json);

What you have is not a JSON but most likely a simple html parameter string. Looks like the format is fixed given how your class Letter looks like.
I guess you can just do it with Regex :
var match = Regex.Match("To=Jim&From=Dan+Bailey", "To=(?<To>[^&]+)&From=(?<From>[^&]+)");
var letter = new Letter() { To = match.Groups["To"].Value, From = match.Groups["From"].Value };

Related

How to only serialize a special property's value to json

YamlDotNet can deserialize a yaml document which contain json.
Suppose there is a yaml document as input like below.
fieldA: a
fieldB:
- { "subFieldA": "a1","subFieldB": "b1" }
- { "subFieldA": "a2","subFieldB": "b2" }
Then, I deserialize it and re-serialize.
class Program
{
static void Main(string[] args)
{
using var sr = new StreamReader("test.yaml");
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
var output = deserializer.Deserialize<Temp>(sr);
var serializer = new SerializerBuilder()
.Build();
Console.WriteLine(serializer.Serialize(output));
}
}
public class Temp
{
public string FieldA { get; set; }
public List<Dictionary<string, string>> FieldB { get; set; }
}
I would get output like below.
FieldA: a
FieldB:
- subFieldA: a1
subFieldB: b1
- subFieldA: a2
subFieldB: b2
But I want the property FieldB still be serialized to json.
In other words, I want to get a output same as input.
Is there a way to use YamlDotNet to achieve this effect, please?
YamlDotNet is only used for serializing and deserializing YAML. Use the .NET serialization library if all you want to do is actually serialize that dictionary. Obviously the string property cannot do anything with unless it's part of the dictionary.
using System.Text.Json;
var temp = new Temp();
temp.Dict = new Dictionary<string, string>();
temp.Dict.Add("hello", "world");
string json = JsonSerializer.Serialize(temp.Dict);
If you're asking if you can put JSON into YAML, sure, just turn it into a json string first, and add that string as a property of a separate class to serialize into YAML. I don't believe there's a way to automatically get a YAML library to be serializing portions of its stuff into JSON. You can't mix and match.

Is there a way to deserialize only a single JSON field [duplicate]

So I have a JSON string where I just want to read a specific value. How do I just pick "Read me please!" from string below?
var readString = /*Read me please!*/
JSON string:
"{\"aString\":\"Read me please!\"}"
For better understanding, how do I do the same here? (just "Read me please!"):
"{\"Result\":
{
\"aString\":\"Read me please!\",
\"anotherString\":\"Dont read me!\"
}
}"
If both alternative have different solution I would like to know both.
PS: I do not wish to save the value into object/class or so. Just temporary inside var readString.
You could write a model:
public class MyModel
{
public string AString { get; set; }
}
and then use a JSON serializer such as Json.NET:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = JsonConvert.DeserializeObject<MyModel>(readString);
Console.WriteLine(model.AString);
If you don't want to use third party solutions you could use the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = new JavaScriptSerializer().Deserialize<MyModel>(readString);
Console.WriteLine(model.AString);
Now assuming you want to handle your second JSON string you could simply adapt your model:
public class Wrapper
{
public MyModel Result { get; set; }
}
public class MyModel
{
public string AString { get; set; }
public string AnotherString { get; set; }
}
and then deserialize to this wrapper class:
string readString = ... the JSON string in your second example ...;
Wrapper wrapper = JsonConvert.DeserializeObject<Wrapper>(readString);
Console.WriteLine(wrapper.Result.AString);
Console.WriteLine(wrapper.Result.AnotherString);
UPDATE:
And if you don't want to deserialize to a model you could directly do this:
string readString = "{\"aString\":\"Read me please!\"}";
var res = (JObject)JsonConvert.DeserializeObject(readString);
Console.WriteLine(res.Value<string>("aString"));
or with the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
var serializer = new JavaScriptSerializer();
var res = (IDictionary<string, object>)serializer.DeserializeObject(readString);
Console.WriteLine(res["aString"]);
var readString = JObject.Parse(str)["aString"];
Or for your second example:
var readString2 = JObject.Parse(str2)["Result"]["aString"];
Json.NET also provides a JSON reader if you don't want to deserialize the whole thing. For example:
string json = "{\"Result\": { \"aString\":\"Read me please!\", \"anotherString\":\"Dont read me!\" } }";
using (var reader = new JsonTextReader(new StringReader(json)))
{
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "aString")
{
reader.Read();
Console.Write(reader.Value);
break;
}
}
}
Console.ReadKey();
You have to use Newtonsoft (JSON.NET) to accomplish that. Then, you can access your json property this way:
var obj = JsonConvert.DeserializeObject(yourJson);
Console.WriteLine(obj.Result.aString);
I played around with writing a generic method that can read any part of my json string. I tried a lot of the answers on this thread and it did not suit my need. So this is what I came up with. I use the following method in my service layer to read my configuration properties from the json string.
public T getValue<T>(string json,string jsonPropertyName)
{
var parsedResult= JObject.Parse(json);
return parsedResult.SelectToken(jsonPropertyName).ToObject<T>();
}
and this is how you would use it :
var result = service.getValue<List<string>>(json, "propertyName");
So you can use this to get specific properties within your json string and cast it to whatever you need it to be.

How can I add json data to a label in C#? ( windows forms )

so i want to get bitcoin price from a URL and see it in a label in my form.
URL
i tried to make a class for it with the code
public string price { get; set; }
but i don't know what to do after that, i searched a lot in google but they all show the result in list and etc
To deserialize, first you need to make a class with the attributes the JSON has. This page will help you a lot in that.
Once you have a class, you need to deserialize your JSON into that class. In C# I like to use JsonConvert from the library Newtonsoft.Json, you need to import it.
The method that deserializes it is JsonConvert.DeserializeObject.
One little example, let's say your class is called Bitcoin, then you would have to do it that way :
var myBitcoin = JsonConvert.DeserializeObject<Bitcoin>(yourJson);
EDIT: To pull your json from an URL you can use Webclient DownloadString method.
var myjson = new WebClient().DownloadString("url");
This post may also help you.
This should be your class.
public class APIResponse
{
public string symbol { get; set; }
public string price { get; set; }
}
Then in your function add these lines.
APIResponse response = new APIResponse();
response = JsonConvert.DeserializeObject<APIResponse>();
myPriceLabel.Text = response.price;
What did we do? We created a C# model same as the Json Data model and we took JSON data and converted it to APIResponse type so we can access it and use it as we like.
It can be achieved simply by converting the Json with generic object
var myBitcoin = JsonConvert.DeserializeObject<object>(yourJson);
thank you all for answering but i found the solution!
the code should be like this
string url = "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT";
using (WebClient wc = new WebClient())
{
var json = wc.DownloadString(url);
JavaScriptSerializer oJS = new JavaScriptSerializer();
PriceClass obj = new PriceClass();
obj = oJS.Deserialize<PriceClass>(json);
BTCPrice_Label.Text = obj.price;
}
and the class should be like this
using System;
public class PriceClass
{
public string symbol { get; set; }
public string price { get; set; }
}

Need to parse a JSON coming in via a Post request

I am trying to parse a JSON received in a Post request.
The JSON is as follows. It has to be agnostic as to how many records there are or what the fields are called. But the contact variable is always null when I send it via Postman. Is there something wrong with the class I throw it in to?
{
"Fields":
{
"first":"fn",
"last":"ln",
...
}
}
public class FieldsValues
{
List<KeyValuePair<string, string>> Fields = new List<KeyValuePair<string, string>>() { };
}
public void Post([FromBody]FieldsValues Fields)
{
...
}
I want to send the JSON into a Dictionary object but the value coming in is always null.
Your Json is not an array. You need square brackets to build an array.
Besides this the KeyValuePair has members named "Key" and "Value".
To match the List<KeyValuePair<string, string>> you'll need to input something like this:
{
"Fields":
[{
"Key":"first",
"Value":"fn"
}]
}
If you can't change the JSON structure yourself and the structure is really unknown to you, I would go for a method that accepts raw strings and parse that string with Newtonsoft to a dynamic object.
E.g. this code could accept your JSON:
public void Post()
{
string text = "";
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
text = reader.ReadToEnd();
dynamic dynObj = JObject.Parse(text);
var firstValue = dynObj.Fields.first.Value;
...
}

Read specific value from JSON in C#

So I have a JSON string where I just want to read a specific value. How do I just pick "Read me please!" from string below?
var readString = /*Read me please!*/
JSON string:
"{\"aString\":\"Read me please!\"}"
For better understanding, how do I do the same here? (just "Read me please!"):
"{\"Result\":
{
\"aString\":\"Read me please!\",
\"anotherString\":\"Dont read me!\"
}
}"
If both alternative have different solution I would like to know both.
PS: I do not wish to save the value into object/class or so. Just temporary inside var readString.
You could write a model:
public class MyModel
{
public string AString { get; set; }
}
and then use a JSON serializer such as Json.NET:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = JsonConvert.DeserializeObject<MyModel>(readString);
Console.WriteLine(model.AString);
If you don't want to use third party solutions you could use the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
MyModel model = new JavaScriptSerializer().Deserialize<MyModel>(readString);
Console.WriteLine(model.AString);
Now assuming you want to handle your second JSON string you could simply adapt your model:
public class Wrapper
{
public MyModel Result { get; set; }
}
public class MyModel
{
public string AString { get; set; }
public string AnotherString { get; set; }
}
and then deserialize to this wrapper class:
string readString = ... the JSON string in your second example ...;
Wrapper wrapper = JsonConvert.DeserializeObject<Wrapper>(readString);
Console.WriteLine(wrapper.Result.AString);
Console.WriteLine(wrapper.Result.AnotherString);
UPDATE:
And if you don't want to deserialize to a model you could directly do this:
string readString = "{\"aString\":\"Read me please!\"}";
var res = (JObject)JsonConvert.DeserializeObject(readString);
Console.WriteLine(res.Value<string>("aString"));
or with the built-in JavaScriptSerializer class:
string readString = "{\"aString\":\"Read me please!\"}";
var serializer = new JavaScriptSerializer();
var res = (IDictionary<string, object>)serializer.DeserializeObject(readString);
Console.WriteLine(res["aString"]);
var readString = JObject.Parse(str)["aString"];
Or for your second example:
var readString2 = JObject.Parse(str2)["Result"]["aString"];
Json.NET also provides a JSON reader if you don't want to deserialize the whole thing. For example:
string json = "{\"Result\": { \"aString\":\"Read me please!\", \"anotherString\":\"Dont read me!\" } }";
using (var reader = new JsonTextReader(new StringReader(json)))
{
while (reader.Read())
{
if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "aString")
{
reader.Read();
Console.Write(reader.Value);
break;
}
}
}
Console.ReadKey();
You have to use Newtonsoft (JSON.NET) to accomplish that. Then, you can access your json property this way:
var obj = JsonConvert.DeserializeObject(yourJson);
Console.WriteLine(obj.Result.aString);
I played around with writing a generic method that can read any part of my json string. I tried a lot of the answers on this thread and it did not suit my need. So this is what I came up with. I use the following method in my service layer to read my configuration properties from the json string.
public T getValue<T>(string json,string jsonPropertyName)
{
var parsedResult= JObject.Parse(json);
return parsedResult.SelectToken(jsonPropertyName).ToObject<T>();
}
and this is how you would use it :
var result = service.getValue<List<string>>(json, "propertyName");
So you can use this to get specific properties within your json string and cast it to whatever you need it to be.

Categories

Resources