我有下面的代碼來呼叫帶有 json 主體的 POST 方法,但是The remote server returned an error: (400) Bad Request.當它執行using (var response = (HttpWebResponse)request.GetResponse()).
只有在不需要原始資料的情況下,我的代碼才能正常作業。
示例 json
{"redirect":"www.google.com","subscriptionTypeId":76670001,"marketingCampaign":{"conversionId":12345,"agency":"","medium":"","name":"","source":""}}
我的代碼
public static bool HTTPRequest(string URL, RequestMethod CallMethod, Hashtable RequestHeaders, string json, ref StringBuilder httpRequestHeader, ref string jsonResponse, bool preparepurchaseFlag)
{
try
{
var request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = CallMethod.ToString();
request.ContentLength = 0;
//Header
if (RequestHeaders != null)
{
foreach (string ParamKey in RequestHeaders.Keys)
{
if (ParamKey == "Content-Type")
{
request.ContentType = RequestHeaders[ParamKey].ToString();
}
else if (ParamKey.ToLower() == "accept")
{
request.Accept = RequestHeaders[ParamKey].ToString();
}
else
{
request.Headers[ParamKey] = RequestHeaders[ParamKey].ToString();
}
}
}
//Body
if (!string.IsNullOrEmpty(json))
{
var encoding = new UTF8Encoding();
var bytes = Encoding.GetEncoding("UTF-8").GetBytes(json);
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
}
//Log Request Header
httpRequestHeader.AppendLine("curl --location --request " request.Method.ToString());
httpRequestHeader.AppendLine(request.RequestUri.ToString());
foreach (string ParamKey in RequestHeaders.Keys)
{
httpRequestHeader.Append("--header ");
httpRequestHeader.AppendLine(ParamKey ": " RequestHeaders[ParamKey].ToString());
}
if (preparepurchaseFlag)
{
httpRequestHeader.Append("--data-raw ");
httpRequestHeader.AppendLine(json);
}
using (var response = (HttpWebResponse)request.GetResponse())
{
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK)
{
var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
throw new Exception(message);
}
var httpWebResponse = (HttpWebResponse)request.GetResponse();
using (var responseStream = httpWebResponse.GetResponseStream())
{
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd();
}
}
jsonResponse = responseValue;
return true;
}
}
catch (WebException e)
{
//catch
return false;
}
catch (Exception ex)
{
//catch
}
}
uj5u.com熱心網友回復:
Microsoft 不建議將HttpWebRequest用于新開發。相反,您應該使用HttpClient類,它可以簡化很多程序。
這是我為幫助您入門而創建的快速包裝器。
public class HttpClientWrapper
{
private readonly HttpClient _httpClient;
public HttpClientWrapper(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<T> SendRequestAsync<T>(
string relativeUrl,
HttpMethod method,
object? payload,
IDictionary<string, string>? queryParameters,
IDictionary<string, string>? headers)
{
if (string.IsNullOrEmpty(relativeUrl))
{
throw new ArgumentNullException(nameof(relativeUrl));
}
string relativeUrlWithArguments = AddArgumentsToUrl(relativeUrl, queryParameters);
HttpRequestMessage requestMessage = CreateHttpRequestMessage(relativeUrlWithArguments, method, payload, headers);
var response = await _httpClient.SendAsync(requestMessage);
response.EnsureSuccessStatusCode();
var textResponse = await response.Content.ReadAsStringAsync();
if (string.IsNullOrEmpty(textResponse))
{
throw new InvalidOperationException("Empty response returned by server.");
}
T? data = JsonSerializer.Deserialize<T>(textResponse);
if (data == null)
{
throw new InvalidOperationException("Failed to deserialize the response to your model.");
}
return data;
}
private static string AddArgumentsToUrl(string url, IDictionary<string, string>? queryParameters)
{
queryParameters ??= new Dictionary<string, string>();
string argumentsString = string.Join("&", queryParameters.Select(arg => $"{arg.Key}={arg.Value}"));
return !string.IsNullOrEmpty(argumentsString) ? $"{url}?{argumentsString}" : url;
}
private static HttpRequestMessage CreateHttpRequestMessage(string relativeUrl,
HttpMethod method,
object? payload,
IDictionary<string, string>? headers)
{
var httpRequestMessage = new HttpRequestMessage(method, relativeUrl)
{
Content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json")
};
if (headers != null)
{
foreach (var header in headers)
{
httpRequestMessage.Headers.Add(header.Key, header.Value);
}
}
return httpRequestMessage;
}
}
上面類的簡單用法可以是:
private static HttpClient httpClient = new HttpClient();
var httpClientWrapper = new HttpClientWrapper(httpClient);
var response = httpClientWrapper.SendRequestAsync<ResponseClass>(
relativeUrl: "http://myurl.com",
method: HttpMethod.Post,
payload: YourObjectThatWillBeSerializedToJson,
queryParameters: new Dictionary<string, string>
{
{ "query1", "value1" }
},
headers: new Dictionary<string, string>
{
{ "Accept", "AcceptValue" },
{ "Header2", "Header2Value" }
});
ResponseClass回應 JSON 將被反序列化到的型別在哪里。對于payload,您必須發送將被序列化為 JSON 的物件。查詢引數和標題是可選的,可以作為字典傳遞。您可以根據自己的喜好編輯此包裝器的功能。例如,如果您想將已經序列化的 JSON 作為有效負載傳遞,則必須稍微修改該CreateHttpRequestMessage方法。
重要提示:建議使用IHttpClientFactory來管理您的 HttpClient 實體。我HttpClient在我的示例中創建了一個靜態,這也可以。但這里重要的部分是不要HttpClient為您提出的每個請求創建一個新實體。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/517403.html
