WP7 - 带有图像的POST表单

时间:2011-04-11 14:36:26

标签: windows-phone-7 post httpwebrequest

我需要将Windows Phone 7中的图像发送到某些电子邮件地址。 我使用这个类将文本值提交给PHP脚本,解析数据并将格式化的电子邮件发送到地址。 问题是我无法弄清楚如何将图像发送到该脚本,将图像附加到电子邮件。可以以任何方式更改PHP脚本。如果我有一个Image对象,如何更改此类以允许发送图像?

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();

非常感谢!

3 个答案:

答案 0 :(得分: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());
            }
        }
    }
}

要将图像从相机转换为字节数组,我使用了以下内容:

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();

我不知道这是将图像从手机发送到服务器的最佳方式,但我找不到任何东西,所以我自己上课时只读了这个,而且它花了我几个天。如果有人想改进代码或写任何评论将受到欢迎。

答案 1 :(得分:0)

这里有很多问题/答案可以提供帮助

e.g。 Post with WebRequest - 虽然我无法专门发现照片。

也许最好的方法是在Codeplex上使用像Hammock这样的东西 - http://hammock.codeplex.com/ - 或者像RESTSharp这样的东西 - http://restsharp.org/ - 它们提供标准的REST POST功能。

e.g。如果你看看Hammock,那么你会发现其他人直接从相机发布图像到tumblr - 见http://hammock.codeplex.com/discussions/235650

答案 2 :(得分:0)

上面的代码非常完美。我只是使用一种不同的方法将文件转换为一个字节数组,与Audio

完美配合
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;
        }
    }
}