所以这个问题让我很困惑。我将发布一些代码来解释这一点。首先,我有一个“旧”版本的代码(c#),我用它来向Slack发布消息和文件。这段代码对我来说工作得很好!感兴趣的方法如下:
public class PostMessage
{
private string _token = "xoxp-MyToken";
public string token { get { return _token; } }
public string channel { get; set; }
public string text { get; set; }
public MultipartFormDataContent UploadFile()
{
var requestContent = new MultipartFormDataContent();
var fileContent = new StreamContent(GetFile.ReadFile());
requestContent.Add(new StringContent(token), "token");
requestContent.Add(new StringContent(channel), "channels");
requestContent.Add(fileContent, "file", Path.GetFileName(GetFile.path));
return requestContent;
}
public static class GetFile
{
public static string path = @"C:\Users\f.held\Desktop\Held-Docs\Download.jpg";
public static FileStream ReadFile()
{
FileInfo fileInfo = new FileInfo(path);
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
return fs;
}
}
是我的客户端:
public class SlackClient
{
public Uri _method { get; set; }
private readonly HttpClient _httpClient = new HttpClient {};
public SlackClient(Uri webhookUrl)
{
_method = webhookUrl;
}
public async Task<HttpResponseMessage> UploadFileAsync(MultipartFormDataContent requestContent)
{
var response = await _httpClient.PostAsync(_method, requestContent);
return response;
}
}
和我在Main中将所有这一切称为:
public static void Main(string[] args)
{
Task.WaitAll(TalkToSlackAsync());
private static async Task TalkToSlackAsync()
{
var webhookUrl = new Uri("https://slack.com/api/files.upload");
var slackClient = new SlackClient(webhookUrl);
PostMessage PM = new PostMessage();
PM.channel = "DCW21NBHD";
var cont = PM.UploadFile();
var response = await slackClient.UploadFileAsync(cont);
string content = await response.Content.ReadAsStringAsync();
}
}
到目前为止,还不错!但现在它变得有趣了。我构建了一个类似的版本,其中我使用Newtonsoft的Json NuGet-package
现在,首先是代码:
客户端:
public async Task<HttpResponseMessage> SendFileAsync(MultipartFormDataContent requestContent)
{
_httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "xoxp-MyToken");
var response = await _httpClient.PostAsync(UriMethod, requestContent);
return response;
}
使用相同的文件内存读取方法::
public class Message
{
public class GetFile // Just pass a path here as parameter!
{
public static string path = @"C:\Users\f.held\Desktop\Held-Docs\Download.jpg";
public static FileStream ReadFile()
{
FileInfo fileInfo = new FileInfo(path);
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
return fs;
}
}
序列化Json-:
public class JsonObject
{
[JsonProperty("file")]
public string file { get; set; }
[JsonProperty("channels")]
public string channels { get; set; }
}
和Main:
class MainArea
{
public static void Main( string[] args)
{
try
{
Task.WaitAll(SendMessage());
}
catch(Exception dudd)
{
Console.WriteLine(dudd);
Console.ReadKey();
}
}
private static async Task SendMessage()
{
var client = new BpsHttpClient("https://slack.com/api/files.upload");
JsonObject JO = new JsonObject();
JO.channels = "DCW21NBHD";
var Json = JsonConvert.SerializeObject(JO, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var StringJson = new StringContent(Json, Encoding.UTF8, "multipart/form-data");
var DeSon = JsonConvert.DeserializeObject(Json);
Console.WriteLine(DeSon);
Console.ReadKey();
var requestContent = new MultipartFormDataContent();
var fileContent = new StreamContent(Message.GetFile.ReadFile());
requestContent.Add(fileContent, "file", Path.GetFileName(Message.GetFile.path));
requestContent.Add(StringJson);
var ResponseFile = await client.SendFileAsync(requestContent);
Console.WriteLine(ResponseFile);
Console.ReadKey();
}
}
因此,这两种方法似乎都有效。但这些方法中的后一种方法并不将文件发布到声明的通道-它只是将文件上传到Slack。这很好,因为我可以和“public_url”一起工作,在任何频道上宣传它。但是-很大,但是-使用第一个方法,它会立即将其加载到我的频道中!在我从Slack得到的回复中,它告诉了我这一点。两者的响应是完全相同的--除了时间戳和file_id等等。但是结尾是不同的!这里是来自旧版本的响应的结尾:
"shares":{"private":{"DCW21NBHD":[{"reply_users":[],"reply_users_count":0,"reply_count":0,"ts":"1544025773.001700"}]}},"channels":[],"groups":[],"ims":["DCW21NBHD"]}}
,这是新版本的答案:
"shares":{},"channels":[],"groups":[],"ims":[]}}
好了,为什么一种方法可以做到这一点,而另一种方法不能做到呢?
感谢任何人谁有一些洞察力和知识的具体“问题”,并愿意分享!
发布于 2018-12-06 03:22:27
如files.upload
文档中所述
将参数作为参数显示在
application/x-www-form-urlencoded
查询字符串或POST正文中。此方法当前不接受application/json
。
因此,这种方法不起作用的原因是,当此方法不支持JSON时,您试图将channels
之类的API参数作为JSON提供。结果是这些属性被忽略,这就是为什么图像被上传,但没有在指定的通道中共享的原因。
要修复它,只需提供参数作为application/x-www-form-urlencoded
查询字符串,就像您在第一个示例中所做的那样。
注意,通常只有一部分Slack API方法支持使用JSON提供所列here所示的参数。如果你想使用JSON,请仔细检查API方法是否支持它,或者为了安全起见,坚持使用x-www-form-urlencoded
(这是POST的标准)。
https://stackoverflow.com/questions/53636334
复制相似问题