简体   繁体   中英

CSharp - How can I upload an image using a HTTP Request and Multipart as the Content-Type

I am using C# 4.7.2 and am using a Console and not WinForms. I am trying to get an input of a user's image path then send a post request to a ShareX Image Hoster API.

How can I keep it plain and simple using void ? EX:

public static void UploadImg(string ImagePath, string UploadAPI, string UploadKey) { }

ShareX Config:

{
    "Version": "13.2.1",
    "Name": "host",
    "DestinationType": "ImageUploader",
    "RequestMethod": "POST",
    "RequestURL": "https://ADDRESS/upload",
    "Headers": {
        "token": "name_RANDOMSTRING",
        "json": "true"
    },
    "Body": "MultipartFormData",
    "Arguments": {
        "imgfile": null
    },
    "FileFormName": "imgfile",
    "URL": "$json:url$"
}

Capturing traffic with Fiddler I can use these headers:

POST https://IMAGEHOST/api/upload HTTP/1.1
token: SPECIALKEY
json: true
Content-Type: multipart/form-data; boundary=--------------------8d8ee229124e662
User-Agent: ShareX/13.4.0
Host: IMGHOSTER
Content-Length: 7518
Connection: Keep-Alive

----------------------8d8ee229124e662
Content-Disposition: form-data; name="imgfile"; filename="851TO25E8.png"
Content-Type: image/png

Then the rest after these headers is unknown ascii bytes nonsense.

The response is:

{"url":"https://FinalShortenedURL/‌​​​‌‌​‌​‌‌​‌‌‌‌‌‌​​​‌​‌‌‌​​​​​‌​‌​‌‌‌‌‌​​‌‌‌‌​​‌‌‌‌​‌‌‌‌‌​​"}

UPDATE -.Net 4.7.2

public static async Task UploadImg(string ImagePath, string UploadAPI, string UploadKey)
{
    using (var client = new System.Net.Http.HttpClient())
    {
        // TODO: implement auth - this example works for bearer tokens:
        // client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", UploadKey);
        // Or you could use simple headers:
        client.DefaultRequestHeaders.Add("token", UploadKey);
        // inject the JSON header... and others if you need them
        client.DefaultRequestHeaders.Add("json", "true");

        var uri = new System.Uri(UploadAPI);

        // Load the file:
        var file = new System.IO.FileInfo(ImagePath);
        if (!file.Exists)
            throw new ArgumentException($"Unable to access file at: {ImagePath}", nameof(ImagePath));

        using (var stream = file.OpenRead())
        {
            var multipartContent = new System.Net.Http.MultipartFormDataContent();
            multipartContent.Add(
                new System.Net.Http.StreamContent(stream),
                "imgfile", // this is the name of FormData field
                file.Name);

            System.Net.Http.HttpRequestMessage request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, uri);
            request.Content = multipartContent;
            var response = await client.SendAsync(request);
            response.EnsureSuccessStatusCode(); // this throws an exception on non HTTP success codes
        }
    }
}

The following is the original posted solution for.Net Core to upload using multi-part:

    public static async Task UploadImg(string ImagePath, string UploadAPI, string UploadKey)
    {
        using (var client = new Windows.Web.Http.HttpClient())
        {
            // TODO: implement auth - this example works for bearer tokens:
            client.DefaultRequestHeaders.Authorization = new Windows.Web.Http.Headers.HttpCredentialsHeaderValue("Bearer", UploadKey);
            // Or you could use simple headers:
            client.DefaultRequestHeaders.Add("token", UploadKey);

            // Load the file:
            StorageFile file = await StorageFile.GetFileFromPathAsync(ImagePath);

            var uri = new System.Uri(UploadAPI);

            HttpMultipartFormDataContent multipartContent = new HttpMultipartFormDataContent();

            multipartContent.Add(
                new HttpStreamContent(stream),
                "imgfile", // this is the name of FormData field
                file.Name);

            Windows.Web.Http.HttpRequestMessage request = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.Post, uri);
            request.Content = multipartContent;
            var response = await client.SendRequestAsync(request);
            response.EnsureSuccessStatusCode(); // this throws an exception on non HTTP success codes
        }
    }

The process is similar in.Net framework, except that you can use System.IO for file operations.

More Information

Having a quick snoop around SO will find many similar questions with similar solutions or pratical advice. This answer is specifically provided to work with OPs ShareX configuration, but if you need further information have a read over these articles:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM