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?
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);
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>();
I need help with uploading files to Slack.
I have a Slack-App that is working with my code(below) so far. But all I can do is post messages. I can not attach images to the messages - because I do not understand how to use the so called "methods" and the syntax Slack is "showing" on their API-page.
This creates my "content" and below its just a Stream for reading a file I could upload:
public class PostMessage
{
public FormUrlEncodedContent Content(string message, string file)
{
var values = new Dictionary<string, string>
{
{"token", "xoxp-myToken"},
{ "username", "X"},
{ "channel", "myChannel"},
{ "as_user", "false"},
{"text", message},
{ "content", file},
{ "attachments","[{ \"fallback\":\"dummy\", \"text\":\"this is a waste of time\"}]"}
};
var content = new FormUrlEncodedContent(values);
return content;
}
}
public class PostFile
{
String path = #"C:\Users\f.held\Desktop\Held-Docs\dagged.jpg";
public string ReadImageFile()
{
FileInfo fileInfo = new FileInfo(path);
long imageFileLength = fileInfo.Length;
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
byte[] imageData = br.ReadBytes((int)imageFileLength);
var str = Encoding.Default.GetString(imageData);
return str;
}
}
}
The client that communicates:
public class SlackClient
{
private readonly Uri _webhookUrl;
private readonly HttpClient _httpClient = new HttpClient {};
public SlackClient(Uri webhookUrl)
{
_webhookUrl = webhookUrl;
}
public async Task<HttpResponseMessage> SendMessageAsync(FormUrlEncodedContent content)
{
var response = await _httpClient.PostAsync(_webhookUrl, content);
return response;
}
}
}
The Main:
public static void Main(string[] args)
{
Task.WaitAll(IntegrateWithSlackAsync());
}
private static async Task IntegrateWithSlackAsync()
{
var webhookUrl = new Uri("https://slack.com/api/files.upload");
var slackClient = new SlackClient(webhookUrl);
PostMessage PM = new PostMessage();
PostFile PF = new PostFile();
while (true)
{
Console.Write("Type a message: ");
var message = Console.ReadLine();
var testFile = PF.ReadImageFile();
FormUrlEncodedContent payload = PM.Content(message, testFile);
var response = await slackClient.SendMessageAsync(payload);
var isValid = response.IsSuccessStatusCode ? "valid" : "invalid";
Console.WriteLine($"Received {isValid} response.");
Console.WriteLine(response);
response.Dispose();
}
}
}
}
If somebody has an example on what a upload has to look like. Or even better,
if somebody could really explain the syntax these Slack-Messages have to have.
That would be great! I still do not know where and HOW I should put the so called
"Accepted content types: multipart/form-data, application/x-www-form-urlencoded" to my upload. I just can not find examples on this...
Edit:
What confuses me needlesly is that Slack states they have an extra method called file.upload - but we shouldn't use it anymore, we should use just postMessage.
But how would I "pack" a file in a message? My syntax always seems to be off. Especially when it comes to "content"...
I just can not figure out what the c#-code has to look like. Where do I declare the aforementioned "content type"?
Another problem is, it always sends my messages through - means I get a 200-response from the server. But it never shows the file (which probably means the syntax is off) Or I get the 200-response but the message never shows in Slack.
Images in message
If you want to include an image in your message (along with some text) you can do so by adding images as message attachment to a normal message send with chat.postMessage.
For that you need a public URL of your image and that link with the image_url property to an attachment. That attachment can also contain text, and you can add multiple attachments to your message.
This is how it looks like:
And here is how this message looks in JSON:
{
"channel": "test",
"text": "This is a message example with images in the attachment",
"attachments": [
{
"fallback": "game over",
"text": "This is some text in the attachement",
"image_url": "https://i.imgur.com/jO9N3eJ.jpg"
}
]
}
Uploading images
The image URL needs to be publicly accessible on the Internet. So you need to host your image file on a public webserver or upload it to a image cloud service (e.g. imgur.com).
You can also use Slack as cloud service for your images. Here is how that works:
Upload to Slack: Upload your image to your Slack workspace with files.upload
Get public URL: Get a public URL for your image file with files.sharedPublicURL. Normally all files on Slack are private, but you can only use public URLs for message attachments.
Send message: Include your image as attachment in a message: Use the permalink_public property of your image file as value for image_url
Example code
Here is a full working example in C# for first uploading an image to Slack and then using it in a message.
Note: This example requires Newtonsoft.Json.
using System;
using System.Net;
using System.Collections.Specialized;
using System.Text;
using Newtonsoft.Json;
public class SlackExample
{
// classes for converting JSON respones from API method into objects
// note that only those properties are defind that are needed for this example
// reponse from file methods
class SlackFileResponse
{
public bool ok { get; set; }
public String error { get; set; }
public SlackFile file { get; set; }
}
// a slack file
class SlackFile
{
public String id { get; set; }
public String name { get; set; }
public String permalink_public { get; set; }
}
// reponse from message methods
class SlackMessageResponse
{
public bool ok { get; set; }
public String error { get; set; }
public String channel { get; set; }
public String ts { get; set; }
}
// a slack message attachment
class SlackAttachment
{
public String fallback { get; set; }
public String text { get; set; }
public String image_url { get; set; }
}
// main method with logic
public static void Main()
{
String token = "xoxp-YOUR-TOKEN";
/////////////////////
// Step 1: Upload file to Slack
var parameters = new NameValueCollection();
// put your token here
parameters["token"] = token;
var client1 = new WebClient();
client1.QueryString = parameters;
byte[] responseBytes1 = client1.UploadFile(
"https://slack.com/api/files.upload",
"C:\\Temp\\Stratios_down.jpg"
);
String responseString1 = Encoding.UTF8.GetString(responseBytes1);
SlackFileResponse fileResponse1 =
JsonConvert.DeserializeObject<SlackFileResponse>(responseString1);
String fileId = fileResponse1.file.id;
/////////////////////
// Step 2: Make file public and get the URL
var parameters2 = new NameValueCollection();
parameters2["token"] = token;
parameters2["file"] = fileId;
var client2 = new WebClient();
byte[] responseBytes2 = client2.UploadValues("https://slack.com/api/files.sharedPublicURL", "POST", parameters2);
String responseString2 = Encoding.UTF8.GetString(responseBytes2);
SlackFileResponse fileResponse2 =
JsonConvert.DeserializeObject<SlackFileResponse>(responseString2);
String imageUrl = fileResponse2.file.permalink_public;
/////////////////////
// Step 3: Send message including freshly uploaded image as attachment
var parameters3 = new NameValueCollection();
parameters3["token"] = token;
parameters3["channel"] = "test_new";
parameters3["text"] = "test message 2";
// create attachment
SlackAttachment attachment = new SlackAttachment();
attachment.fallback = "this did not work";
attachment.text = "this is anattachment";
attachment.image_url = imageUrl;
SlackAttachment[] attachments = { attachment };
parameters3["attachments"] = JsonConvert.SerializeObject(attachments);
var client3 = new WebClient();
byte[] responseBytes3 = client3.UploadValues("https://slack.com/api/chat.postMessage", "POST", parameters3);
String responseString3 = Encoding.UTF8.GetString(responseBytes3);
SlackMessageResponse messageResponse =
JsonConvert.DeserializeObject<SlackMessageResponse>(responseString3);
}
}
Here is a shorter working example showing how to just upload any file to Slack with C# only. The example will also automatically share the file the given channel.
I have included the logic to convert the API response from JSON, which will always be needed to determine if the API call was successful.
Note: This example requires Newtonsoft.Json
using System;
using System.Net;
using System.Collections.Specialized;
using System.Text;
using Newtonsoft.Json;
public class SlackExample
{
// classes for converting JSON respones from API method into objects
// note that only those properties are defind that are needed for this example
// reponse from file methods
class SlackFileResponse
{
public bool ok { get; set; }
public String error { get; set; }
public SlackFile file { get; set; }
}
// a slack file
class SlackFile
{
public String id { get; set; }
public String name { get; set; }
}
// main method with logic
public static void Main()
{
var parameters = new NameValueCollection();
// put your token here
parameters["token"] = "xoxp-YOUR-TOKEN";
parameters["channels"] = "test";
var client = new WebClient();
client.QueryString = parameters;
byte[] responseBytes = client.UploadFile(
"https://slack.com/api/files.upload",
"D:\\temp\\Stratios_down.jpg"
);
String responseString = Encoding.UTF8.GetString(responseBytes);
SlackFileResponse fileResponse =
JsonConvert.DeserializeObject<SlackFileResponse>(responseString);
}
}
About content types: Those are part of the header of a HTTP request and can be set manually in the WebClient object (see also this answer). However, for our case you can ignore it, because the default content types that WebClient is using for the POST request will work just fine.
Also see this answer on how to upload files with the WebClient class.
Here is another complete example for uploading a file to Slack, this time using the async approach with HttpClient.
Note: This example requires Newtonsoft.Json.
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
namespace SlackExample
{
class UploadFileExample
{
private static readonly HttpClient client = new HttpClient();
// classes for converting JSON respones from API method into objects
// note that only those properties are defind that are needed for this example
// reponse from file methods
class SlackFileResponse
{
public bool ok { get; set; }
public String error { get; set; }
public SlackFile file { get; set; }
}
// a slack file
class SlackFile
{
public String id { get; set; }
public String name { get; set; }
}
// sends a slack message asynchronous
// throws exception if message can not be sent
public static async Task UploadFileAsync(string token, string path, string channels)
{
// we need to send a request with multipart/form-data
var multiForm = new MultipartFormDataContent();
// add API method parameters
multiForm.Add(new StringContent(token), "token");
multiForm.Add(new StringContent(channels), "channels");
// add file and directly upload it
FileStream fs = File.OpenRead(path);
multiForm.Add(new StreamContent(fs), "file", Path.GetFileName(path));
// send request to API
var url = "https://slack.com/api/files.upload";
var response = await client.PostAsync(url, multiForm);
// fetch response from API
var responseJson = await response.Content.ReadAsStringAsync();
// convert JSON response to object
SlackFileResponse fileResponse =
JsonConvert.DeserializeObject<SlackFileResponse>(responseJson);
// throw exception if sending failed
if (fileResponse.ok == false)
{
throw new Exception(
"failed to upload message: " + fileResponse.error
);
}
else
{
Console.WriteLine(
"Uploaded new file with id: " + fileResponse.file.id
);
}
}
static void Main(string[] args)
{
// upload this file and wait for completion
UploadFileAsync(
"xoxp-YOUR-TOKEN",
"C:\\temp\\Stratios_down.jpg",
"test"
).Wait();
Console.ReadKey();
}
}
}
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") } };
Send array post RestSharp?
Dictionary, List<> is not compatibile ?
public class Test
{
public string key { get; set; }
public string viewType { get; set; }
public string module { get; set; }
public string method { get; set; }
public Dictionary<string, string> parameters { get; set; }
}
My class init.
Test t = new Test();
t.key = "xxxxxxxxxxxxxxxxxx";
t.viewType = "json";
t.module = "test";
t.method = "test";
t.parameters = new Dictionary<string,string>();
t.parameters.Add("p1", "data1");
Send data request
IRestResponse response = restClient.Execute<Test>(restRequest);
Send is debbuger:
[JSON]
-request
module: "test"
method: "test"
parameters:"System.Collections.Generic.Dictionary`2[System.String,System.String]"
Who RestSharp create ? ? Send Array options object ?
$postData = array(
'key' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'viewType' => 'json',
'module' => 'test',
'method' => 'test',
[options] => stdClass Object
(
[name] => 'ADIDAS'
)
);
I found this in the documentation:
To add all properties for an object as parameters, use AddObject(). To
add a file for upload, use AddFile() (request will be sent as
multipart encoded form). To include a request body (like XML or JSON),
use AddBody();
So because you are using restRequest.AddObject(), RestSharp uses the value of t.parameters.ToString() instead of serializing to JSON.
Fix: use restRequest.AddBody(t) instead. You also have to specify the content type.
request.RequestFormat = DataFormat.Json;
request.AddBody(t);
RestClient restClient = new RestClient("https:");
RestRequest restRequest = new RestRequest(Method.POST);
Test t = new Test();
t.key = ac.Password;
t.viewType = "json";
t.module = "hello";
t.method = "hello";
t.parameters = new Dictionary<string,string>();
t.parameters.Add("wddwdw", "ddd");
restRequest.AddObject(t);
IRestResponse response = restClient.Execute<Test>(restRequest);