簡體   English   中英

400錯誤的請求,通過HttpClient.PutAsync將Json提交到WebApi

[英]400 Bad Request submitting Json to WebApi via HttpClient.PutAsync

通常,從服務到webapi調用都將使用序列化的對象,但是在這種情況下,我必須為調用使用json表示形式。

該過程將是將json反序列化為適當的類,然后照常進行處理。

HttpClient放

從控制台應用程序中調用方法

   public async Task<ApiMessage<string>> PutAsync(Uri baseEndpoint, string relativePath, Dictionary<string, string> headerInfo, string json)
    {
        HttpClient httpClient = new HttpClient();
        if (headerInfo != null)
        {
            foreach (KeyValuePair<string, string> _header in headerInfo)
                _httpClient.DefaultRequestHeaders.Add(_header.Key, _header.Value);
        }

        httpClient.DefaultRequestHeaders.Accept.Clear();
        httpClient.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json-patch+json"));

        var content = new StringContent(json, Encoding.UTF8, "application/json-patch+json");

        var response = await httpClient.PutAsync(CreateRequestUri(relativePath, baseEndpoint), content);
        var data = await response.Content.ReadAsStringAsync();

        ... 
    }

終點

呼叫永遠不會到達端點。 如果刪除[FromBody]標記,則端點被命中,但是按預期,該參數為null。 似乎正在發生某種過濾。

    [HttpPut()]
    [Route("")]
    [SwaggerResponse(StatusCodes.Status200OK)]
    [SwaggerResponse(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> UpdatePaymentSync([FromBody] string paymentSyncJson)
    {
        if (string.IsNullOrEmpty(paymentSyncJson))
            return BadRequest();
         //hack: don't have access to models so need to send json rep
         var paymentSync = JsonConvert.DeserializeObject<PaymentSync>(paymentSyncJson);
       ....
    }

這是json負載。 我以為[FromBody]處理簡單類型,但這證明我錯了。

  {
    "paymentSyncJson": {
      "id": 10002,
      "fileName": "Empty_20190101.csv",
      "comments": "Empty File",
      "processingDate": "2019-01-02T19:43:11.373",
      "status": "E",
      "createdDate": "2019-01-02T19:43:11.373",
      "createdBy": "DAME",
      "modifiedDate": null,
      "modifiedBy": null,
      "paymentSyncDetails": []
    }
  }

您的有效負載不是字符串,而是json,這就是運行時無法將主體解析為您請求的string paymentSyncJson

要解決此問題,請創建一個反映json的匹配dto

public class PaymentDto
{
    public PaymentSyncDto PaymentSyncJson { get; set; }
}
public class PaymentSyncDto
{
    public int Id { get; set; }
    public string FileName { get; set; }
    public string Comments { get; set; }
    public DateTime ProcessingDate { get; set; }
    public string Status { get; set; }
    public DateTime CreatedDate { get; set; }
    public string CreatedBy { get; set; }
    public DateTime ModifiedDate { get; set; }
    public string ModifiedBy { get; set; }
    public int[] PaymentSyncDetails { get; set; }
}

然后在控制器方法中使用它從請求主體中讀取數據

public async Task<IActionResult> UpdatePaymentSync([FromBody] PaymentDto payment)

只是擴大我的評論。

OP做了:

[HttpPut()]
[Route("")]
[SwaggerResponse(StatusCodes.Status200OK)]
[SwaggerResponse(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> UpdatePaymentSync([FromBody] string paymentSyncJson)
{
    if (string.IsNullOrEmpty(paymentSyncJson))
        return BadRequest();
     //hack: don't have access to models so need to send json rep
     var paymentSync = JsonConvert.DeserializeObject<PaymentSync>(paymentSyncJson);
   ....
}

在他們將[FromBody] string paymentSyncJson放入的[FromBody] string paymentSyncJson ,FromBody會嘗試反序列化為您指定的類型,在這種情況下為string 我建議這樣做:

public async Task<IActionResult> UpdatePaymentSync([FromBody] JObject paymentSyncJson)

然后,您可以更改此行:

var paymentSync = JsonConvert.DeserializeObject<PaymentSync>(paymentSyncJson);

至:

var paymentSync = paymentSyncJson.ToObject<PaymentSync>();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM