【问题标题】:How to pass content body to API Get method如何将内容主体传递给 API Get 方法
【发布时间】:2021-01-12 20:55:35
【问题描述】:

一旦我尝试调用 Web API 控制器方法,我就会收到此错误,

Cannot send a content-body with this verb-type.

我的详细信息控制器如下,

[HttpGet("requestDetails/Details")]
public IActionResult GetDetails([FromHeader] int tenantId,[FromBody]ParamterDTO pdto)
{
    try
    {
        var details = Service.GetDetials(pdto.FromDate, pdto.SearchText, pdto.UserId);
        return Ok(details);
    }
    catch (Exception)
    {
        return StatusCode(500);
    }
}

这就是我使用 Details 控制器方法的方式。

public string GetDetails(string fromDate, string searchText, string userID) {

  try {
    string serviceUrl = "http://localhost/Testapi/api/details/requestDetails/Details";

    string jsonParamterData = new JavaScriptSerializer().Serialize(new {
      FromDate = fromDate,
        SearchText = searchText,
        UserId = userID
    });

    HttpClient client = new HttpClient();

    HttpMethod method = new HttpMethod("GET");
    HttpRequestMessage message = new HttpRequestMessage(method, serviceUrl);

    StringContent content = new StringContent(jsonParamterData, Encoding.UTF8, "application/json");
    client.DefaultRequestHeaders.Add("TenantId", tenantId.ToString());
    client.DefaultRequestHeaders.Add("Authorization", string.Format("bearer {0}", token));
    message.Content = content;

    var response = client.SendAsync(message).Result;
    client.Dispose();
    return response.Content.ToString();
  } catch (Exception ex) {
    NameValueCollection logParams = new NameValueCollection();
    Logger.LogErrorEvent(ex, logParams);
    throw;
  }
}

谁能解释一下,我在这里做错了什么。

更新:

我使用 post 而不是通过更改代码来获取,

HttpMethod method = new HttpMethod("POST");
HttpRequestMessage message = new HttpRequestMessage(method, serviceUrl);

StringContent content = new StringContent(jsonParamterData, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Add("TenantId", tenantId.ToString());
client.DefaultRequestHeaders.Add("Authorization", string.Format("bearer {0}", token));
message.Content = content;
//var response = client.GetStringAsync(message.).Result;
var response = client.SendAsync(message);

但响应结果如下,

【问题讨论】:

  • 你必须使用“帖子”
  • @CasparKleijne 这是访问响应数据的正确方法吗? var response = client.SendAsync(message).Result; client.Dispose(); return response.Content.ToString();
  • @CasparKleijne 我使用了 post 并且它击中了控制器方法。但是api返回的数据不能访问。 var response 值显示为 statusCode 200 ReasonPharse 'ok'
  • 你需要inttenantId做什么?没用?

标签: c# .net asp.net-web-api get


【解决方案1】:

尝试将您的操作更改为:

[Route("requestDetails/Details")]
public ActionResult<Details> GetDetails([FromBody] ParamterDTO pdto)
{
    try
    {
return Service.GetDetials(pdto.FromDate, pdto.SearchText, pdto.UserId);
    //or you can try    
return Ok(Service.GetDetials(pdto.FromDate, pdto.SearchText, pdto.UserId)); 
   // but you need special deserialization
      
    }
    catch (Exception)
    {
        return StatusCode(StatusCodes.Status500InternalServerError, new Details());
    }
}

并将您的请求代码更改为:

using (var client = new HttpClient())
{
    ....your code 
        
    
    var response = client.SendAsync(message);

    if (response.IsSuccessStatusCode)
    {
        return response.Content.ReadAsStringAsync().Result;
                
    }
   ````your code
}

【讨论】:

  • 我的回复显示如下,我如何访问 API 返回的数据。 i.stack.imgur.com/58TQ0.png
  • @thomsan 如果您不喜欢第一种方法,请尝试另一种方法。我编辑一个答案
  • 先生,我的消费方法返回类型是字符串。你能检查我更新的问题吗?
  • 好吧,我也换了
【解决方案2】:

也许可以尝试一些不同的方法。如果你可以OFC...

我用类似于你的代码做了一些快速的尝试。

看看这个……

控制器方法:

    [HttpPost]
    public IActionResult GetDetails([FromHeader] int tenantId, [FromBody] ParameterDto parameter)
    {
        try
        {
            return Ok(parameter);
        }
        catch (Exception)
        {
            return StatusCode(500);
        }
    }

非常简单,只是为了展示它的工作原理,并且没有自定义路由,但我认为这里没有问题。

另外,为了需要我的示例,我将它托管在 localhost(在控制台中独立)。

这是我的 API 消费者代码:

    public static async Task<ParameterDto> Post(ParameterDto dto)
    {
        var _restClient = new RestClient("http://localhost:5000");
        var body = dto != null ? JsonConvert.SerializeObject(dto) : null;

        var request = new RestRequest("/details", Method.POST);

        var absoluteUri = _restClient.BuildUri(request).AbsoluteUri;

        request.AddHeader("TenantId", "2");
        request.AddParameter("application/json; charset=utf-8", body, ParameterType.RequestBody);
        _restClient.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

        var response = await _restClient.ExecuteTaskAsync(request);

        if (response.ResponseStatus != ResponseStatus.Completed || !IsSuccess(response.StatusCode) ||
               response.StatusCode == HttpStatusCode.BadRequest || response.StatusCode == HttpStatusCode.Unauthorized)
        {
            var message = string.Format("POST request failed. Code: {0}, Status: {1}",
                response.StatusCode, response.ResponseStatus);

            throw new Exception(message);
        }

        return JsonConvert.DeserializeObject<ParameterDto>(response.Content);
    }

    public static bool IsSuccess(HttpStatusCode httpStatusCode)
    {
        return (int)httpStatusCode >= 200 && (int)httpStatusCode <= 299;
    }

如您所见,有一些样板代码,但我有时会使用这种方法,所以我只是复制我的代码。

它就像一个魅力!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    • 2022-10-04
    • 2018-07-14
    • 2021-06-30
    相关资源
    最近更新 更多