HttpContent 错误请求 {"error":{"message":"Mandatory parameter missed","error_key":null}}
HttpContent Bad request {"error":{"message":"Mandatory parameter missed","error_key":null}}
我正在尝试使用 HttpClient 做一个简单的 POST,但我在使用 HttpRequestMessage.Content
时遇到了一些问题。 \n
简而言之,如果我在没有 escape character
的情况下对其中一个必需参数进行硬编码,例如:
string value = "lorem ipsum lorem ipsum lorem ipsum lorem ipsum";
request.Content = new StringContent("{\"requiredParameter\":\""+ value +"\}");
一切正常。
但是,如果我按如下方式连接字符串:
string value = "\norem ipsum \n" +
"lorem ipsum \n" +
"lorem ipsum\n";
or even
//string value = "\nlorem ipsum lorem ipsum lorem ipsum lorem ipsum";
request.Content = new StringContent("{\"requiredParameter\":\""+ value +"\}");
它没有,我收到一个错误的请求:
Status code: BadRequest
{"error":{"message":"Mandatory parameter missed","error_key":null}}
已经尝试过
System.Text.Json.JsonSerializer.Serialize
var options = new JsonSerializerOptions
{
WriteIndented = true,
};
string json = System.Text.Json.JsonSerializer.Serialize(value, options);
StringBuilder 因为它更适合大量的字符串操作。
string value1 = "\nlorem ipsum \n";
string value2 = "lorem ipsum \n";
string value3 = "lorem ipsum\n";
stringBuilder.Append(value1);
stringBuilder.Append(value2);
stringBuilder.Append(value3);
request.Content = new StringContent("{\"requiredParameter\":\""+ stringBuilder.toString() +"\}");
并且,Encoding.UTF8,“application/json”
request.Content = new StringContent("{\"requiredParameter\":\""+ value +"\", Encoding.UTF8, "application/json");
没有成功。
最小复制:
static async Task<string> postAsync(Uri uri, string postContent)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://www.url.com/"))
{
request.Headers.TryAddWithoutValidation("authority", "www.url.com");
request.Headers.TryAddWithoutValidation("accept", "application/json, text/plain, */*");
request.Headers.TryAddWithoutValidation("x-oauth2-required", "true");
request.Content = new StringContent("{\"requiredParameter\":\""+ value +"\}");
return await response.Content.ReadAsStringAsync();
}
}
}
static async Task Main(string[] args)
{
Uri uri = new Uri("www.uri.com");
var postContent = GenerateDynamicStringContent(List<string> params);
await PostAsync(uri, postContent);
}
我在这里错过了什么?
不同的是,第二和第三个选项,lorem ipsum
之间没有space。
如果您在 concatenate
字符串(每行末尾)中给出空的 spaces 并且在 stringBuilder
中类似,那么它们将与第一个相同。
带连接
string value = "lorem ipsum " +
"lorem ipsum " +
"lorem ipsum ";
使用 StringBuilder
string value1 = "lorem ipsum ";
string value2 = "lorem ipsum ";
string value3 = "lorem ipsum";
stringBuilder.Append(value1);
stringBuilder.Append(value2);
stringBuilder.Append(value3);
首先,您没有意识到您实际上并不需要任何 string
操作来构建 JSON。 JsonSerializer
会为你做的。
考虑以下示例。
using System.Text.Json;
using System.Net.Http;
public class Program
{
private static readonly HttpClient client = new HttpClient();
public async Task Main()
{
Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("lorem1", "ipsum1");
values.Add("lorem2", "ipsum2");
values.Add("lorem3", "ipsum3");
JsonSerializerOptions options = new JsonSerializerOptions
{
WriteIndented = true // these Options are not mandatory, just for pretty json formatting for debugging purpose
};
string json = JsonSerializer.Serialize(values, options);
Console.WriteLine(json);
string result = await PostJsonAsync("https://myapi.url/api", json);
// handle result here
}
private static async Task<string> PostJsonAsync(string url, string json)
{
using HttpContent content = new StringContent(json, Encoding.UTF8, "application/json");
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
request.Content = content;
using HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
return await response.Content.ReadAsStringAsync();
}
}
输出
{
"lorem1": "ipsum1",
"lorem2": "ipsum2",
"lorem3": "ipsum3"
}
How to serialize and deserialize (marshal and unmarshal) JSON in .NET
更新
我发现发送的数据破坏了 json 结构并导致服务器在 deserealize 过程中失败。
然后创建数据class。它称为数据模型。上面的 link 详细描述了如何做,但我会展示这个例子。不要害怕阅读。我已经完全回答了你的问题,但是你没有弄清楚。
public class MyPostDataClass
{
[JsonPropertyName("requiredParameter")] // the attribute needed only if Property name differs from the json field name
public string RequiredParameter { get; set; }
}
那么简单
string postContent = GenerateDynamicStringContent(List<string> params);
MyPostDataClass postData = new MyPostDataClass();
postData.RequiredParameter = postContent;
string json = JsonSerializer.Serialize(postData);
string result = await PostJsonAsync("https://myapi.url/api", json);
使用答案中的 post 方法,删除多余的 Headers
设置,使用我的 StringContent
构造函数。不要设置任何 headers,StringContent
会为您正确设置。不要每个请求实例化new HttpClient
,这是错误的,使用上面显示的方式。
我正在尝试使用 HttpClient 做一个简单的 POST,但我在使用 HttpRequestMessage.Content
时遇到了一些问题。 \n
简而言之,如果我在没有 escape character
的情况下对其中一个必需参数进行硬编码,例如:
string value = "lorem ipsum lorem ipsum lorem ipsum lorem ipsum";
request.Content = new StringContent("{\"requiredParameter\":\""+ value +"\}");
一切正常。
但是,如果我按如下方式连接字符串:
string value = "\norem ipsum \n" +
"lorem ipsum \n" +
"lorem ipsum\n";
or even
//string value = "\nlorem ipsum lorem ipsum lorem ipsum lorem ipsum";
request.Content = new StringContent("{\"requiredParameter\":\""+ value +"\}");
它没有,我收到一个错误的请求:
Status code: BadRequest
{"error":{"message":"Mandatory parameter missed","error_key":null}}
已经尝试过
System.Text.Json.JsonSerializer.Serialize
var options = new JsonSerializerOptions
{
WriteIndented = true,
};
string json = System.Text.Json.JsonSerializer.Serialize(value, options);
StringBuilder 因为它更适合大量的字符串操作。
string value1 = "\nlorem ipsum \n";
string value2 = "lorem ipsum \n";
string value3 = "lorem ipsum\n";
stringBuilder.Append(value1);
stringBuilder.Append(value2);
stringBuilder.Append(value3);
request.Content = new StringContent("{\"requiredParameter\":\""+ stringBuilder.toString() +"\}");
并且,Encoding.UTF8,“application/json”
request.Content = new StringContent("{\"requiredParameter\":\""+ value +"\", Encoding.UTF8, "application/json");
没有成功。
最小复制:
static async Task<string> postAsync(Uri uri, string postContent)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://www.url.com/"))
{
request.Headers.TryAddWithoutValidation("authority", "www.url.com");
request.Headers.TryAddWithoutValidation("accept", "application/json, text/plain, */*");
request.Headers.TryAddWithoutValidation("x-oauth2-required", "true");
request.Content = new StringContent("{\"requiredParameter\":\""+ value +"\}");
return await response.Content.ReadAsStringAsync();
}
}
}
static async Task Main(string[] args)
{
Uri uri = new Uri("www.uri.com");
var postContent = GenerateDynamicStringContent(List<string> params);
await PostAsync(uri, postContent);
}
我在这里错过了什么?
不同的是,第二和第三个选项,lorem ipsum
之间没有space。
如果您在 concatenate
字符串(每行末尾)中给出空的 spaces 并且在 stringBuilder
中类似,那么它们将与第一个相同。
带连接
string value = "lorem ipsum " +
"lorem ipsum " +
"lorem ipsum ";
使用 StringBuilder
string value1 = "lorem ipsum ";
string value2 = "lorem ipsum ";
string value3 = "lorem ipsum";
stringBuilder.Append(value1);
stringBuilder.Append(value2);
stringBuilder.Append(value3);
首先,您没有意识到您实际上并不需要任何 string
操作来构建 JSON。 JsonSerializer
会为你做的。
考虑以下示例。
using System.Text.Json;
using System.Net.Http;
public class Program
{
private static readonly HttpClient client = new HttpClient();
public async Task Main()
{
Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("lorem1", "ipsum1");
values.Add("lorem2", "ipsum2");
values.Add("lorem3", "ipsum3");
JsonSerializerOptions options = new JsonSerializerOptions
{
WriteIndented = true // these Options are not mandatory, just for pretty json formatting for debugging purpose
};
string json = JsonSerializer.Serialize(values, options);
Console.WriteLine(json);
string result = await PostJsonAsync("https://myapi.url/api", json);
// handle result here
}
private static async Task<string> PostJsonAsync(string url, string json)
{
using HttpContent content = new StringContent(json, Encoding.UTF8, "application/json");
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
request.Content = content;
using HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
return await response.Content.ReadAsStringAsync();
}
}
输出
{
"lorem1": "ipsum1",
"lorem2": "ipsum2",
"lorem3": "ipsum3"
}
How to serialize and deserialize (marshal and unmarshal) JSON in .NET
更新
我发现发送的数据破坏了 json 结构并导致服务器在 deserealize 过程中失败。
然后创建数据class。它称为数据模型。上面的 link 详细描述了如何做,但我会展示这个例子。不要害怕阅读。我已经完全回答了你的问题,但是你没有弄清楚。
public class MyPostDataClass
{
[JsonPropertyName("requiredParameter")] // the attribute needed only if Property name differs from the json field name
public string RequiredParameter { get; set; }
}
那么简单
string postContent = GenerateDynamicStringContent(List<string> params);
MyPostDataClass postData = new MyPostDataClass();
postData.RequiredParameter = postContent;
string json = JsonSerializer.Serialize(postData);
string result = await PostJsonAsync("https://myapi.url/api", json);
使用答案中的 post 方法,删除多余的 Headers
设置,使用我的 StringContent
构造函数。不要设置任何 headers,StringContent
会为您正确设置。不要每个请求实例化new HttpClient
,这是错误的,使用上面显示的方式。