首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么两种(几乎)相似的上传文件到Slack的方法(使用c#)会导致不同的结果?

为什么两种(几乎)相似的上传文件到Slack的方法(使用c#)会导致不同的结果?
EN

Stack Overflow用户
提问于 2018-12-06 00:08:48
回答 1查看 117关注 0票数 1

所以这个问题让我很困惑。我将发布一些代码来解释这一点。首先,我有一个“旧”版本的代码(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":[]}}

好了,为什么一种方法可以做到这一点,而另一种方法不能做到呢?

感谢任何人谁有一些洞察力和知识的具体“问题”,并愿意分享!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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的标准)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53636334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档