I am using C# to connect to IBM Cloudant. IBM Cloudant supports JSON queries IBM Cloudant, it is mentioned that I need to use a POST request in order to create a query but it is not explained, I am using HttpClient which has a method PostAsync method.
Does anyone have an idea how to use this method to create a query for example the following query:
{
"selector": {
"_id": {
"$gt": null
}
}
}
I had some confusion about this as well. Please refer to below.
var client = new HttpClient();
var content = new StringContent("JSON Content");
content.Headers.Add("header-name", "header value");
client.PostAsync("http://example.com/something", content);
Your JSON content can also be a C# object, which you could JSON serialize using something like Newtonsoft.Json
You could also try this version, classes for your query
public class Id{
public object gt { get; set; }
}
public class Selector{
public Id _id { get; set; }
}
public class RootObject{
public Selector selector { get; set; }
}
serialize tmpObject and PostAsync:
client.PostAsync(url, new StringContent(tmpObject.ToString(), Encoding.UTF8, "application/json"));
so i finally managed to retrieve the response of the query it is as follows:
var jsonString = "{\"selector\": {\"_id\": {\"$gt\": null}},\"fields\": [\"" + Attribute + "\"],\"sort\": [{\"_id\": \"asc\"}]}";
var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
HttpResponseMessage res = await Client.PostAsync(string.Format("https://{0}.cloudant.com/{1}/_find", User, Database), content);
StreamReader streamReader = new StreamReader(await res.Content.ReadAsStreamAsync());
JObject responseContent = (JObject)JToken.ReadFrom(new JsonTextReader(streamReader));
streamReader.Close();
var Elements =responseContent["docs"].Value<JArray>();
Related
I am pulling data from API. I am getting an error while deserializing. please help me.
error:
System.Text.Json.JsonException: '',' is invalid after a single JSON value. Expected end of data. Path: $ | LineNumber: 0 | BytePositionInLine: 128.'
data i pull:
{"firmano":128257,"adi":"- FATİH YILMAZ"},{"firmano":128446,"adi":"-MEHMET ÜSTÜN"}
my c# codes:
Index.cs :
var result = await Api<Company>.pullDataAsync("https://localhost:5001/api/PesinIskontolar/companyGet");
api.cs:
public class Api<T> where T : class
{
public async static Task<T> pullDataAsync(string url)
{
var client = new RestClient(url);
var request = new RestRequest(Method.GET);
IRestResponse response = await client.ExecuteAsync(request);
return Json_Convert<T>.deserializeProcess(apiFormat(response.Content));
}
public static string apiFormat(string response)
{
var result = response.Replace("\\", "").Replace("[","").Replace("]","");
return result.Substring(1, result.Length - 2);
}
}
Json_Convert.cs:
public class Json_Convert<T> where T : class
{
public static T deserializeProcess(string response)
{
return JsonSerializer.Deserialize<T>(response);
}
}
dal:
public string getCompany()
{
......
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
string data = JsonConvert.SerializeObject(dt);
baglanti.Close();
baglanti.Dispose();
return data;
}
api:
[HttpGet("companyGet")]
public IActionResult companyGet()
{
return Ok(_firmaServices.getCompany());
}
Since some friends said that there is a problem with the api, I added other codes.
company class:
public class Company
{
public int firmano { get; set; }
public string adi { get; set; }
}
Your JSON is invalid, should be:
[{"firmano":128257,"adi":"- FATİH YILMAZ"},{"firmano":128446,"adi":"-MEHMET ÜSTÜN"}]
instead of:
{"firmano":128257,"adi":"- FATİH YILMAZ"},{"firmano":128446,"adi":"-MEHMET ÜSTÜN"}
Also, instead of calling response.Content prior to deserialization, you need to call await response.Content.ReadAsStringAsync() method to actually read the returning json string from the server.
As you pulling a list of two companies, your deserialization should be deserializing to a list instead of a single object, so you need to delete the apiFormat method and call await Api<IEnumerable<Company>>.pullDataAsync instead of await Api<Company>.pullDataAsync
You should deserialize List< Company >, not just Company so use this code
var result = await Api<List<Company>>.pullDataAsync("https://localhost:5001/api/PesinIskontolar/companyGet");
and fix your generic code by removing apiFormat(response.Content), replace it by just content. it will prevent removing [] from your json, this is what causes an exception
public async static Task<T> pullDataAsync(string url)
{
var client = new RestClient(url);
var request = new RestRequest(Method.GET);
IRestResponse response = await client.ExecuteAsync(request);
return Json_Convert<T>.deserializeProcess(response.Content); //fix here!!!
}
and according to your response.Content, you company class should be changed
public partial class Company
{
[JsonPropertyName("firmano")]
public int firmano { get; set; }
[JsonPropertyName("Column1")]
public string adi { get; set; }
}
1.Try to use known class as Company instate of
2.Json converter does not like special characters like '(Some times People are using the ' char, to write a letter like è, and this can bracke the Json String). You can do like .Replace("'", "''")
3.Use encoding UTF8.
4.Control the API Site in Debug and see the Response creation..
5. before subtracting the end 2 chars check if the string has this chars. better do this operations after you get the response.
return result.Substring(1, result.Length - 2);
Newbie in this so sorry for the mistakes.
I have a C# app that is running and calling python functions. the functions is being called using POST method. In addition, I would like that this call will reply from python to C# object which include 4 arrays. I successfully did passing a simple string but when I am trying to pass an object, it doesnt work. Here is the code:
C# caller side
public class RootObject
{
public Array b1 { get; set; }
public Array cl { get; set; }
public Array sc { get; set; }
}
public static List<RootObject> post(string path, int Port)
{
var client = new RestClient("http://localhost:" +
Port.ToString());
var request = new RestRequest("/postmethod", Method.POST);
request.AddHeader("content-type", "application/form-data");
request.AddFile("file", path);
IRestResponse response = client.Execute(request);
var json = response.Content;
var content = response.Content; // raw content as string
List<RootObject> r;
r = JsonConvert.DeserializeObject<List<RootObject>>(json);
return r;
}
Python side
class myscoresobj:
def __init__(self):
self.b1
self.cl
self.sc
#app.route('/postmethod', methods=['POST'])
def index():
if 'file' not in request.files:
return "file not found"
file = request.files['file']
contents = file.read()
....
myscoresobj = worker(input_q, output_q)
return str(myscoresobj )
Any way how to solve this?
i am quite new to Json, i have a program which makes a put request with some json data.
i need to make the equivelant of this: { "project": { "date_closed":"2017-01-05"} }
and this is my code i need to adapt..
object instructionData = new { date_closed = DateTime.Now.ToString("yyyy-MM-dd") };
var instructionString = JsonConvert.SerializeObject(instructionData);
StringContent instruction = new StringContent(instructionString, Encoding.UTF8, "application/json");
which is currently more than i can seem to figure out...
i've looked at some converters, which just creates classes. And those i don't really know what to do with..
Hope there is someone willing to help.
Edit
i am creating a response which is being sent.
var response = instructions.GetPutResponse(instructions.GetCleanUpProjectsRequestUrl(projectId), instructions.GetJsonInstructions(instructionData), client);
GetPutResponse method:
public HttpResponseMessage GetPutResponse(string requestUrl, HttpContent httpContent, HttpClient client)
{
return client.PutAsync(requestUrl, httpContent).Result;
}
public class Project
{
public string date_closed { get; set;}
}
public class MyClass
{
public Project project { get; set;}
}
var obj = new MyClass();
obj.project = new Project();
obj.project.date_closed = DateTime.Now.ToString("yyyy-MM-dd");
var instructionString = JsonConvert.SerializeObject(obj);
Like one of comments above suggests using string concatenation which seems fair approach however if you don't want to go that route then you can use following snippet to achieve what you want. Replace below line
object instructionData = new { date_closed = DateTime.Now.ToString("yyyy-MM-dd") };
with
var instructionData = new { projects = new { date_closed = DateTime.Now.ToString("yyyy-MM-dd") } };
We have got a Odata response as below:
"{\r\n \"#odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}"
Now say we have a class:
public class myValidationResult
{
public myValidationResult()
{
Messages = new List<string>();
}
public List<string> Messages { get; set; }
public bool IsValidEntity { get; set; }
}
This class used in MyOdataController class as below:
public class MyODataController : ODataController
{
[Authorize(Roles = "Admin")]
public async Task<IHttpActionResult> Post(T entity)
{
myValidationResult vResult = new myValidationResult();
vResult.Messages.Add("message 1");
vResult.Messages.Add("message 2");
vResult.Messages.Add("message 3");
vResult.Messages.Add("message 4");
vResult.IsValidEntity = false;
var strResult = JsonConvert.SerializeObject(vResult);
var resp = Content(HttpStatusCode.BadRequest, strResult );
return resp;
}
}
For the client Consuming this, we created below Class:
public class OData<T>
{
[JsonProperty("odata.context")]
public string Metadata { get; set; }
public T value { get; set; }
}
In the method where we call the Odata method & store response in 'msg':
var resp = msg.Result.Content.ReadAsStringAsync().Result;
resp is:
"{\r\n \"#odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}"
var odatares = JsonConvert.DeserializeObject<OData<myValidationResult>>(resp);
But the above line giving error:
Can not convert value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false} to <.....namespace......>myValidationResult
Please suggest accordingly.
The OData response contains a string, not an instance of myValidationResult. Also, the response looks like it's missing some backslashes. (Are you sure the response shown is exactly what you received from the service?)
You can either fix the serialization of myValidationResult on the service:
// Don't serialize vResult yourself. OData will do it for you.
var resp = Content(HttpStatusCode.BadRequest, vResult );
Or deserialize in two steps as follows.
var data = "{\r\n \"#odata.context\":\"http://localhost/ApplicationService/model/$metadata#Edm.String\",\"value\":\"{\\\"Messages\\\":[\\\"message 1\\\",\\\"message 2\\\",\\\"message 3\\\",\\\"message 4\\\"],\\\"IsValidEntity\\\":false}\"\r\n}";
var outer = Newtonsoft.Json.JsonConvert.DeserializeObject<OData<string>>(data);
var inner = Newtonsoft.Json.JsonConvert.DeserializeObject<myValidationResult>(outer.value);
One more thing: The JsonProperty on OData<T> should be named #odata.context.
In my case the OData response did not contain a string but an object array which contains the data string as its first element. So in this case reading the data should look like this:
var outer = Newtonsoft.Json.JsonConvert.DeserializeObject<OData<object[]>>(data);
var inner = Newtonsoft.Json.JsonConvert.DeserializeObject<myValidationResult>(outer.value[0].ToString());
Sorry for asking this question again, but I just don't seem to understand the given answers :(
I need to read some JSON using JSON.net. some of the keys start with numbers, eg.
"24h_rate":22.65826595,"
When I put the JSON into http://json2csharp.com/ to make my classes, it makes it into __invalid_name__24h_total.
I am using the following to read and Deserialize the JSON
public class JsonWebClient
{
public async Task<System.IO.TextReader> DoRequestAsync(WebRequest req)
{
var task = Task.Factory.FromAsync((cb, o) => ((HttpWebRequest)o).BeginGetResponse(cb, o), res => ((HttpWebRequest)res.AsyncState).EndGetResponse(res), req);
var result = await task;
var resp = result;
var stream = resp.GetResponseStream();
var sr = new System.IO.StreamReader(stream);
return sr;
}
public async Task<T> getJsonAsync<T>(string url)
{
HttpWebRequest req = HttpWebRequest.CreateHttp(url);
req.AllowReadStreamBuffering = true;
var ret = await DoRequestAsync(req);
var response = await ret.ReadToEndAsync();
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(response);
}
}
What do I need to change to make this work?
Thanks very much.
Playing around with it a bit I found out that the deserializer you're using can't 'handle' key names that start with a number for some reason, even though it's perfectly valid JSON (checked with http://jsonlint.com/)
If you change it to this instead
{ "rate_24h":22.65826595 }
it works:
public class RootObject
{
public double rate_24h { get; set; }
}
Thanks to #Ulugbek Umirov:
Your rate_24h property should be attributed with [JsonProperty("24h_rate")] to be property deserialized by JSON.NET.