2011-04-11 85 views
6

我需要將Windows Phone 7的圖像發送到某些電子郵件地址。 我使用這個類將文本值提交給PHP腳本,解析數據並將格式化的電子郵件發送到地址。 問題是,我無法弄清楚如何將圖像發送到該腳本,以將圖像附加到電子郵件。 PHP腳本可以以任何方式更改。如果我有一個Image對象,我該如何改變這個類來允許發送圖像?WP7 - 帶圖像的POST表單

public class PostSubmitter 
{ 
    public string url { get; set; } 
    public Dictionary<string, string> parameters { get; set; } 

    public PostSubmitter() { } 

    public void Submit() 
    { 
     // Prepare web request... 
     HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url); 
     myRequest.Method = "POST"; 
     myRequest.ContentType = "application/x-www-form-urlencoded"; 

     myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), myRequest); 
    } 

    private void GetRequestStreamCallback(IAsyncResult asynchronousResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 
     System.IO.Stream postStream = request.EndGetRequestStream(asynchronousResult); 

     // Prepare Parameters String 
     string parametersString = ""; 
     foreach (KeyValuePair<string, string> parameter in parameters) 
     { 
      parametersString = parametersString + (parametersString != "" ? "&" : "") + string.Format("{0}={1}", parameter.Key, parameter.Value); 
     } 

     byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(parametersString); 
     // Write to the request stream. 
     postStream.Write(byteArray, 0, parametersString.Length); 
     postStream.Close(); 
     // Start the asynchronous operation to get the response 
     request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request); 
    } 

    private void GetResponseCallback(IAsyncResult asynchronousResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 
     HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); 
     Stream streamResponse = response.GetResponseStream(); 
     StreamReader streamRead = new StreamReader(streamResponse); 
     string responseString = streamRead.ReadToEnd(); 
     // Close the stream object 
     streamResponse.Close(); 
     streamRead.Close(); 
     // Release the HttpWebResponse 
     response.Close(); 
     //Action<string> act = new Action<string>(DisplayResponse); 
     //this.Dispatcher.BeginInvoke(act, responseString); 
    } 

我使用類以這樣的方式

Dictionary<string, string> data = new Dictionary<string, string>() 
{ 
     {"nom", nom.Text}, 
     {"cognoms", cognoms.Text}, 
     {"email", email.Text}, 
     {"telefon", telefon.Text} 
}; 

PostSubmitter post = new PostSubmitter() { url = "http://example.com/parserscript.php", parameters = data }; 
post.Submit(); 

非常感謝您!

+0

你可以在這裏找到答案:http://gregdoesit.com/2009/10/file-upload-in -silverlight -a-simple-solution/ – AlexMok 2011-04-11 16:27:25

回答

14

我已經將上面的代碼轉換爲以下,我相信它會幫助:

public class PostSubmitter 
{ 
    public string url { get; set; } 
    public Dictionary<string, object> parameters { get; set; } 
    string boundary = "----------" + DateTime.Now.Ticks.ToString(); 

    public PostSubmitter() { } 

    public void Submit() 
    { 
     // Prepare web request... 
     HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(new Uri(url)); 
     myRequest.Method = "POST"; 
     myRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary); 

     myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), myRequest); 
    } 

    private void GetRequestStreamCallback(IAsyncResult asynchronousResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 
     Stream postStream = request.EndGetRequestStream(asynchronousResult); 

     writeMultipartObject(postStream, parameters); 
     postStream.Close(); 

     request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request); 
    } 

    private void GetResponseCallback(IAsyncResult asynchronousResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 
     HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); 
     Stream streamResponse = response.GetResponseStream(); 
     StreamReader streamRead = new StreamReader(streamResponse); 
     streamResponse.Close(); 
     streamRead.Close(); 
     // Release the HttpWebResponse 
     response.Close(); 
    } 


    public void writeMultipartObject(Stream stream, object data) 
    { 
     StreamWriter writer = new StreamWriter(stream); 
     if (data != null) 
     { 
      foreach (var entry in data as Dictionary<string, object>) 
      { 
       WriteEntry(writer, entry.Key, entry.Value); 
      } 
     } 
     writer.Write("--"); 
     writer.Write(boundary); 
     writer.WriteLine("--"); 
     writer.Flush(); 
    } 

    private void WriteEntry(StreamWriter writer, string key, object value) 
    { 
     if (value != null) 
     { 
      writer.Write("--"); 
      writer.WriteLine(boundary); 
      if (value is byte[]) 
      { 
       byte[] ba = value as byte[]; 

       writer.WriteLine(@"Content-Disposition: form-data; name=""{0}""; filename=""{1}""", key, "sentPhoto.jpg"); 
       writer.WriteLine(@"Content-Type: application/octet-stream"); 
       //writer.WriteLine(@"Content-Type: image/jpeg"); 
       writer.WriteLine(@"Content-Length: " + ba.Length); 
       writer.WriteLine(); 
       writer.Flush(); 
       Stream output = writer.BaseStream; 

       output.Write(ba, 0, ba.Length); 
       output.Flush(); 
       writer.WriteLine(); 
      } 
      else 
      { 
       writer.WriteLine(@"Content-Disposition: form-data; name=""{0}""", key); 
       writer.WriteLine(); 
       writer.WriteLine(value.ToString()); 
      } 
     } 
    } 
} 

將圖像從相機轉換爲字節數組,我用了follwing:

private void photoChooserTask_Completed(object sender, PhotoResult e) 
     { 
      try 
      { 
       BitmapImage image = new BitmapImage(); 
       image.SetSource(e.ChosenPhoto); 
       foto.Source = image; 

       using (MemoryStream ms = new MemoryStream()) 
       { 
        WriteableBitmap btmMap = new WriteableBitmap(image); 

        // write an image into the stream 
        Extensions.SaveJpeg(btmMap, ms, image.PixelWidth, image.PixelHeight, 0, 100); 

        byteArray = ms.ToArray(); 
       } 
      } 
      catch (ArgumentNullException) { /* Nothing */ } 
     } 

我使用的類是這樣的:

Dictionary<string, object> data = new Dictionary<string, object>() 
     { 
      {"nom", nom.Text}, 
      {"cognoms", cognoms.Text}, 
      {"email", email.Text}, 
      {"telefon", telefon.Text}, 
      {"comentari", comentari.Text}, 
      {"foto", byteArray}, 
     }; 
     PostSubmitter post = new PostSubmitter() { url = "http://example.com/parserscript.php", parameters = data}; 
     post.Submit(); 

我不知道這是從手機發送圖像到服務器的最佳方式,但我找不到任何東西,所以我讓自己的課程只是閱讀這個和那個,而且它已經帶走了我幾個天。如果有人想改進代碼或寫任何評論將受到歡迎。

+0

我們可以通過設置組合類型爲內聯使瀏覽器本身能夠上傳文件視圖嗎?我修改了內容類型,然後它沒有中斷上傳,但是在表單數據破壞上傳之後,將組合類型更改爲內聯或添加內聯。 – ua741 2013-04-30 08:51:43

+0

您好我已經嘗試使用您的方法的多部分職位,但我沒有得到n的迴應(回調)我張貼圖像到字符串列表,它是否必須是一個數組 – Bohrend 2013-08-22 07:31:12

+0

真棒 - 謝謝。我無法與application/octet-stream一起工作,但可以使用image/jpeg。必須取決於服務如何接收它... – James 2013-09-24 09:48:52

0

在這裏有很多問題/答案,以幫助已經

例如, Post with WebRequest - 雖然我無法找到任何具體的照片。

也許最好的方法是在Codeplex上使用類似Hammock的東西 - http://hammock.codeplex.com/ - 或者像RESTSharp - http://restsharp.org/ - 它們提供標準的REST POST函數。

例如如果你看Hammock,那麼你會發現其他人已經發布圖像直接從相機tumblr - 請參閱http://hammock.codeplex.com/discussions/235650

+0

我不喜歡任何符合我需求的東西,但是感謝你的鏈接 – enkara 2011-04-12 14:29:04

0

上述代碼完美無缺。我只是用不同的方法來將文件轉換爲字節數組,它可以完美兼容音頻

public static class FileHelper 
{ 
    public static byte[] ReadToEnd(System.IO.Stream stream) 
    { 
     long originalPosition = stream.Position; 
     stream.Position = 0; 

     try 
     { 
      byte[] readBuffer = new byte[4096]; 

      int totalBytesRead = 0; 
      int bytesRead; 

      while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0) 
      { 
       totalBytesRead += bytesRead; 

       if (totalBytesRead == readBuffer.Length) 
       { 
        int nextByte = stream.ReadByte(); 
        if (nextByte != -1) 
        { 
         byte[] temp = new byte[readBuffer.Length * 2]; 
         Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length); 
         Buffer.SetByte(temp, totalBytesRead, (byte)nextByte); 
         readBuffer = temp; 
         totalBytesRead++; 
        } 
       } 
      } 

      byte[] buffer = readBuffer; 
      if (readBuffer.Length != totalBytesRead) 
      { 
       buffer = new byte[totalBytesRead]; 
       Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead); 
      } 
      return buffer; 
     } 
     finally 
     { 
      stream.Position = originalPosition; 
     } 
    } 
}