Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 400通过HttpClient.PutAsync向WebApi提交Json的错误请求_C#_Json_Asp.net Core Webapi_Dotnet Httpclient - Fatal编程技术网

C# 400通过HttpClient.PutAsync向WebApi提交Json的错误请求

C# 400通过HttpClient.PutAsync向WebApi提交Json的错误请求,c#,json,asp.net-core-webapi,dotnet-httpclient,C#,Json,Asp.net Core Webapi,Dotnet Httpclient,通常,从服务到webapi调用将使用序列化对象,但在本例中,我必须为调用使用json表示 这个过程是将json反序列化到适当的类,然后像往常一样处理 HttpClient Put 方法是从控制台应用程序中调用的 public async Task<ApiMessage<string>> PutAsync(Uri baseEndpoint, string relativePath, Dictionary<string, string> headerInfo

通常,从服务到webapi调用将使用序列化对象,但在本例中,我必须为调用使用json表示

这个过程是将json反序列化到适当的类,然后像往常一样处理

HttpClient Put 方法是从控制台应用程序中调用的

   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();

        ... 
    }
这是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)
public异步任务UpdatePaymentSync([FromBody]PaymentDto付款)

您的负载不是字符串,而是json,这就是为什么运行时无法将正文解析为您请求的
字符串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)
public异步任务UpdatePaymentSync([FromBody]PaymentDto付款)

只是在我的评论上展开

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);
   ....
}
然后您可以更改此行:

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

var paymentSync=paymentSyncJson.ToObject();

只是在我的评论上展开

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);
   ....
}
然后您可以更改此行:

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

var paymentSync=paymentSyncJson.ToObject();

如果它没有到达您的端点,它可能是路由,我看到您的方法上有一个路由属性是空的,您的控制器类上有路由前缀吗?
[FromBody]
将尝试反序列化到给定的对象-在您的例子中是字符串。。您可以将
([FromBody]JObject payment)
-这将防止您需要反序列化对象。若要转换为对象,您可以执行
payment.ToObject()
@Callumlington请回答这个问题,这样我就可以“检查它”-就是这样@威尔洛佩兹完成了!如果它没有到达端点,可能是路由,我看到你的方法上有一个路由属性是空的,你的控制器类上有路由前缀吗?
[FromBody]
将尝试反序列化到给定的对象-在你的例子中是字符串。。您可以将
([FromBody]JObject payment)
-这将防止您需要反序列化对象。若要转换为对象,您可以执行
payment.ToObject()
@Callumlington请回答这个问题,这样我就可以“检查它”-就是这样@威尔洛佩兹完成了!感谢您的回复,但上面的评论中有一个答案。通常我就是这样做的,效果很好……在这个例子中,这是系统之间的互操作问题感谢您的回复,但上面的评论中有一个答案。通常我就是这样做的,效果很好……在这个例子中,这是系统之间的互操作问题