【问题标题】:Http Post for Windows Phone 8适用于 Windows Phone 8 的 Http Post
【发布时间】:2013-01-19 20:51:31
【问题描述】:

我是 C# 新手,所以我想知道是否有人可以帮助我解决这个问题。我正在尝试将 HttpPost 从 Windows Phone 8 发送到服务器。我找到了两个我想合并的例子。

第一个是发送Http Post(http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetrequeststream.aspx)的例子。这个问题是 Windows Phone 8 不支持它。

第二个示例是使用 BeginGetResponse (http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.net.httpwebrequest(v=vs.105).aspx)。这支持windows phone 8。

我需要像第一个示例一样将第二个示例转换为 BeginGetRequestStream()。我会尝试自己解决这个问题,但如果有人已经知道如何做到这一点,我会在网上发布。我相信这将对其他 WP8 开发人员有所帮助。

更新 我现在正试图从服务器获得响应。我开始了一个新问题。请点击此链接 (Http Post Get Response Error for Windows Phone 8)

【问题讨论】:

    标签: c# http-post windows-phone


    【解决方案1】:

    我目前也在处理一个 Windows Phone 8 项目,这是我发布到服务器的方式。 Windows Phone 8 对完整 .NET 功能的访问有限,我阅读的大多数指南都说您需要使用所有功能的异步版本。

    // server to POST to
    string url = "myserver.com/path/to/my/post";
    
    // HTTP web request
    var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
    httpWebRequest.ContentType = "text/plain; charset=utf-8";
    httpWebRequest.Method = "POST";
    
    // Write the request Asynchronously 
    using (var stream = await Task.Factory.FromAsync<Stream>(httpWebRequest.BeginGetRequestStream,          
                                                             httpWebRequest.EndGetRequestStream, null))
    {
       //create some json string
       string json = "{ \"my\" : \"json\" }";
    
       // convert json to byte array
       byte[] jsonAsBytes = Encoding.UTF8.GetBytes(json);
    
       // Write the bytes to the stream
       await stream.WriteAsync(jsonAsBytes, 0, jsonAsBytes.Length);
    }
    

    【讨论】:

    • 这对于 C# 新手来说更简单、更容易理解。由于您使用的是await,如果我在该行之后调用一个函数,这是否意味着数据已成功发送,这是否正确? (你如何从服务器获得响应?)..
    • 嗨@Hunter MCmillen,你上面的代码运行成功了吗?我问是因为我已经尝试了两次,但它显示 NotFound 异常。
    • 您是否将 URL 替换为真实地址? myserver.com不是真实站点,只是一个例子
    • 嗨@HunterMcMillen,我正在尝试您的解决方案,但httpWebRequest.ContentLength 在写入后始终为-1(并且_ContentLength = 0),并且我的服务器上的Request.ContentLength 也为零。你能帮帮我吗?
    【解决方案2】:

    我提出了一种更通用的异步方法,支持成功和错误回调here

    //Our generic success callback accepts a stream - to read whatever got sent back from server
    public delegate void RESTSuccessCallback(Stream stream);
    //the generic fail callback accepts a string - possible dynamic /hardcoded error/exception message from client side
    public delegate void RESTErrorCallback(String reason);
    
    public void post(Uri uri,  Dictionary<String, String> post_params, Dictionary<String, String> extra_headers, RESTSuccessCallback success_callback, RESTErrorCallback error_callback)
    {
        HttpWebRequest request = WebRequest.CreateHttp(uri);
        //we could move the content-type into a function argument too.
        request.ContentType = "application/x-www-form-urlencoded";
        request.Method = "POST";
    
        //this might be helpful for APIs that require setting custom headers...
        if (extra_headers != null)
            foreach (String header in extra_headers.Keys)
                try
                {
                    request.Headers[header] = extra_headers[header];
                }
                catch (Exception) { }
    
    
        //we first obtain an input stream to which to write the body of the HTTP POST
        request.BeginGetRequestStream((IAsyncResult result) =>
        {
            HttpWebRequest preq = result.AsyncState as HttpWebRequest;
            if (preq != null)
            {
                Stream postStream = preq.EndGetRequestStream(result);
    
                //allow for dynamic spec of post body
                StringBuilder postParamBuilder = new StringBuilder();
                if (post_params != null)
                    foreach (String key in post_params.Keys)
                        postParamBuilder.Append(String.Format("{0}={1}&", key, post_params[key]));
    
                Byte[] byteArray = Encoding.UTF8.GetBytes(postParamBuilder.ToString());
    
                //guess one could just accept a byte[] [via function argument] for arbitrary data types - images, audio,...
                postStream.Write(byteArray, 0, byteArray.Length);
                postStream.Close();
    
    
                //we can then finalize the request...
                preq.BeginGetResponse((IAsyncResult final_result) =>
                {
                    HttpWebRequest req = final_result.AsyncState as HttpWebRequest;
                    if (req != null)
                    {
                        try
                        {
                            //we call the success callback as long as we get a response stream
                            WebResponse response = req.EndGetResponse(final_result);
                            success_callback(response.GetResponseStream());
                        }
                        catch (WebException e)
                        {
                            //otherwise call the error/failure callback
                            error_callback(e.Message);
                            return;
                        }
                    }
                }, preq);
            }
        }, request);            
    }
    

    【讨论】:

    • @AshishJain,是的。实际上,我已经在商店中的 3 个 WP8 应用程序(MyChild、M​​yStudents、MySchool)中使用了它。这个通用代码的更新版本也在我这里:gist.github.com/mcnemesis/6250994
    • using System.Security.Cryptography; using System.Text; 这些额外的命名空间是必需的。
    • 如何在不通过委托的情况下从这个 post 函数返回一个字符串?
    • @Jimmyt1988 就像现在一样,这将需要您修改该函数的定义以使 实际 发布同步,以便线程阻塞直到请求完成,然后你可以在主函数中返回响应。否则,我目前使用回调方法来适应实现的异步特性。不过,对于 WP8 的大多数 IO API,建议在异步模式下工作——原因是有道理的。
    • 谢谢你。这可能是我在 Windows Phone 8 中看到的针对 HTTP 发布请求的第一个明智的解决方案,即没有 ManualResetEvents 或疯狂的异步方法链或 HTTPClient。
    猜你喜欢
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-25
    • 2012-11-15
    相关资源
    最近更新 更多