Solicitudes POST en WP7

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,

El servidor remoto devolvió un 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

preguntado el 08 de noviembre de 11 a las 15:11

Why not show us the code you've tried? -

If the server is returning a 404, perhaps you've got the wrong URL? You should use Wireshark to see what's actually going on at the network level. -

@RowlandShaw, I tried so many codes, so many.. and I don't want to interfer with someone's thought about making this to tweak my code and then it won't work again... I just want someone to put us a template to make a proper POST request in WP7 -

Is it HTTPS connection? If so, there is a similar question: stackoverflow.com/questions/8049368/… -

5 Respuestas

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

respondido 08 nov., 11:19

I think I'm close, How to add the post data ? - ahumado

You need to call BeginGetRequestStream() and write your data to the stream ( msdn.microsoft.com/en-us/library/… ). I will update my answer with an example. - calma

Works like a charm :) , tested with more than API, it even works with https... Thank you. - ahumado

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

Ejemplo:

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! :-)

respondido 08 nov., 11:21

I've updated my post: Added example how to get the response (as string) at PostComplete. - Pieter Nijs

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.

respondido 08 nov., 11:23

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

respondido 08 nov., 11:19

Te recomiendo que uses el 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));
}

Respondido 02 Oct 12, 14:10

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.