如何使用自定义标头将任意JSON数据发送到REST服务器?

TL; DR – 如何使用auth标头将JSON字符串发送到REST主机? 我已经尝试了3种不同的方法,其中一种方法适用于匿名类型。 为什么我不能使用匿名类型? 我需要设置一个名为“Group-Name”的变量,连字符不是有效的C#标识符。

背景

我需要POST JSON但是无法获取正文和内容类型

function#1 – 使用匿名类型

内容类型和数据是正确的,但我不想使用匿名类型。 我想用一个字符串

static void PostData(string restURLBase, string RESTUrl, string AuthToken, string postBody) { HttpClient client = new HttpClient(); client.BaseAddress = new Uri(restURLBase); client.DefaultRequestHeaders.Add("Auth-Token", AuthToken); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // StringContent content = new StringContent(postBody); var test1 = "data1"; var test2 = "data2"; var test3 = "data3"; var response = client.PostAsJsonAsync(RESTUrl, new { test1, test2, test3}).Result; // Blocking call! if (!response.IsSuccessStatusCode) { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); return; } } 

输出#1

使用AnonymousTypes + PostAsJsonAsync时,内容类型和数据是正确的,但我不想使用匿名类型。

 POST https://api.dynect.net/REST/Zone/ABCqqqqqqqqqqqqYYYYYtes3ss.com HTTP/1.1 Auth-Token: --- REDACTED ----- Accept: application/json Content-Type: application/json; charset=utf-8 Host: api.dynect.net Content-Length: 49 Expect: 100-continue {"test1":"data1","test2":"data2","test3":"data3"} 

function#2 – 无法按预期工作

取一个字符串并将其放入StringContent对象中。 这具有改变内容类型的副作用。

  static void PostData(string restURLBase, string RESTUrl, string AuthToken, string postBody) { HttpClient client = new HttpClient(); client.BaseAddress = new Uri(restURLBase); client.DefaultRequestHeaders.Add("Auth-Token", AuthToken); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); StringContent content = new StringContent(postBody); var response = client.PostAsync(RESTUrl, content).Result; // Blocking call! if (!response.IsSuccessStatusCode) { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); return; } } 

输出#2

使用StringContent + PostAsync时内容类型错误

 POST https://api.dynect.net/REST/Zone/ABCqqqqqqqqqqqqYYYYYtes3ss.com HTTP/1.1 Auth-Token: ---- REDACTED ------- Accept: application/json // CORRECT Content-Type: text/plain; charset=utf-8 // WRONG!!! Host: api.dynect.net Content-Length: 100 Expect: 100-continue {"rdata" : ["rname" : "dynect.nfp.com", "zone" : "ABCqqqqqqqqqqqqYYYYYtes3ss.com"], "ttl" : "43200"} // ^^ THIS IS CORRECT 

function#3 – 不能按预期工作

由于我知道PostAsJsonAsync正确设置了contentType,因此我们使用该方法。 (不起作用)

  static void PostData(string restURLBase, string RESTUrl, string AuthToken, string postBody) { HttpClient client = new HttpClient(); client.BaseAddress = new Uri(restURLBase); client.DefaultRequestHeaders.Add("Auth-Token", AuthToken); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); StringContent content = new StringContent(postBody); var response = client.PostAsJsonAsync(RESTUrl, content).Result; // Blocking call! if (!response.IsSuccessStatusCode) { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); return; } } 

输出#3

内容类型正确,使用StringContent + PostAsJsonAsync时POST正文错误

 POST https://api.dynect.net/REST/Zone/ABCqqqqqqqqqqqqYYYYYtes3ss.com HTTP/1.1 Auth-Token: -- REDACTED --- Accept: application/json Content-Type: application/json; charset=utf-8 Host: api.dynect.net Content-Length: 74 Expect: 100-continue {"Headers":[{"Key":"Content-Type","Value":["text/plain; charset=utf-8"]}]} 

我想做的就是将JSON作为字符串或运行时定义的动态对象发送到服务器,HTTP内容类型正确,并带有特殊的“Auth-Token”标头。

任何例子,如果不使用WebAPI,例如servicestack,或其他任何东西都很酷。

 ///  /// Creates a new instance of the  class. ///  /// The content used to initialize the .The encoding to use for the content.The media type to use for the content. [__DynamicallyInvokable] public StringContent(string content, Encoding encoding, string mediaType) : base(StringContent.GetContentByteArray(content, encoding)) { this.Headers.ContentType = new MediaTypeHeaderValue(mediaType == null ? "text/plain" : mediaType) { CharSet = encoding == null ? HttpContent.DefaultStringEncoding.WebName : encoding.WebName }; } 

它是StringContent的构造函数。 看起来您应该指定适当的Encoding和mediaType

您无法直接设置HttpContent的实例,因为它是一个抽象类。 您需要根据需要使用其中一个子类。 很可能是StringContent,它允许您在构造函数中设置响应的字符串值,编码和媒体类型: http : //msdn.microsoft.com/en-us/library/system.net.http.stringcontent。 ASPX

答案如何为我的HttpClient PostAsync第二个参数设置HttpContent?