相同的代码可以使用 HttpWebRequest 但不能使用 HttpRequestMessage

The same code works using HttpWebRequest but not using HttpRequestMessage

我创建了 HttpClient 用于发送请求:

public static void Initialize()
{
    handler = new HttpClientHandler() { UseCookies = false, AllowAutoRedirect = true };
    http = new HttpClient(handler) { BaseAddress = new Uri("http://csgolounge.com/mytrades") };
    http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36");
}

之后,我创建了自定义 class 的实例,用于存储帐户的 cookie 字符串(类似于 id=xxxxxxxx; tkz=xxxxxxxxxx; token=xxxxxxxxxxx.

这就是我发送 post 请求的方式:

public async Task Bump()
{
    //if (Bumpable)
    //{
    var req = new HttpRequestMessage(HttpMethod.Post, "http://www.csgolounge.com/ajax/bumpTrade.php");
    req.Headers.Add("Cookie", cookieString);
    req.Headers.Add("X-Requested-With", "XMLHttpRequest");
    req.Headers.Add("Referer", "http://csgolounge.com/mytrades"); //Not really sure if this does anything but I've run out of smart ideas long time ago

    /*Dictionary<string, string> postData = new Dictionary<string, string>()
    {
        {"trade", offer_id}
    };
    var encoded = new FormUrlEncodedContent(postData);
    */
    req.Content = new StringContent("&trade="+Offer_id, Encoding.UTF8, "application/x-www-form-urlencoded"); //Desperation.. decided to change the encoded dictionary to StringContent
    var res = await SteamAccount.http.SendAsync(req);
    var html = await res.Content.ReadAsStringAsync();
    //}
}

我不明白这段代码有什么问题。这对我来说似乎是正确的。

此外,当我设置 AllowAutoRedirect = false 时它 returns 301: Moved Permanently 错误,而通常它 returns 200 没有 HTML 无论我传递什么作为内容.

我做错了什么?

编辑:这是我提出请求的 JavaScript 函数:

function bumpTrade(trade) {
    $.ajax({
        type: "POST",
        url: "ajax/bumpTrade.php",
        data: "trade=" + trade
    });
}

我以前处理过更复杂的 AJAX,但无论我做什么,这似乎都行不通。

编辑:我失去了耐心,改为 HttpWebRequest

现在方法如下所示:

public async Task BumpLegacy()
{
    while (true)
    {
        try
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://csgolounge.com/ajax/bumpTrade.php");
            var cc = new CookieContainer();
            MatchCollection mc = Regex.Matches(Account.CookieString, @"\s?([^=]+)=([^;]+);");
            foreach (Match m in mc)
                cc.Add(new Cookie(m.Groups[1].Value, m.Groups[2].Value, "/", "csgolounge.com"));
            httpWebRequest.CookieContainer = cc;
            byte[] bytes = Encoding.ASCII.GetBytes("trade=" + Offer_id);
            httpWebRequest.Referer = "http://csgolounge.com/mytrades";
            httpWebRequest.Headers.Add("X-Requested-With", "XMLHttpRequest");
            httpWebRequest.Method = "POST";
            httpWebRequest.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
            httpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36";
            httpWebRequest.ContentLength = (long)bytes.Length;
            var g = await httpWebRequest.GetRequestStreamAsync();
            await g.WriteAsync(bytes, 0, bytes.Count());
            g.Close();
            var res = await httpWebRequest.GetResponseAsync();
            res.Close();
            break;
        }
        catch
        {
        }
    }
}

也许我只是很笨,但对我来说似乎并没有什么不同。是否有一些关键差异可能是原因?

这是我的一个工作系统的代码,它通过 HTTPClient.

提交 POST 请求
[Route("resource")]
public async Task<dynamic> CreateResource([FromBody]Resource resource)
{
    if (resource == null) return BadRequest();
    dynamic response = null;
    resource.Topic = GetDataFromSomewhereElse();
    var message = new PostMessage(resource).BodyContent;

    dynamic postRequest = new
    {
        Message = message
    };
    var post = JsonConvert.SerializeObject(postRequest);

    HttpContent content = new StringContent(post, Encoding.UTF8, "application/json");

    using (var client = new HttpClient())
    {
        client.Timeout = TimeSpan.FromMinutes(1);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

        try
        {
            client.BaseAddress = @"http://localhost:51145/"; 

            HttpResponseMessage postResponse = await client.PostAsync("Resource", content); //"Resource" is a route exposed on the remote host

            string json = await postResponse.Content.ReadAsStringAsync();

            if (postResponse.StatusCode == HttpStatusCode.BadRequest) return BadRequest();
            if (postResponse.StatusCode == HttpStatusCode.InternalServerError) return InternalServerError();
            if (postResponse.StatusCode == HttpStatusCode.NotFound) return NotFound();

            return json;
        }
        catch(Exception ex)
        {
            return InternalServerError(ex);
        }
    }
}

[编辑] "PostMessage" 已修改以删除特定于域的详细信息。以下是 BodyContent 在我的解决方案中的真实 "PostMessage" 中的定义方式,为您提供足够的上下文来理解 "message" 实际上是什么以及它如何在示例中工作。

public string BodyContent
    {
        get
        {
            string content = "";

            Type type = this.GetType();
            Assembly assembly = Assembly.GetExecutingAssembly();
            string resource = String.Format("{0}.{1}", type.Namespace, this.EmbeddedResourceName);
            Stream stream = assembly.GetManifestResourceStream(resource);
            StreamReader reader = new StreamReader(stream);
            content = reader.ReadToEnd();

            return content;
        }
    }

...这里是 PostRequest(同样,删除了特定于域的详细信息)

public class PostRequest
{
   public string Message { get;set; }
}