Postman 和 HttpWebRequest 给出了不同的结果

Postman and HttpWebRequest are giving different results

我是 C# 的新手,我想在 JSON 中向 API 发送请求并在 return 中获得 JSON 响应,这样我就可以在我的应用程序中使用它。但是每次我发出请求时,我都会收到 404 错误。当我使用 POST 的相同数据执行 Postman 请求时,我得到了肯定的结果。

下面是 JSON 我要使用 Postman 发送到 API 的

{
  "ActionId": null,
  "AgentCode": "MerchantCode:Password",
  "Mpin": null,
  "Amount": 0.0,
  "CustomerMSISDN": null,
  "ServiceId": 0,
  "MTI": "0300",
  "TerminalId": null,
  "TransactionRef": null,
  "CustomerAccount": null,
  "CustomerData": null,
  "Product": null,
  "ServiceProvider": "Yomoney",
  "Source": null,
  "PaymentMethod": null,
  "ProcessingCode": "420000",
  "Quantity": null,
  "OrderLines": null,
  "Narrative": null,
  "Note": null,
  "MaxSale": 0.0,
  "MinSale": 0.0,
  "TransactionType": 2
}

这是我要发送给的 URL:

https://www.yomoneyservice.com/yoclient/transaction 

这是我得到的回复

{"ResponseCode":"00000","Description":null,"Balance":null,"TransactionCode":null,"vouchers":null,"AgentCode":null,"Mpin":null,"Amount":0,"MaxSale":0,"MinSale":0,"CustomerMSISDN":null,"ServiceId":0,"MTI":null,"TerminalId":null,"TransactionRef":null,"TransactionType":0,"CustomerAccount":null,"CustomerData":null,"Product":null,"Quantity":0,"Action":null,"ProcessingCode":null,"Note":"Purchase","Narrative":"[{\"Id\":\"1\",\"Name\":\"THE
REDEEMED
SOLDIER\",\"Value\":\"12\",\"Note\":\"Supplier\",\"Image\":null,\"Description\":null,\"Section\":null,\"ServiceId\":12,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":false,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"BUY
VOUCHER\",\"Value\":\"10\",\"Note\":\"Supplier\",\"Image\":\"~/Content/Logos/YOMONEY/yomoney_v_logo.png\",\"Description\":null,\"Section\":null,\"ServiceId\":10,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":false,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"ECONET
PINLLESS\",\"Value\":\"8\",\"Note\":\"Supplier\",\"Image\":\"~/Content/Logos/YOMONEY/buddie.png\",\"Description\":null,\"Section\":null,\"ServiceId\":8,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":false,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"TELECEL
PINLESS\",\"Value\":\"3\",\"Note\":\"Supplier\",\"Image\":null,\"Description\":null,\"Section\":null,\"ServiceId\":3,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":false,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"Econet\",\"Value\":\"2\",\"Note\":\"Supplier\",\"Image\":null,\"Description\":null,\"Section\":null,\"ServiceId\":2,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":true,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"NETONE
PINLESS\",\"Value\":\"1\",\"Note\":\"Supplier\",\"Image\":null,\"Description\":null,\"Section\":null,\"ServiceId\":1,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":false,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"THE
REDEEMED
SOLDIER\",\"Value\":\"12\",\"Note\":\"Supplier\",\"Image\":null,\"Description\":null,\"Section\":null,\"ServiceId\":12,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":false,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"BUY
VOUCHER\",\"Value\":\"10\",\"Note\":\"Supplier\",\"Image\":\"~/Content/Logos/YOMONEY/yomoney_v_logo.png\",\"Description\":null,\"Section\":null,\"ServiceId\":10,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":false,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"ECONET
PINLLESS\",\"Value\":\"8\",\"Note\":\"Supplier\",\"Image\":\"~/Content/Logos/YOMONEY/buddie.png\",\"Description\":null,\"Section\":null,\"ServiceId\":8,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":false,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"TELECEL
PINLESS\",\"Value\":\"3\",\"Note\":\"Supplier\",\"Image\":null,\"Description\":null,\"Section\":null,\"ServiceId\":3,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":false,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"Econet\",\"Value\":\"2\",\"Note\":\"Supplier\",\"Image\":null,\"Description\":null,\"Section\":null,\"ServiceId\":2,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":true,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false},{\"Id\":\"1\",\"Name\":\"NETONE
PINLESS\",\"Value\":\"1\",\"Note\":\"Supplier\",\"Image\":null,\"Description\":null,\"Section\":null,\"ServiceId\":1,\"Currency\":null,\"ActionId\":1,\"TransactionType\":0,\"SupplierId\":null,\"Amount\":null,\"Count\":0,\"date\":\"0001-01-01T00:00:00\",\"WebLink\":null,\"HasProducts\":false,\"IsAdvert\":false,\"IsNotAdvert\":false,\"IsShare\":false,\"RequireVerification\":false,\"RequiresRegistration\":false,\"RequiresAmount\":false}]"}

现在,在 C# 中,我正在使用 WebRequest&WebResponse,但我收到 404 错误消息“远程服务器 returned 一个错误:(404) 未找到。”。下面是我的 C# 代码

try
            {
                string url = String.Format("https://www.yomoneyservice.com/yoclient/transaction");
                var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
                httpWebRequest.ContentType = "application/json";
                httpWebRequest.Method = "POST";                        
                
                using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                {
                    string json = JsonConvert.SerializeObject(yomoneyRequest, Formatting.Indented);

                    streamWriter.Write(json);
                    streamWriter.Flush();
                    streamWriter.Close();

                    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

                    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                    {
                        var result = streamReader.ReadToEnd();
                        yomoneyResponse = JsonConvert.DeserializeObject<YomoneyResponse>(result);
                    }
                }                
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

我不再确定我的 C# 代码哪里出错了,有人能帮我吗?

我试图在代码和邮递员中重现您的用例。您的观察是正确的,它在邮递员中有效,但在 C# 代码中无效。

然后我观察了从代码和邮递员发送的请求之间的不同。区别在于cookie。

邮递员发送一个名为“AspxAutoDetectCookieSupport”的 cookie,其值为“1”。

然后我修改了你的代码,在向 API 发送请求时也添加了 cookie,它工作正常。

要将 cookie 添加到 HttpWebRequest,您需要使用 CookieContainer

您需要初始化 CookiContainer 属性 的 httpWebRequest 并向其添加 cookie。

您需要如下更改代码。

try
{

    string url = String.Format("https://www.yomoneyservice.com/yoclient/transaction");
    var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
    httpWebRequest.ContentType = "application/json";
    httpWebRequest.Method = "POST"; 
    httpWebRequest.CookieContainer = new CookieContainer();
    Cookie c = new Cookie("AspxAutoDetectCookieSupport", "1");
    c.Domain = "www.yomoneyservice.com";
    httpWebRequest.CookieContainer.Add(c);  
    string json = JsonConvert.SerializeObject(yomoneyRequest, Formatting.Indented);
    
    using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
    {
        streamWriter.Write(json);
    }

    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
    {
        var result = streamReader.ReadToEnd();
        var yomoneyResponse = JsonConvert.DeserializeObject<YomoneyResponse>(result);
    } 
}
catch(Exception e)
{
    Console.WriteLine(e.Message);
}

希望本文能帮助您解决问题。