Uploading an image using C# and WebRequest?

32,772

Solution 1

Try this:

string file = @"C:\Users\Sergio\documents\visual studio 2010\Projects\WpfApplication1\WpfApplication1\Test\Avatar.png";
string parameters = @"key=1df918979bf3f8dff2125c22834210903&image=" +
    Convert.ToBase64String(File.ReadAllBytes(file));

Solution 2

You should correctly form a multipart POST request. See an example here: Upload files with HTTPWebrequest (multipart/form-data)

Solution 3

Read image posted by in API

public IHttpActionResult UpdatePhysicianImage(HttpRequestMessage request)
    {
        try
        {
            var form = HttpContext.Current.Request.Form;
            var model = JsonConvert.DeserializeObject<UserPic>(form["json"].ToString());
            bool istoken = _appdevice.GettokenID(model.DeviceId);
            if (!istoken)
            {
                statuscode = 0;
                message = ErrorMessage.TockenNotvalid;
                goto invalidtoken;
            }
            HttpResponseMessage result = null;
            var httpRequest = HttpContext.Current.Request;
            if (httpRequest.Files.Count > 0)
            {
                var docfiles = new List<string>();
                foreach (string file in httpRequest.Files)
                {
                    var postedFile = httpRequest.Files[file];
                    // var filePath = uploadPath + postedFile.FileName;
                    //  string fileUrl = Utility.AbsolutePath("~/Data/User/" + model.UserId.ToString());
                    string fileUrl = Utility.AbsolutePath("~/" + Utility.UserDataFolder(model.UserId, "Document"));
                    if (!Directory.Exists(fileUrl))
                    {
                        Directory.CreateDirectory(fileUrl);
                        Directory.CreateDirectory(fileUrl + "\\" + "Document");
                        Directory.CreateDirectory(fileUrl + "\\" + "License");
                        Directory.CreateDirectory(fileUrl + "\\" + "Profile");
                    }
                    string imageUrl = postedFile.FileName;
                    string naviPath = Utility.ProfileImagePath(model.UserId, imageUrl);
                    var path = Utility.AbsolutePath("~/" + naviPath);
                    postedFile.SaveAs(path);
                    docfiles.Add(path);
                    if (model.RoleId == 2)
                    {
                        var doctorEntity = _doctorProfile.GetNameVideoChat(model.UserId);
                        doctorEntity.ProfileImagePath = naviPath;
                        _doctorProfile.UpdateDoctorUpdProfile(doctorEntity);
                    }
                    else
                    {
                        var patientEntity = _PatientProfile.GetPatientByUserProfileId(model.UserId);
                        patientEntity.TumbImagePath = naviPath;
                        _PatientProfile.UpdatePatient(patientEntity);
                    }
                }
                result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
            }
            else
            {
                result = Request.CreateResponse(HttpStatusCode.BadRequest);
            }
        }
        catch (Exception e)
        {
            statuscode = 0;
            message = "Error" + e.Message;
        }
    invalidtoken:
        return Json(modeldata.GetData(statuscode, message));
    }
Share:
32,772
Sergio Tapia
Author by

Sergio Tapia

I'm a 21 year old professional programmer that likes to read about a wide range of things related to programming. Currently, I'm pounding away at ASP.Net MVC2.

Updated on September 03, 2020

Comments

  • Sergio Tapia
    Sergio Tapia over 3 years

    Here is the working code in Python (using cURL):

    #!/usr/bin/python
    
    import pycurl
    
    c = pycurl.Curl()
    values = [
              ("key", "YOUR_API_KEY"),
              ("image", (c.FORM_FILE, "file.png"))]
    # OR:     ("image", "http://example.com/example.jpg"))]
    # OR:     ("image", "BASE64_ENCODED_STRING"))]
    
    c.setopt(c.URL, "http://imgur.com/api/upload.xml")
    c.setopt(c.HTTPPOST, values)
    
    c.perform()
    c.close()
    

    Here's what I have in C#:

    public void UploadImage()
        {
            //I think this line is doing something wrong.
            //byte[] x = File.ReadAllBytes(@"C:\Users\Sergio\documents\visual studio 2010\Projects\WpfApplication1\WpfApplication1\Test\hotness2.jpg");
    
            //If I do it like this, using a direct URL everything works fine.
            string parameters = @"key=1b9189df79bf3f8dff2125c22834210903&image=http://static.reddit.com/reddit.com.header.png"; //Convert.ToBase64String(x);
            WebRequest webRequest = WebRequest.Create(new Uri("http://imgur.com/api/upload"));
    
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.Method = "POST";
            byte[] bytes = Encoding.ASCII.GetBytes(parameters);
    
            Stream os = null;
            try
            { // send the Post
                webRequest.ContentLength = bytes.Length;   //Count bytes to send
                os = webRequest.GetRequestStream();
                os.Write(bytes, 0, bytes.Length);         //Send it
            }
            catch (WebException ex)
            {
                MessageBox.Show(ex.Message, "HttpPost: Request error");
    
            }
            finally
            {
                if (os != null)
                {
                    os.Close();
                }
            }
    
            try
            { // get the response
                WebResponse webResponse = webRequest.GetResponse();
    
                StreamReader sr = new StreamReader(webResponse.GetResponseStream());
                MessageBox.Show(sr.ReadToEnd().Trim());
            }
            catch (WebException ex)
            {
                MessageBox.Show(ex.Message, "HttpPost: Response error");                  
            }            
    
        }
    

    Now, the things I noticed is that when I changed my API key in the parameters string to "239231" or whatever number, the response I got was: "Invalid API key." So I think something must be working right.

    I placed my correct API key and now I get a different response: "Invalid image format. Try uploading a JPEG image."

    The service I'm using accepts almost every image format, so I am 100% certain the error is in the way I'm sending the file. Can anyone shed some light?

    EDIT!!!

    It turns out when I upload a JPG image I get that gray box thing. If I upload a big jpg image I don't get anything. For example: http://i.imgur.com/gFsUY.jpg

    When I upload PNG's, the image uploaded doesn't even show.

    I'm certain the issue is the encoding. What can I do?

    EDIT 2!!!

    Now I'm 100% certain that the problem lies in the first line of the method. The File.ReadAllBytes() must be doing something wrong. If I upload a URL file, every works peachy: http://imgur.com/sVH61.png

    I wonder what encoding I should use. :S

  • Sergio Tapia
    Sergio Tapia over 14 years
    This worked, somewhat. I think I'm sending the file before I complete reading all the bytes because I recieve this image: i.imgur.com/hXIfq.jpg
  • Rubens Farias
    Rubens Farias over 14 years
    maybe you should ask to your API provider, or your current image is broken, or try to upload a JPEG image
  • Sergio Tapia
    Sergio Tapia over 14 years
    I don't know what's going wrong with the upload. Check this image out: i.imgur.com/y0WVP.jpg If you notice, the top has a bit of image, maybe I'm closing the connection too soon? How can I check this?
  • Sergio Tapia
    Sergio Tapia over 14 years
    I get a response OK, which is the expected response and it even gives me the link of the uplaoded image. I think the problem is in the encoding of the image. :S
  • Rubens Farias
    Rubens Farias over 14 years
    Try to use Encoding.UTF8 instead Encoding.ASCII
  • Rubens Farias
    Rubens Farias over 14 years
    try to upload a smaller image (<30k)
  • Sergio Tapia
    Sergio Tapia over 14 years
    "Cannot display image because it contains errors" - When uploading a very small image. Rubens, do you know a different way to read the bytes of a file other than File.ReadAllBytes()? I'm certain that is causing the issue because if I don't use that and upload a web image, it works perfectly.
  • Rubens Farias
    Rubens Farias over 14 years
    FileInfo fi = new FileInfo(path); byte[] content = new byte[(int)fi.Length]; new FileStream(path, FileMode.Open).Read(content, 0, content.Length);
  • Rubens Farias
    Rubens Farias over 14 years
    btw, web images doesnt involves byte[] encoding; I suggest you to finish this question and to start another one and/or ask your API provider for directions
  • Raymond
    Raymond over 14 years
    Can clever -1ers please give a justification? +1ing to balance.
  • Nyerguds
    Nyerguds about 8 years
    Yeah, definitely use multipart for large stuff like files.
  • Nyerguds
    Nyerguds about 8 years
    @SergioTapia You do actually have to send the information as multipart, then.