Windows Mobile Developer Center > Windows Phone Forums > Windows Phone 7 > how to convert MultipartEntity to c# (WP7)

Locked how to convert MultipartEntity to c# (WP7)

  • Friday, April 16, 2010 6:39 PM
     
     

    Hello everyone, Please I need your help in this problem, it's really killing me :(
    In below is a Java code written for Android, what I want is to rewrite it again for WP7 of course by C# using Silverlight library.
    The method is for just making a POST http request, and I put my C# code below also.
    All what I get in response a -1 value which is mean error, there is something wrong I guess in passing the parameters so the response value not > 0 !!

    I hope it's clear ?

     ----------------------------------------- Java code(The orignal code need to be in C#)
    Method1(string NAME, string ID, string username, string password, byte[] pic) {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost( BASE_URL );

            HttpParams params = httpclient.getParams();
            HttpConnectionParams.setConnectionTimeout(params, TIMEOUT);
            HttpConnectionParams.setSoTimeout(params, TIMEOUT);

            HttpEntity resEntity = null;
            InputStream is = null;
      InputStreamReader isr = null;
      BufferedReader br = null;
      StringBuilder responseSB = new StringBuilder();
            try {
                MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.STRICT, null, Charset.forName("UTF-8"));
       reqEntity.addPart("name", new StringBody(NAME));
       reqEntity.addPart("id", new StringBody(ID));
       reqEntity.addPart("credentials", new StringBody(getCredentials(username, password)));
       byte[] picture = pic;
       if (picture != null) {
        reqEntity.addPart(
          "picture", new InputStreamBody(
            new ByteArrayInputStream(pic), "file.bin"
          )
        );
        picture = null;
       }
      
       ByteArrayEntity bae = null;
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       reqEntity.writeTo(baos);
       baos.flush();
       bae = new ByteArrayEntity(baos.toByteArray());
       baos.close();
       
       bae.setChunked(false);
       bae.setContentEncoding(reqEntity.getContentEncoding());
       bae.setContentType(reqEntity.getContentType());
       
             httppost.setEntity(bae);
       HttpResponse response = httpclient.execute(httppost);
             resEntity = response.getEntity();

             if (resEntity != null) {
                 is = resEntity.getContent();
              isr = new InputStreamReader( is );
              br = new BufferedReader( isr, 8192 );
             
              String line = null;
              while ( (line = br.readLine()) != null ) {
               responseSB.append(line);
              }
             }
      } catch (IOException ioe) {
       throw new MyException(ioe);
      } finally {
             if (br != null) {
              try {
               br.close();
              } catch (IOException ioe) {
               // ignore
              }
             }
             if (isr != null) {
              try {
               isr.close();
              } catch (IOException ioe) {
               // ignore
              }
             }
             if (is != null) {
              try {
               is.close();
              } catch (IOException ioe) {
               // ignore
              }
             }
             if (resEntity != null) {
              try {
               resEntity.consumeContent();
              } catch (IOException ioe) {
               // ignore
              }
             }
      }
      long z = Long.parseLong(responseSB.toString());
      if (z == -1 || z < 0)
       throw new MyException("error", -1);
            return z;
    }
    private String m2(String s1, String s2)
    {
     return B64Codec.encodeAsString(s1 + ":" + s2);
    }
    ------------------------------------------------------------------------------ C# code (My code doesn't work !! )

    public void mehtod1(object sender, EventArgs e)
    {
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(BASE_URL);
     request.Method = "POST";
     request.ContentType = "application/x-www-form-urlencoded";
     request.BeginGetRequestStream(new AsyncCallback(RequestProceed), request);
    }
    private void RequestProceed(IAsyncResult asuncResult)
    {
     HttpWebRequest request = (HttpWebRequest)asuncResult.AsyncState;
         StreamWriter postDataWriter = new StreamWriter(request.EndGetRequestStream(asuncResult));
     string parameter = "name=" + Uri.EscapeUriString("someName")
        + "&id=" + Uri.EscapeUriString(someID)
        + "&credentials=" + System.Uri.EscapeDataString(System.Convert.ToBase64String(System.Text.Encoding.Unicode.GetBytes("RealUserName" + ":" + "RealPassword")));
     if (parameter != null)
      postDataWriter.Write(parameter);
     postDataWriter.Close();
     request.BeginGetResponse(new AsyncCallback(ResponceProceed), request);
    }
    private void ResponceProceed(IAsyncResult asuncResult)
    {
     HttpWebRequest request = (HttpWebRequest)asuncResult.AsyncState;
     HttpWebResponse responce = (HttpWebResponse)request.EndGetResponse(asuncResult);
     StreamReader responceReader = new StreamReader(responce.GetResponseStream());
     string responceString = (responceReader.ReadToEnd());
     long responcelong = long.Parse(responceString);
     this.Dispatcher.BeginInvoke(delegate(){
      if (responcelong == -1 || responcelong < 0)
       Texbox1.Text = "Submitting failed"; // this the always result !!
      else
       Texbox1.Text = responcelong;
     });
    }

Answers

  • Saturday, April 24, 2010 11:48 PM
     
     Answered

    In case it helps, here's some code I used in a Windows Mobile app to send a multipart post to TwitPic. Most or not all of this code should work under WP7 (I've left out the bits I'm certain don't work with Silverlight)
    The section I've included is mostly the part that's specific to handling the Multipart stuff (it takes quite a bit more setup work than the default).
    Note the boundary markers and repeated newlines.

    (Obviously you post the byte array to the remote server although I haven't shown that part because in my original code it was a synchronous call, which isn't possible with Silverlight. And I'm too lazy to update it to be asynchronous and test it for a code sample :-))

          req.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
                req.Method = "POST";
                string imageType = "image/jpeg";

                if (fileName.EndsWith(".gif", StringComparison.OrdinalIgnoreCase))
                {
                    imageType = "image/gif";
                }
                else if (fileName.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
                {
                    imageType = "image/png";
                }
               
               
                string header = string.Format("--{0}", boundary);
                string footer = string.Format("--{0}--", boundary);

                StringBuilder payload = new StringBuilder();

                payload.AppendFormat("{0}{1}Content-Disposition: file; name=\"media\"; filename=\"{2}\"{1}", header, Environment.NewLine, fileName);
                payload.AppendFormat("Content-Type: {0}{1}{1}", imageType , Environment.NewLine);
                payload.AppendLine(Encoding.GetEncoding(encoding).GetString(imageData, 0, imageData.Length));
                payload.AppendFormat("{0}{1}Content-Disposition: form-data; name=\"username\"{1}{1}{2}{1}", header, Environment.NewLine, userName);
                payload.AppendFormat("{0}{1}Content-Disposition: form-data; name=\"password\"{1}{1}{2}{1}", header, Environment.NewLine, password);

                if (!String.IsNullOrEmpty(message))
                {
                    payload.AppendFormat("{0}{1}Content-Disposition: form-data; name=\"message\"{1}{1}{2}{1}", header, Environment.NewLine, message);
                }

                payload.AppendLine(footer);
               
                byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(payload.ToString());
                req.ContentLength = bytes.Length;

     It's a bit a mess but you should be able to get the gist.

     You might also find this Wikipedia piece helpful for context.
    Lastly, when you get your code working I'd suggest you might be better off putting the string version of the response in your TextBox.Text rather than the long, since there's no implicit conversion from string to long.

     

    • Marked As Answer by sul09 Saturday, May 08, 2010 1:17 PM
    •  

All Replies

  • Saturday, April 17, 2010 5:18 AM
     
     

    Hi Sul09,

    I was going to try your code out but I think I'll need BASE_URL. Are you able to show us this?

    Trying against bing returned a remote server exception in EndGetResponse().

  • Saturday, April 17, 2010 10:56 AM
     
     
    Sorry, I'm not allow to do that, it's a private URL.

    But what make me confuse is the HttpEntity class, I'm fried this class perform something different then the usual POST request !!
  • Saturday, April 17, 2010 11:23 AM
     
     

    It's ok, I understand.

    If you think of a way to mock the url without disclosing anything I'm happy to have a closer look at the problem.

  • Friday, April 23, 2010 1:55 PM
     
     
    the problem is in multipart.
    what is the equivalent class in silverlight for multipart?
  • Friday, April 23, 2010 8:31 PM
     
     

    Looks liek a MultiPart gets converted to a string.

    Simply put, it's appears to be POST data, try using a HTTPWebRequest, more info on how to use this is here. (not the best, but first decent post i dug up off google) http://blog.brezovsky.net/

  • Saturday, April 24, 2010 11:48 PM
     
     Answered

    In case it helps, here's some code I used in a Windows Mobile app to send a multipart post to TwitPic. Most or not all of this code should work under WP7 (I've left out the bits I'm certain don't work with Silverlight)
    The section I've included is mostly the part that's specific to handling the Multipart stuff (it takes quite a bit more setup work than the default).
    Note the boundary markers and repeated newlines.

    (Obviously you post the byte array to the remote server although I haven't shown that part because in my original code it was a synchronous call, which isn't possible with Silverlight. And I'm too lazy to update it to be asynchronous and test it for a code sample :-))

          req.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
                req.Method = "POST";
                string imageType = "image/jpeg";

                if (fileName.EndsWith(".gif", StringComparison.OrdinalIgnoreCase))
                {
                    imageType = "image/gif";
                }
                else if (fileName.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
                {
                    imageType = "image/png";
                }
               
               
                string header = string.Format("--{0}", boundary);
                string footer = string.Format("--{0}--", boundary);

                StringBuilder payload = new StringBuilder();

                payload.AppendFormat("{0}{1}Content-Disposition: file; name=\"media\"; filename=\"{2}\"{1}", header, Environment.NewLine, fileName);
                payload.AppendFormat("Content-Type: {0}{1}{1}", imageType , Environment.NewLine);
                payload.AppendLine(Encoding.GetEncoding(encoding).GetString(imageData, 0, imageData.Length));
                payload.AppendFormat("{0}{1}Content-Disposition: form-data; name=\"username\"{1}{1}{2}{1}", header, Environment.NewLine, userName);
                payload.AppendFormat("{0}{1}Content-Disposition: form-data; name=\"password\"{1}{1}{2}{1}", header, Environment.NewLine, password);

                if (!String.IsNullOrEmpty(message))
                {
                    payload.AppendFormat("{0}{1}Content-Disposition: form-data; name=\"message\"{1}{1}{2}{1}", header, Environment.NewLine, message);
                }

                payload.AppendLine(footer);
               
                byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(payload.ToString());
                req.ContentLength = bytes.Length;

     It's a bit a mess but you should be able to get the gist.

     You might also find this Wikipedia piece helpful for context.
    Lastly, when you get your code working I'd suggest you might be better off putting the string version of the response in your TextBox.Text rather than the long, since there's no implicit conversion from string to long.

     

    • Marked As Answer by sul09 Saturday, May 08, 2010 1:17 PM
    •  
  • Monday, May 03, 2010 8:55 PM
     
     

    the imageData is the image converrted to byte[] ??

    how i convert image to byte[]?(if yes)