POST Requests on WP7

2020-06-06 20:42发布

问题:

I've been dying for about 6 hours trying to figure out how to make a regular POST request in WP7 , I tried the answers of similar questions posted here and on many other places, I also tried many different APIs POST request, they all lead to one certain problem,

The remote server returned an error: NotFound.

it seems like everytime there's something missing.

So, if you please someone show us how to properly get a POST request right in this WP7

回答1:

I use this to post to facebook without any problem:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
request.Method = "POST";
request.BeginGetResponse((e) =>
{
    try
    {
        WebResponse response = request.EndGetResponse(e);
        // Do Stuff
    }
    catch (WebException ex)
    {
        // Handle
    }
    catch (Exception ex)
    {
        // Handle
    }
}, null);

I assume you would have tried this already so it may be something to do with the post data (which isn't in the above example as facebook uses the query string). Can you give us any more info?

EDIT: This is an (untested) example for writing post data:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
request.Method = "POST";
request.BeginGetRequestStream((e) =>
{
    using (Stream stream = request.EndGetRequestStream(e))
    {
        // Write data to the request stream
    }
    request.BeginGetResponse((callback) =>
    {
        try
        {
            WebResponse response = request.EndGetResponse(callback);
            // Do Stuff
        }
        catch (WebException ex)
        {
            // Handle
        }
        catch (Exception ex)
        {
            // Handle
        }
    }, null);
}, null);


回答2:

I use the following class for making POST requests with WP7:

public class PostMultiPartFormData
{
    private Dictionary<string, object> Parameters;
    private Encoding ENCODING = Encoding.UTF8;
    private string BOUNDARY = "-----------------------------wp7postrequest";
    public event EventHandler PostComplete;

    public void Post(string postbackURL,
        Dictionary<string, object> parameters)
    {
        Parameters = parameters;

        Uri url = null;
        url = new Uri(postbackURL);


        HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
        request.Method = "POST";

        request.ContentType = "multipart/form-data; boundary=" + BOUNDARY;
        request.BeginGetRequestStream(new AsyncCallback(SendStatusUpdate), request);
    }

    private void SendStatusUpdate(IAsyncResult ar)
    {
        HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
        Stream stream = request.EndGetRequestStream(ar);

        byte[] byteArray = GetMultipartFormData(Parameters, BOUNDARY);

        stream.Write(byteArray, 0, byteArray.Length);
        stream.Close();
        stream.Dispose();

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

    private byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
    {
        Stream formDataStream = new System.IO.MemoryStream();
        foreach (var param in postParameters)
        {
            if (param.Value is byte[])
            {
                byte[] fileData = param.Value as byte[];

                string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}.jpg\";\r\nContent-Type: application/octet-stream\r\n\r\n", boundary, param.Key, param.Key);

                formDataStream.Write(ENCODING.GetBytes(header), 0, header.Length);

                formDataStream.Write(fileData, 0, fileData.Length);
            }
            else
            {
                string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n", boundary, param.Key, param.Value);
                byte[] b = ENCODING.GetBytes(postData);
                foreach (var item in b)
                {
                    formDataStream.WriteByte(item);
                }
            }
        }

        string footer = "\r\n--" + boundary + "--\r\n";
        byte[] footerbytes = ENCODING.GetBytes(footer);
        formDataStream.Write(footerbytes, 0, footerbytes.Length);

        formDataStream.Position = 0;
        byte[] formData = new byte[formDataStream.Length];
        formDataStream.Read(formData, 0, formData.Length);
        formDataStream.Flush();
        formDataStream.Close();
        return formData;
    }

    private void StatusUpdateCompleted(IAsyncResult ar)
    {
        if (PostComplete != null)
        {
            PostComplete(ar, null);
        }
    }
}

Example:

PostMultiPartFormData postRequest = new PostMultiPartFormData();

        postRequest.PostComplete += new EventHandler( (sender, e) => 
        {
            IAsyncResult ar = ((IAsyncResult)sender);

            using (WebResponse resp = ((HttpWebRequest)ar.AsyncState).EndGetResponse(ar))
            {

                using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
                {

                    string responseString = sr.ReadToEnd();

                    this.Dispatcher.BeginInvoke(() =>
                    {
                        textBlock.Text = responseString;
                    });
                }
            }
        });

        postRequest.Post("http://localhost:50624/SSLProxy.ashx", 
            new Dictionary<string, object>() { { "param1", "value1" } });

This should work... If it doesn't let me know! :-)



回答3:

For easier access to advanced http features check out these http classes:

http://mytoolkit.codeplex.com/wikipage?title=Http

It encapsulates GET, POST, FILES (using path or Stream objects) and GZIP (not directly supported by WP7) requests.



回答4:

To add post data just call BeginGetRequestStream method (also, BeginGetResponse move to GetRequestStreamCallback)

request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);

void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
    HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
    // End the stream request operation
    Stream postStream = webRequest.EndGetRequestStream(asynchronousResult);

    // Create the post data
    string postData = "post data";
    byte[] byteArray = Encoding.Unicode.GetBytes(postData);

    // Add the post data to the web request            
    postStream.Write(byteArray, 0, byteArray.Length);
    postStream.Close();

    // Start the web request
    webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest);
}


回答5:

I recommend you to use the postclient. It is pretty simple. You just need to add reference to dll file into your project, and then write something like:

public void authorize(string login, string password)
{
    Dictionary<string, object> parameters = new Dictionary<string, object>();
    parameters.Add("command", "login");
    parameters.Add("username", login);
    parameters.Add("password", password);

    PostClient proxy = new PostClient(parameters);
    proxy.DownloadStringCompleted += (sender, e) =>
    {
        if (e.Error == null)
        {
            MessageBox.Show(e.Result);
        }
    };
    proxy.DownloadStringAsync(new Uri("http://address.com/service", UriKind.Absolute));
}