我使用多部分表单数据通过 REST api 将图像发送到服务器,但它已损坏

I send an image to server through REST api using multipart formdata but it gets corrupted

根据下面给出的代码,我将图像转换为字节数组,然后使用 REST API post 方法通过多部分数据将其发送到服务器。它在服务器上发送字节数组,但是当我从服务器获取相同的图像时,我收到图像格式已损坏的消息。我无法理解错误。

public static async Task < HomeWorkResponse > CreateHomeWork(HomeWorkRequest homeWork, UserData user) {
    try {
        MultipartFormDataContent Mfdc = new MultipartFormDataContent();
        System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient();
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        MultipartFormDataContent form = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture));
        List < KeyValuePair < string,
        string >> Post_parameters = null;
        string token = "";
        var result = await ServerMethods.GetTokenForTLE();
        if (result != null && !string.IsNullOrEmpty(result.response.token)) {
            token = result.response.token;
        }

        //Convert Image into bytearray

        for (int i = 0; i < homeWork.attachmentspath.Count; i++) {
            Mfdc = new MultipartFormDataContent();
            StorageFile sfs = await StorageFile.GetFileFromPathAsync(homeWork.attachmentspath[i]);
            FileStream fileStream = null;
            byte[] imageByteArray = null;
            using(var stream = await sfs.OpenReadAsync()) {
                imageByteArray = new byte[stream.Size];
                using(var reader = new DataReader(stream)) {
                    await reader.LoadAsync((uint) stream.Size);
                    reader.ReadBytes(imageByteArray);
                }
            }

            //Add that bytearray into http content

            HttpContent content = new ByteArrayContent(imageByteArray, 0, imageByteArray.Length);
            Mfdc.Add(content);
            content.Headers.ContentType = MediaTypeHeaderValue.Parse(sfs.ContentType);
            content.Headers.ContentDisposition = new ContentDispositionHeaderValue("filename");
            content.Headers.ContentDisposition.FileName = sfs.DisplayName;
            Mfdc.Headers.ContentType = MediaTypeHeaderValue.Parse(sfs.ContentType);
            form.Add(Mfdc, i.ToString(), homeWork.attachments[i]);
        }

        //Add different types of data in form data

        form.Add(new StringContent(user.user_id), "user_id");
        form.Add(new StringContent(user.user_session_id), "session_id");
        form.Add(new StringContent(homeWork.subject_id), "subject_id");
        form.Add(new StringContent(homeWork.section_id), "section_id");
        form.Add(new StringContent(homeWork.class_id), "class_id");
        form.Add(new StringContent(user.school_id), "school_id");
        form.Add(new StringContent(homeWork.assignment_title), "title");
        form.Add(new StringContent(homeWork.content), "content");
        form.Add(new StringContent("class-section"), "channel");
        form.Add(new StringContent("mobile"), "origin");
        form.Add(new StringContent("homework"), "type");
        form.Add(new StringContent(""), "homework_id");
        form.Add(new StringContent(homeWork.target_date), "target_date");
        form.Add(new StringContent(homeWork.section_id), "classsec_ids");
        form.Add(new StringContent(""), "group_ids");
        form.Add(new StringContent(""), "file_list");
        form.Add(new StringContent("class"), "assign_to");
        form.Add(new StringContent(token), "token");

        //send the data on server through REST API using post method

        System.Net.Http.HttpResponseMessage response = await httpClient.PostAsync(string.Format(UrlHelpers.TLE_TEACHER_CREATE_HOMEWORK_URL), form);
        response.EnsureSuccessStatusCode();
        httpClient.Dispose();

        string sd = response.Content.ReadAsStringAsync().Result;
        var DeserializeObject = JsonConvert.DeserializeObject < HomeWorkResponse > (sd);
        return (HomeWorkResponse) Convert.ChangeType(DeserializeObject, typeof(HomeWorkResponse));

    }
    catch(Exception e) {

}
}

通过这段代码,我将我的图像从我的系统转换为字节数组

for (int i = 0; i < homeWork.attachmentspath.Count; i++) {
    Mfdc = new MultipartFormDataContent();
    StorageFile sfs = await StorageFile.GetFileFromPathAsync(homeWork.attachmentspath[i]);
    FileStream fileStream = null;
    byte[] imageByteArray = null;
    using(var stream = await sfs.OpenReadAsync()) {
        imageByteArray = new byte[stream.Size];
        using(var reader = new DataReader(stream)) {
            await reader.LoadAsync((uint) stream.Size);
            reader.ReadBytes(imageByteArray);
        }
    }

这是 java 中的代码,被 android 团队使用并成功上传了他们的图片

ArrayList<String> stringArrayList = new ArrayList<>();
stringArrayList = sourceFileUr;
// defaultHttpClient
InputStream inputStream;
File sourceFile;
byte[] data;
MultipartEntity entity = new MultipartEntity();
JSONObject jsonObject = new JSONObject();
InputStreamBody inputStreamBody;
if (stringArrayList != null && stringArrayList.size() > 0) {
    String allFile = "";

    for (int i = 0; i < stringArrayList.size(); i++) {
        String fileName = stringArrayList.get(i).substring(stringArrayList.get(i).lastIndexOf("/") + 1);
        String Fullpath = stringArrayList.get(i);
        sourceFile = new File(Fullpath);
        inputStream = new FileInputStream(sourceFile);
        data = IOUtils.toByteArray(inputStream);
        inputStreamBody = new InputStreamBody(new ByteArrayInputStream(data), fileName);
        entity.addPart("" + i, inputStreamBody);
        //  entity.addPart("file_name", new StringBody(fileName));
        jsonObject.put("" + i, Fullpath);
    }

}

如果你想上传图片到服务器,你不需要将图片转换成字节数组,你可以通过使用 HttpStreamContent Class in the Windows.Web.Http 命名空间提供使用流的 HTTP 内容来上传图片。这是示例代码,您可以在您的应用程序中尝试。

    //using Windows.Web.Http.HttpClient 
    public async Task<bool> ShareStatusWithPicture(string text, StorageFile file)
    {
        Windows.Web.Http.HttpClient client = new Windows.Web.Http.HttpClient();
        var fileContent = new HttpStreamContent(await file.OpenAsync(FileAccessMode.Read));
        fileContent.Headers.Add("Content-Type", "multipart/form-data");

        var content = new HttpMultipartFormDataContent();
        Uri uri = new Uri("URI of your server");
        content.Add(fileContent, "pic", file.Name);
        content.Add(new HttpStringContent(tokens.AccessToken), "access_token");
        content.Add(new HttpStringContent("homework"), "status");
        //TO DO 
        //Add other HttpStringContent
        Windows.Web.Http.HttpResponseMessage msg = await client.PostAsync(uri, content);
        client.Dispose();
        return msg.IsSuccessStatusCode;
    }

---更新---

您可以尝试使用以下代码将您的图像转换为字节数组:

for (int i = 0; i < homeWork.attachmentspath.Count; i++)
{
    Mfdc = new MultipartFormDataContent();
    StorageFile sfs = await StorageFile.GetFileFromPathAsync(homeWork.attachmentspath[i]);
    FileStream fileStream = null;
    byte[] imageByteArray = null;
    using (var stream = await sfs.OpenReadAsync())
    {
        imageByteArray = new byte[stream.Size];
        using (var reader = new DataReader(stream))
        {
            await reader.LoadAsync((uint)stream.Size);
            // Keep reading until we consume the complete stream.
            while (reader.UnconsumedBufferLength > 0)
            {
                uint bytesToRead = reader.ReadUInt32();
                reader.ReadBytes(imageByteArray);
            }
        }
    }

如果这些代码仍然不起作用,您可以使用Stream.CopyTo方法,然后将复制的流转换为数组。

for (int i = 0; i < homeWork.attachmentspath.Count; i++)
{
    Mfdc = new MultipartFormDataContent();
    StorageFile sfs = await StorageFile.GetFileFromPathAsync(homeWork.attachmentspath[i]);
    FileStream fileStream = null;
    byte[] imageByteArray = null;
    using (var stream = await sfs.OpenReadAsync())
    {
        //imageByteArray = new byte[stream.Size];
        using (MemoryStream ms = new MemoryStream())
        {
            stream.AsStream().CopyTo(ms);
            imageByteArray= ms.ToArray();
        }
    }

通过使用下面给出的代码我已经解决了我的问题

for (int i = 0; i < Postdata.Attachment_Path.Count; i++)
                {
                    Mfdc = new MultipartFormDataContent();
                    StorageFile sfs = await StorageFile.GetFileFromPathAsync(Postdata.Attachment_Path[i]);
                     await Task.Run(async () => {
                         FileStream fs = File.OpenRead(sfs.Path);
                         var streamContent = new StreamContent(fs);
                         var imageContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
                         imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
                         form.Add(imageContent, i.ToString(), Postdata.Attached_filename[i]);
                     });
                }