目标: - .NET Framework 4.5; - Windows 8; - Windows Phone 8.1; - 便携式类库。
大家好, 我需要在C#.NET可移植类库上实现HTTP POST请求。我遇到了一个问题,即没有发送参数(请求体是空的)。
更新 我试过这个link 这个link与HttpClient接近,请求体仍然是空的 END UPDATE
这是通过fiddler对预期和实际请求的比较。
我有一个这个请求的代码,可以从常见的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。 谢谢!
答案 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();
}