[英]FromBody string parameter is giving null
這可能是非常基本的東西,但我無法弄清楚我哪里出錯了。
我試圖從 POST 的正文中獲取一個字符串,但“jsonString”僅顯示為 null。我也想避免使用 model,但這也許是不可能的。 我用 PostMan 打的這段代碼是這個塊:
[Route("Edit/Test")]
[HttpPost]
public void Test(int id, [FromBody] string jsonString)
{
...
}
也許這是我在 postman 上做錯的事情,但我一直在嘗試在正文的值部分 - x-www-form-urlencoded 部分使用“=test”(如其他關於該主題的問題)鍵為 jsonString 什么都沒有。 我也嘗試過使用原始文本和原始文本/純文本。 我得到了 ID,所以我知道 url 是正確的。 對此的任何幫助將不勝感激。
PostMan目前是這樣設置的:
POST http://localhost:8000/Edit/Test?id=111
key = id value = 111
Body - x-www-form-urlencoded
key = jsonString value = "=test"
通過使用[FromBody]
聲明 jsonString 參數,您可以告訴 ASP.NET Core 使用輸入格式化程序將提供的 JSON(或 XML)綁定到模型。 所以你的測試應該可以工作,如果你提供一個簡單的模型類
public class MyModel
{
public string Key {get; set;}
}
[Route("Edit/Test")]
[HttpPost]
public void Test(int id, [FromBody] MyModel model)
{
... model.Key....
}
和發送的 JSON 之類的
{
key: "value"
}
當然,您可以跳過模型綁定,直接通過訪問控制器中的HttpContext.Request
來檢索提供的數據。 HttpContext.Request.Body
屬性為您提供內容流,或者您可以通過HttpContext.Request.Forms
訪問表單數據。
由於類型安全,我個人更喜歡模型綁定。
使用 [FromBody]
要強制 Web API 從請求正文中讀取簡單類型,請將[FromBody]屬性添加到參數:
[Route("Edit/Test")] [HttpPost] public IHttpActionResult Test(int id, [FromBody] string jsonString) { ... }
在此示例中,Web API 將使用媒體類型格式化程序從請求正文中讀取jsonString的值。 這是一個示例客戶端請求。
POST http://localhost:8000/Edit/Test?id=111 HTTP/1.1 User-Agent: Fiddler Host: localhost:8000 Content-Type: application/json Content-Length: 6 "test"
當參數具有 [FromBody] 時,Web API 使用 Content-Type 標頭來選擇格式化程序。 在此示例中,內容類型為“application/json”,請求正文為原始 JSON 字符串(不是 JSON 對象)。
在上面的示例中,如果在正文中以正確的格式提供數據,則不需要模型。
對於 URL 編碼的請求看起來像這樣
POST http://localhost:8000/Edit/Test?id=111 HTTP/1.1
User-Agent: Fiddler
Host: localhost:8000
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
=test
當具有 [FromBody] 屬性時,發送的字符串不應是原始字符串,而是 JSON 字符串,因為它包含包裝引號:
"test"
就我而言,我忘記使用
JSON.stringify(bodyStuff).
你走在正確的軌道上。
在您的標題集上
Content-Type: application/x-www-form-urlencoded
POST 請求的主體應該是=test
而沒有別的。 對於未知/可變字符串,您必須對值進行 URL 編碼,這樣您就不會意外地使用輸入字符進行轉義。
我知道這個答案有點舊,並且有一些非常好的答案已經解決了問題。 為了擴大這個問題,我想再提一件在過去的 4 或 5 個小時里讓我發瘋的事情。
模型類中的屬性啟用set屬性非常非常重要。
這將不起作用(參數仍然為空):
/* Action code */
[HttpPost]
public Weird NOURLAuthenticate([FromBody] Weird form) {
return form;
}
/* Model class code */
public class Weird {
public string UserId {get;}
public string UserPwd {get;}
}
這將工作:
/* Action code */
[HttpPost]
public Weird NOURLAuthenticate([FromBody] Weird form) {
return form;
}
/* Model class code */
public class Weird {
public string UserId {get; set;}
public string UserPwd {get; set;}
}
經過 1 小時的斗爭,終於讓它工作了。
這將消除空問題,還以通用方式(無模型綁定)獲取 JSON key1的value1值。
對於新的 WebApi 2 應用程序示例:
郵遞員(看起來完全一樣,如下所示):
POST http://localhost:61402/api/values [Send]
Body
(*) raw JSON (application/json) v
"{ \"key1\": \"value1\" }"
上面的端口61402或 url /api/values可能與您不同。
值控制器.cs
using Newtonsoft.Json;
// ..
// POST api/values
[HttpPost]
public object Post([FromBody]string jsonString)
{
// add reference to Newtonsoft.Json
// using Newtonsoft.Json;
// jsonString to myJsonObj
var myJsonObj = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);
// value1 is myJsonObj[key1]
var valueOfkey1 = myJsonObj["key1"];
return myJsonObj;
}
現在一切都很好,如果我有子鍵,不確定是否需要模型綁定到一個類,或者,子鍵上的 DeserializeObject 是否會起作用。
如果您不想/不需要綁定到具體類,則可以將 JSON 直接傳遞給 WebAPI 控制器。 控制器能夠通過使用ExpandoObject類型來接受 JSON。 下面是方法示例:
public void Post([FromBody]ExpandoObject json)
{
var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)json);
}
將Content-Type標頭設置為application/json並將 JSON 作為正文發送。 keyValuePairs對象將包含 JSON 鍵/值對。
或者,您可以讓該方法接受傳入的 JSON 作為JObject類型(來自 Newtonsoft JSON 庫),並通過將其設置為動態類型,您可以通過點表示法訪問屬性。
public void Post([FromBody]JObject _json)
{
dynamic json = _json;
}
經過長時間擺弄 Google 並在 Stack Overflow 中嘗試錯誤代碼的噩夢,我發現將 ([FromBody] 字符串模型) 更改為 ([FromBody] 對象模型) 確實很神奇,請不要我使用 .NET 4.0 是的,我知道老了但是...
試試下面的代碼:
[Route("/test")]
[HttpPost]
public async Task Test()
{
using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
{
var textFromBody = await reader.ReadToEndAsync();
}
}
對於 .net core 3.1 post(url, JSON.stringify (yourVariable)) 在控制器 MyMethod([FromBody] string yourVariable) 上就像魅力一樣工作
我花了一整天來解決類似的問題。
您必須知道內置序列化器和 Newtonsoft 的工作方式不同。 我的內置案例無法將 JSON 數字解析為 System.String。 但我沒有明顯的例外或細節,只是數據為空。
我只有在我像這樣記錄 ModelState 時才發現它:
logger.LogInformation($"ModelState = {ModelState.IsValid}");
string messages = string.Join("; ", ModelState.Values
.SelectMany(x => x.Errors)
.Select(x => x.ErrorMessage));
logger.LogInformation($"ModelMessages = {messages}");
然后我在日志中看到了特定的異常:
The JSON value could not be converted to System.String
作為修復,我做了:
Microsoft.AspNetCore.Mvc.NewtonsoftJson
。services.AddControllers().AddNewtonsoftJson();
我剛剛遇到了這個並且很沮喪。 我的設置:標頭設置為 Content-Type: application/JSON 並以 JSON 格式傳遞來自正文的信息,並在控制器上讀取 [FromBody]。
一切都設置得很好,我希望它能正常工作,但問題在於發送的 JSON。 由於它是一個復雜的結構,我的一個定義為“抽象”的類沒有被初始化,因此這些值沒有正確分配給模型。 我刪除了抽象關鍵字,它就起作用了..!!!
一個提示,我可以解決這個問題的方法是將數據部分發送到我的控制器並檢查它何時變為空......因為它是一個復雜的模型,我一次將一個模型附加到我的請求參數中。 希望它可以幫助遇到這個愚蠢問題的人。
此外,如果您使用的是 Postman“環境”,請確保在運行使用它的 API 腳本之前選擇該環境。 否則,它只會發送變量字符串 -- {{varname}} -- 而不是它們的關聯值,API 會適當地拒絕這些值。
這也可能派上用場。 我需要將 JSON 字符串傳遞給我的 API 控制器。 但是模型在前期是未知的。 使用 JObject 作為對象類型非常有效。 您可以稍后序列化以獲取字符串。
[FromBody] JObject unknownStringJsonObject
您可以只使用“對象”而不是像這樣的字符串:
public async Task<IActionResult> Method([FromBody] Object plainJson)
然后打印 object:
Console.WriteLine(plainJson.ToString());
就是這樣!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.