.NET可移植类请求等效的.NET POST请求

时间:2015-04-15 18:34:31

标签: c# asp.net windows-phone-8.1 http-post portable-class-library

目标: - .NET Framework 4.5; - Windows 8; - Windows Phone 8.1; - 便携式类库。

大家好, 我需要在C#.NET可移植类库上实现HTTP POST请求。我遇到了一个问题,即没有发送参数(请求体是空的)。

更新  我试过这个link  这个link与HttpClient接近,请求体仍然是空的 END UPDATE

这是通过fiddler对预期和实际请求的比较。 enter image description here

我有一个这个请求的代码,可以从常见的ConsoleApplication中正常工作,但我没有找到如何在Portable类库中实现此类请求的方法。 以下代码适用于常见的控制台应用程序:

using System;
using System.IO;
using System.Net;

namespace ConsoleApplication3
{
class Program
{
    static void Main(string[] args)
    {
        var p = new Program();
        p.MakeRequests();

    }

    private void MakeRequests()
    {
        HttpWebResponse response;
        string json = String.Empty;

        if (Request_www_example_com(out response))
        {
            using (var sr = new StreamReader(response.GetResponseStream()))
            {
                json = sr.ReadToEnd();
            }
            response.Close();
        }
    }

    private bool Request_www_example_com(out HttpWebResponse response)
    {
        response = null;

        try
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.example.com/gps/?city=kyiv&ID=3&lang=ru");

            request.Accept = "*/*";
            request.ContentType = "application/x-www-form-urlencoded";
            request.Headers.Add("Accept-Languages", @"ru-RU,ru;q=0.7,en-US;q=0.6,en;q=0.4");
            request.Headers.Add("Contents-Length", @"59");
            request.Headers.Add("X-Requested-With", @"XMLHttpRequest");
            request.Referer = "http://www.example.com/";
            request.Headers.Set(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.7,ru;q=0.3");
            request.Headers.Set(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko";
            request.Headers.Set(HttpRequestHeader.Pragma, "no-cache");

            request.Method = "POST";
            request.ServicePoint.Expect100Continue = false;

            string body = @"city=kyiv&ID=3&lang=ru";
            byte[] postBytes = System.Text.Encoding.UTF8.GetBytes(body);
            request.ContentLength = postBytes.Length;
            Stream stream = request.GetRequestStream();
            stream.Write(postBytes, 0, postBytes.Length);
            stream.Close();

            response = (HttpWebResponse)request.GetResponse();
        }
        catch (WebException e)
        {
            if (e.Status == WebExceptionStatus.ProtocolError) response = (HttpWebResponse)e.Response;
            else return false;
        }
        catch (Exception)
        {
            if (response != null) response.Close();
            return false;
        }

        return true;
    }
}
}

所以请帮我把这段代码翻译成Portable。 谢谢!

3 个答案:

答案 0 :(得分:1)

所以我已经看到了HttpWebRequest的一些奇怪问题,如果你真的想继续使用HttpWebRequest,请注意App和Phone版本不一样(甚至在便携式项目中)。我找到了两个主要问题:

  • Content Type没有改变
  • Content-Length没有改变

要解决这些问题,请使用以下内容:

        HttpWebRequest webRequest = WebRequest.CreateHttp(yourRequest.RequestUri);
        webRequest.Method = yourRequest.Method;

        // HttpWebRequest does not change when assigning, have to assign base class
        ((WebRequest)webRequest).ContentType = client.Headers.ContentType;

        if (yourRequest.RequestString != null)
        {
            // For Windows Phone 8.1 to work
            if (webRequest.Headers.AllKeys.Contains("Content-Length"))
            {
                webRequest.Headers[HttpRequestHeader.ContentLength] = yourRequest.RequestString.Length.ToString();
            }

            // This is for Windows 8.1 to work
            byte[] arrData = Encoding.UTF8.GetBytes(yourRequest.RequestString);
            using (Stream dataStream = await webRequest.GetRequestStreamAsync())
            {
                dataStream.Write(arrData, 0, arrData.Length);
            }
        }

希望这有帮助!

答案 1 :(得分:0)

我认为您需要将标题名称从“内容长度”更改为“内容长度”以解决您的问题。但你也应该使用Windows.Web.Http.HttpClient,因为这是微软推荐的。

答案 2 :(得分:0)

如果有人帮助: 当您从单元测试运行代码时,当没有正文发送请求时,可能会遇到问题。 下面是一个代码,它可以为Windows 8 \ windows phone app提供良好的代码:

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
    public async Task<string> RunHttpPost(string city, string Id)
    {
        var _url = String.Format("http://www.example.com/gps/?city={0}&Id={1}",city,Id);           

        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml");
            client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
            client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0");
            client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Charset", "ISO-8859-1");
            client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded");

            var values = new Dictionary<string, string>{

            { "city", city },
            { "Id", Id }
            };

            var content = new FormUrlEncodedContent(values);

            var response = await client.PostAsync(_url, content);

           return await response.Content.ReadAsStringAsync();
        }