【发布时间】:2018-12-03 10:57:32
【问题描述】:
我有一个应该与“Slack”通信的小程序。在旧版本中,我使用了“Dictionary<string, string>”,然后将它们放入UrlEncodedContent - 效果很好。
现在我正在尝试创建一个 Json 对象,使用 Newtonsoft 的 Nuget 包并(在我看来)按照他们在网站上所说的方式格式化我的对象。
问题是,当我尝试发出一个简单的请求时,我的程序只运行到代码中的一个特定行(var response = await _httpClient.SendAsync(request);)然后就结束了。它不会抛出异常或显示任何类型的消息,它只是在这一行结束。我在调试时一步一步地浏览了我的代码,这就是我知道它正好在这一行结束的方式。我只是不知道为什么!
现在我的代码: 首先,我的对象...
namespace BPS.Slack
{
public class JsonObject
{
//generally needed parameters
[JsonProperty("ok")]
public bool ok { get; set; }
[JsonProperty("error")]
public string error { get; set; }
[JsonProperty("channel")]
public string channel { get; set; }
[JsonProperty("token")]
private string token = "xoxp-MyToken";
[JsonProperty("as_user")]
public bool as_user = false;
[JsonProperty("username")]
public string username { get;set; }
//--------------------------------
//only needed for textmessages
[JsonProperty("text")]
public string text { get; set; }
//--------------------------------
//for posting messages with data attached
[JsonProperty("initial_comment")]
public string initial_comment { get; set; }
[JsonProperty("file")]
public string file { get; set; }
[JsonProperty("channels")]
public string channels { get; set; }
//--------------------------------
//for getting the latest message from a channel
[JsonProperty("count")]
public string count = "1";
[JsonProperty("unreads")]
public bool unreads = true;
}
}
现在是客户:
namespace BPS.Slack
{
public class BpsHttpClient
{
private readonly HttpClient _httpClient = new HttpClient { };
public Uri UriMethod { get; set; }
public BpsHttpClient(string webhookUrl)
{
UriMethod = new Uri(webhookUrl);
}
public async Task<HttpResponseMessage> UploadFileAsync(MultipartFormDataContent requestContent)
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, UriMethod);
request.Content = requestContent;
var response = await _httpClient.SendAsync(request);
return response;
}
}
}
和主要的
namespace TestArea
{
class MainArea
{
public static void Main( string[] args)
{
try
{
Task.WhenAll(SendMessage());
}
catch(Exception ass)
{
Console.WriteLine(ass);
Console.ReadKey();
}
}
private static async Task SendMessage()
{
var client = new BpsHttpClient("https://slack.com/api/im.history");
JsonObject JO = new JsonObject();
JO.channel = "DCW21NBHD";
var Json = JsonConvert.SerializeObject(JO);
var StringJson = new StringContent(Json, Encoding.UTF8);
MultipartFormDataContent content = new MultipartFormDataContent();
content.Add(StringJson);
var Response = await client.UploadFileAsync(content);
string AnswerContent = await Response.Content.ReadAsStringAsync();
Console.WriteLine(AnswerContent);
Console.ReadKey();
}
}
}
我在旧版本中遇到了同样的问题,但只是因为我想反序列化从 Slack 获得的答案。这与我尝试将答案反序列化的对象有关。但这一次我无法弄清楚出了什么问题。但是,正如我所说,我没有任何使用序列化对象作为 Json 属性来发送请求的经验......有人知道我的代码有什么问题吗?
编辑:这个问题已经解决了。但是有一个后续问题。
好的,我发现abprubt终止的原因是
Task.WhenAll(SendMessage());
应该是
Task.WaitAll(SendMessage());为什么???有人说我应该使用WhenAll,但显然在这种情况下它不能正常工作......
现在我收到了 Slack 的回复,但现在出现了另一个问题。当我使用这种方法时:
public async Task<HttpResponseMessage> UploadFileAsync(MultipartFormDataContent requestContent) { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, UriMethod); request.Content = requestContent; var response = await _httpClient.SendAsync(request); return response; }
我总能得到答案:
{"ok":false,"error":"invalid_form_data"}
所以我试图明确地告诉它“mediaType”,我尝试了“application/json”和其他的,但是我得到了同样的错误。下面是调用上层方法的完整方法:
private static async Task SendMessage()
{
var client = new BpsHttpClient("https://slack.com/api/chat.postMessage");
JsonObject JO = new JsonObject();
JO.channel = "DCW21NBHD";
JO.text = "This is so much fun :D !";
var Json = JsonConvert.SerializeObject(JO, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var StringJson = new StringContent(Json, Encoding.UTF8, "application/json");
var requestContent = new MultipartFormDataContent();
requestContent.Add(StringJson);
var Response = await client.UploadFileAsync(requestContent);
string AnswerContent = await Response.Content.ReadAsStringAsync();
}
当我使用这个方法时:
public async Task<HttpResponseMessage> SendMessageAsync(FormUrlEncodedContent content)
{
var response = await _httpClient.PostAsync(UriMethod, content);
return response;
}
所以基本上我在此传递“FormUrlEncodedContent”而不是“MultipartFormDataContent”,然后我得到我想要的响应并且可以使用它。但是这对我来说没什么用,因为我必须使用“MultipartFormDataContent”才能发送带有我的请求的文件。
有人知道这里出了什么问题吗?为什么它不喜欢一种内容类型而是另一种?非常感谢您的提示和想法!
【问题讨论】: