Could not load image using httpwebrequest in C #

I am trying to upload an image programmatically via an API to another server. The API expects me to load the image into an array of bytes, which will be sent to the field: "image_content".

My implementation and call code is below. The web request hits the server, but the server responds that the image is not in my web request.

When I run the code below, I get an error that the image is not in the request. What am I missing here?

public static class FormUpload
{
    private static readonly Encoding encoding = Encoding.UTF8;
    public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters)
    {
        string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
        string contentType = "multipart/form-data; boundary=" + formDataBoundary;

    byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);

    return PostForm(postUrl, userAgent, contentType, formData);
}
private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
{
    HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;

    if (request == null)
    {
        throw new NullReferenceException("request is not a http request");
    }

    // Set up the request properties.
    request.Method = "POST";
    request.ContentType = contentType;
    request.UserAgent = userAgent;
    request.ContentLength = formData.Length;


    // Send the form data to the request.
    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(formData, 0, formData.Length);
        requestStream.Close();
    }

    return request.GetResponse() as HttpWebResponse;
}

private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
{
    Stream formDataStream = new System.IO.MemoryStream();
    bool needsCLRF = false;

    foreach (var param in postParameters)
    { 
        if (param.Value is FileParameter)
        {
            FileParameter fileToUpload = (FileParameter)param.Value;

            // Add just the first part of this param, since we will write the file data directly to the Stream
            string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n",
                boundary,
                param.Key,
                fileToUpload.FileName ?? param.Key,
                fileToUpload.ContentType ?? "application/octet-stream");

            formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header));

            // Write the file data directly to the Stream, rather than serializing it to a string.
            formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
        }
        else
        {
            string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
                boundary,
                param.Key,
                param.Value);
            formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
        }
    }

    // Add the end of the request.  Start with a newline
    string footer = "\r\n--" + boundary + "--\r\n";
    formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));

    // Dump the Stream into a byte[]
    formDataStream.Position = 0;
    byte[] formData = new byte[formDataStream.Length];
    formDataStream.Read(formData, 0, formData.Length);
    formDataStream.Close();

    return formData;
}

public class FileParameter
{
    public byte[] File { get; set; }
    public string FileName { get; set; }
    public string ContentType { get; set; }
    public FileParameter(byte[] file) : this(file, null) { }
    public FileParameter(byte[] file, string filename) : this(file, filename, null) { }
    public FileParameter(byte[] file, string filename, string contenttype)
    {
        File = file;
        FileName = filename;
        ContentType = contenttype;
    }
}

}

Call function to call above:

// Read file data
FileStream fs = new FileStream("c:\\myimage.jpeg", FileMode.Open, FileAccess.Read);
byte[] data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
fs.Close();

// Generate post objects
Dictionary<string, object> postParameters = new Dictionary<string, object>();
postParameters.Add("image_content",data);

// Create request and receive response
string postURL = "myurl";
string userAgent = "Mozilla";
HttpWebResponse webResponse = FormUpload.MultipartFormDataPost(postURL, userAgent, postParameters);

// Process response
StreamReader responseReader = new StreamReader(webResponse.GetResponseStream());
string fullResponse = responseReader.ReadToEnd();
webResponse.Close();
Response.Write(fullResponse);
+4
source share
3 answers

RestSharp Api, stackoverflow #, JSON RestSharp.

+2

-, MultipartFormDataContent, " , MIME multipart/form-data.".

    public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, byte[] data)
    {
        string contentType;
        byte[] formData = Program.GetMultipartFormData(data, out contentType);  
        return PostForm(postUrl, userAgent, contentType, formData);
    }

    public static byte[] GetMultipartFormData(byte[] data, out string contentType)
    {
        var byteArrayContent = new ByteArrayContent(data);
        byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
        byteArrayContent.Headers.Add("image_content", "myimage.jpeg");

        var content = new MultipartFormDataContent(String.Format("----------{0:N}", Guid.NewGuid())) { byteArrayContent };
        contentType = content.Headers.ContentType.ToString();

        return content.ReadAsByteArrayAsync().Result;
    }
+3

You are all code ok, but you forgot to encode parameter

try it

string postData = string.Format("--{0}\r\nContent-Disposition: 
form-data; name=\"{1}\"\r\n\r\n{2}",
                boundary,
                HttpUtility.UrlEncode(param.Key),
                HttpUtility.UrlEncode(param.Value));

In case of binary data

HttpUtility.UrlEncode(Convert.ToBase64String(byte[]))

try using this code to add a parameter to your query

NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
outgoingQueryString.Add("uname", "username");
outgoingQueryString.Add("pname", "password");
string postdata = outgoingQueryString.ToString();

and write these postdata in the request

+1
source

All Articles