Query string of Webclient to json string - c# - c#

I'm using below query for sending data to webAPI. It is working fine. How can I convert the query string that I used , into a json string within this function? Is it possible?
WebClient wc = new WebClient();
wc.Headers.Add("Authorization", "Bearer " + token);
wc.QueryString.Add("unique_id", (checklist_ID.ToString()));
wc.QueryString.Add("Question_no", (QNO.ToString()));
wc.QueryString.Add("Question", t1_question.Text.ToString());
wc.QueryString.Add("Password", t1_password.Text.ToString());
var data = wc.UploadValues(url, "POST", wc.QueryString);
//here I want this Querystring data in below json format
// [{"unique_id":"2233","Question_no":"43","Question":"XXXX??","Password":"testpswd"}]
var responseString = UnicodeEncoding.UTF8.GetString(data);

Use Linq and JsonConvert to get the desired result
//Use LINQ to convert the QueryString to Dictionary
var keyValuePairs = (
from key in wc.QueryString.AllKeys
from value in wc.QueryString.GetValues(key)
select new { key, value }).ToDictionary(x => x.key, x => x.value);
//Use Newtonsoft.Json to Serialize the object to json format
Console.WriteLine(JsonConvert.SerializeObject(keyValuePairs));

Related

How to Deserialize the dictionary and fetch the value of a particular key

How should I get the value of status key ?
string a = "\"[{\\\"Status\\\":\\\"Passed\\\"}]\""
tried with JObject.Parse and JArray.Parse to deserialize it and fetch the value.
getting error all the time, even if the key is present.
PS: this value is coming directly from the DB, where it is stored as a string.
using System.Text.Json;
string a = "\"[{\\\"Status\\\":\\\"Passed\\\"}]\"";
var json = JsonDocument.Parse(a).RootElement.GetString();
var jDoc = JsonDocument.Parse(json);
var dic = jDoc.RootElement[0].Deserialize<Dictionary<string, string>>();
var status = dic["Status"];
Maybe there is a better solution. But you can remove the / character and split by "
string a = "\"[{\\\"Status\\\":\\\"Passed\\\"}]\"";
var val=a.Replace("\\", "").Split(new string[] { "\"" },
StringSplitOptions.None)[4];
Here is a method can get the value, hope it can give you some help.
using Newtonsoft.Json;
string a = "\"[{\\\"Status\\\":\\\"Passed\\\"}]\"";
var b = JsonConvert.DeserializeObject(a);
var c = JsonConvert.DeserializeObject<Dictionary<string, string>[]>(b.ToString());

C# Concatenate URL with 2 or more strings in between the url

trying to get a list of dates, I need to add 2 strings in between the URL
Cant concatenate the URL right
Need help deserializing into a DateTime list
public async Task<List<DateTime>>GetDate()
{
// Original Url http://local:8796550/serv/newobj/v678/object/35b724c5424/serv/addIDinhere/dates .
List<DateTime> dates = new List<DateTime>();
var Id= "xxxxxxxxxxxxxxhola57a";
var Uri = "http://local:8796550/serv/newobj/v678/object/35b724c5424/serv/";
var Date="/dates";
var client = new HttpClient();
var ServicesDateRequest = await client.GetAsync($"{Uri}&={Id}&={Date}");
string oj = await ServicesDateRequest.Content.ReadAsStringAsync();
//here deserialized it into datetime list
var DatesJson = JsonConvert.DeserializeObject<dates>(oj);
return dates;
}
When you're using string interpolation you only need the curly braces and the expression. The "&=" that you're adding between each component is unnecessary to get to the url format you're looking for (assuming that the format you want is what the "Original Url" comment shows).
var ServicesDateRequest = await client.GetAsync($"{Uri}{Id}{Date}");
For deserialization, check out the documentation on the method you're using. Specifically, the part about Type Parameters. JsonConvert.DeserializeObject<T>(string).
Type Parameters
T
The type of the object to deserialize to.
In other words, you should be using the type that you want to deserialize (in this case List<DateTime> rather than the name of a variable.
Try this. You can use string.format to format your url with query string paramteres.
Do Deserialize, you need to use type no data.
public async Task<List<DateTime>> GetDate()
{
// Original Url http://local:8796550/serv/newobj/v678/object/35b724c5424/serv/addIDinhere/dates .
List<DateTime> dates = new List<DateTime>();
var Id = "xxxxxxxxxxxxxxhola57a";
var Date = "/dates";
var client = new HttpClient();
var formatedUrl = string.Format("http://local:8796550/serv/newobj/v678/object/35b724c5424/serv/?id={0}&date={1}", Id, Date);
var ServicesDateRequest = await client.GetAsync(formatedUrl);
string oj = await ServicesDateRequest.Content.ReadAsStringAsync();
//here deserialized it into datetime list
var DatesJson = JsonConvert.DeserializeObject<DateTime>(oj);
return DatesJson;
}

how to upload values as array using c# webclient ? eg items[]="foo" items[]="foo2"

How would you upload a parameter that is an array using c# webclient ?
public string CallWebService(string url, NameValueCollection parametres, string HttpVerb = "GET")
{
WebClient myWebClient = new WebClient();
byte[] myresponse = myWebClient.UploadValues(url, HttpVerb, parametres);
// on essaye de récuopérer l'encoding depuis les headers
// sinon on utilise l'encoding par defaut
Encoding encoding;
encoding = WebUtils.GetEncodingFrom(myWebClient.ResponseHeaders, Encoding.Default);
return encoding.GetString(myresponse);
}
CallWebService(url, new NameValueCollection {
{ "type_pj", "99_AU" },
{ "type_pj", "41_NC" },
{ "type_pj", "41_NC" }
}, "PATCH")
is not understood server side. It is seen as one string "99_AU,41_NC,41_NC".
If I use
CallWebService(url, new NameValueCollection {
{ "type_pj[]", "99_AU" },
{ "type_pj[]", "41_NC" },
{ "type_pj[]", "41_NC" }
}, "PATCH")
it is seen as an Array but it contains only one string ["99_AU,41_NC,41_NC"]
The following curl get its right.
curl -X PATCH \ https://... \ -d 'type_pj%5B%5D=99_AU&type_pj%5B%5D=41_NC&type_pj%5B%5D=41_NC'
The servers sees it as an array of 3 strings ["99_AU","41_NC","41_NC"]
How could I achieve the same using a webclient ?
[EDIT]
It looks like I confused System.Collections.Specialized.NameValueCollection and System.Web.HttpValueCollection (which is a NameValueCollection too but with additionnal features)
var nv = new NameValueCollection {};
nv.Add("type_pj[]", "99_AU");
nv.Add("type_pj[]", "41_NC");
nv.Add("withcomma", "text,with,comma");
nv.Add("type_pj[]", "41_NC");
=> nv["type_pj[]"] = "99_AU,41_NC,41_NC" // = nv[0]
=> nv["withcomma"] = "text,with,comma" // = nv[1]
var hv = HttpUtility.ParseQueryString(string.Empty);
hv.Add("type_pj[]", "99_AU");
hv.Add("type_pj[]", "41_NC");
hv.Add("withcomma", "text,with,comma");
hv.Add("type_pj[]", "41_NC");
string resp = hv.ToString();
=> hv["type_pj[]"] = "99_AU,41_NC,41_NC" // = hv[0]
=> hv["withcomma"] = "text,with,comma" // = hv[1]
In an HttpValueCollection, when you add a new value for an existing key it looks like it concatenate the new value ti the previous but under the hood it is also stored in a array.
=> hv.GetValues("type_pj[]") = ["99_AU","41_NC","41_NC"] // !!! Array of 3 strings
=> hv.GetValues("withcomma[]") = ["text,with,comma"] // !!! Array of 1 strings
The HttpValueCollection has a ToString() method that does the url encoding for you and it preserves the array struct !
=> hv.ToString() ="type_pj%5b%5d=99_AU&type_pj%5b%5d=41_NC&type_pj%5b%5d=41_NC&withcomma=text%2cwith%2ccomma"
So the best solution is probably to use uploadString as suggested by elgonzo. But instead of using Lis you could use an HttpValueCollection which ToString() method will take care of the urlencoding for you.
The problem you are facing is due to using NamedValueCollection. If you inspect the content of your NamedValueCollection in the debugger, you will notice that it aggregates all values under just one key. This is because the name keys you feed to your NamedValueCollection are all identical.
To avoid this, you will have to generate the data payload string manually. To make things simple for the Linq Select statement below in my answer, i switch to a collection that does not organize key/value pairs depending on the uniqueness of the key. For example, you could use a list like this:
var parameters = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string,string>("type_pj[]", "99_AU"),
new KeyValuePair<string,string>("type_pj[]", "41_NC"),
new KeyValuePair<string,string>("type_pj[]", "41_NC")
};
Based on this collection, you could then "manually" compose the data payload string while also making sure both names and values are properly escaped:
var dataPayload = string.Join(
"&",
parameters.Select(kvp => $"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}")
);
(There are certainly different ways and flavors of how to do this; my example here is just an illustration of the general approach.)
The last step missing is to actually send the encoded payload string and receive the server response. Based on the code in the question, you expect a server response that is text. Fortunately, WebClient has an upload method that both accepts the data to be uploaded as string as well as returning the server response as string: UploadString. Depending on the particular expectations of your server, you might need to specify the content type explicitly, too.
var myWebClient = new WebClient();
myWebClient.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded");
string responseString = myWebClient.UploadString(url, "PATCH", dataPayload);
As pointed out by #frenchone in the comments, it is also possible to generate the encoded data payload string from a NameValueCollection, albeit with a slightly more complex Linq statement:
var parameters = NameValueCollection
{
{ "type_pj[]", "99_AU" },
{ "type_pj[]", "41_NC" },
{ "type_pj[]", "41_NC" }
}
var dataPayload = string.Join(
"&",
parameters.AllKeys.SelectMany(
key => parameters.GetValues(key).Select(val => $"{Uri.EscapeDataString(key)}={Uri.EscapeDataString(val)}")
)
);

How to pass a variable in url in c#

I am trying to pass a string into a url in C#:
using (var client = new WebClient())
{
var responseStr = client.DownloadString("http://api.openweathermap.org/data/2.5 /weather?q=Groningen,nl&APPID=%207b030ffcc7338cc5f1adc4ca8e6205aa");
}
I there a way to pass a string variable, instead of ?q=Groningen
So I could use a text field to get the weather of a city.
I could not find the answer.
Thank you
In C# you can use + operator to concatenate strings.
So you can use something like following,
using (var client = new WebClient())
{
var responseStr = client.DownloadString("http://api.openweathermap.org/data/2.5 /weather?q="+CHOICE+",nl&APPID=%207b030ffcc7338cc5f1adc4ca8e6205aa");
}
CHOICE is the variable with your desired location.
More on concatenate : here
You could use string concatenation to do so:
var url = "http://.....q="+city+"&.....";
var responseStr = client.DownloadString(url);
where city is the variable that holds the city you want to pass.
Webclient client = new Webclient();
string city = "Lahore";
string appId = "123456789";
string url = "http://api.openweathermap.org/data/2.5/weather?APPID="+appId+"&q="+city+"";
var json = client.DownloadString(json);
Now de-serialize josn response as per your requirement.
Either using any way below
JavaScriptSerializer
JSON.Net library
DataContractJsonSerializer

How to Parse Json data to normal data in C#

I am beginner in c#, I have output from the website like {"result":"Invalid"} with my c# program, It seems to be Json ,I want to display these data as normal string and display it in message box and use those parsed data for validation
Program:
private async void Button_Click(object sender, RoutedEventArgs e)
{
var username = Username.Text;
var password = passbox .Password;
var postMessage = new StringContent(string.Format("username={0}&password={1}", username, password), Encoding.UTF8 , "application/x-www-form-urlencoded");
var response = await (new HttpClient()).PostAsync("http://xxx.xx.net/xx.php", postMessage);
var responseBody = await response.Content.ReadAsStringAsync();
MessageBox.Show( responseBody );
}
I want to know how to display the responseBody as normal string ?
Ideal solution depends on how complex Json string you got. If it has only single property-value pair like posted in question :
{"result":"Invalid"}
I think simple string manipulation logic will bring you the value ("Invalid") easily. Like this naive code :
var jsonString = "{\"result\":\"Invalid\"}";
//remove "{" and "}" from sting
var result = jsonString.Replace("{", "").Replace("}", "");
//separate property name from it's value
var pair = result.Split(':');
//property will contain property name : "result"
var property = pair[0];
//value will contain property value : "Invalid"
var value = pair[1];
Otherwise, if JSON response is more complex, it is not reliable to use string manipulation. I'd suggest to go with Newtonsoft.Json library as also suggested by #Mohammad.
Try using JSON.Net using below code if it returns result as output then
string json = responseBody;
JObject parsed = JObject.Parse(json);
string results = (string)parsed["result"];
Not too sure if this is the best approach... But I'm currently implementing something similar, and using a reader to... read the returned data.
System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());
string outputStr = reader.ReadToEnd();
To convert JSON object to string you should serialize it.
I'm using Newtonsoft.Json
After install above package you can use it as the following :
string jsonInString = JsonConvert.SerializeObject(responseBody);
MessageBox.Show(jsonInString);
And for convert json string to an object you can use the following :
ClassName obj = JsonConvert.DeserializeObject<ClassName>(jsonInString);

Categories

Resources