Httpclient通过控制台应用C#消耗web api

时间:2017-05-19 19:06:43

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

我正在尝试使用Httpclient通过控制台应用程序使用下面的web api。我被困在如何传递参数。该参数将作为命令行参数出现。 这是我的Rest api

[HttpPost, Route("Test")]
        public IHttpActionResult Test(bool sample = false)
        {             
                return Ok();
        }

参数来自于命令行参数

/Parameters:sample=true.

以下是我在控制台应用程序中解析参数的方法

 static int Main(string[] args)
        {

                if (args.Length == 0)
                {
                    Console.Error.WriteLine("No action provided.");
                    return -1;
                }
                foreach (string param in args)
                {
                    switch (param.Substring(0, param.IndexOf(":")))
                    {
                        case "/Action":
                            action = param.Substring(param.IndexOf(":") + 1);
                            break;
                        case "/Parameters":
                            parameter = param.Substring(param.IndexOf(":") + 1);
                            break;    
                    }
                }
            return 0;
        }

一旦我得到了这种格式的参数

parameter =“sample = true”

我正在尝试调用web api调用但无法传递参数值。任何人都可以指出我做错了什么

    client.BaseAddress = new Uri(ConfigurationManager.AppSettings.Get("BaseWebApiUrl"));
                    client.DefaultRequestHeaders.Accept.Clear();
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                    var apiUrl = GetApiURL();


                   var Context = new StringContent(JsonConvert.SerializeObject(parameter), Encoding.UTF8, "application/json");

 var respFeed = await client.PostAsync(apiUrl, Context);

3 个答案:

答案 0 :(得分:0)

您应该将其作为网址的一部分传递。

private void CallService(bool sample)
{
    client.BaseAddress = new Uri(ConfigurationManager.AppSettings.Get("BaseWebApiUrl"));
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var apiUrl = $"http://yourserver:port/api/somecontroller/?sample={sample}";

    var Context = new StringContent(JsonConvert.SerializeObject(parameter), Encoding.UTF8, "application/json");

    var respFeed = await client.PostAsync(apiUrl, Context);
}

答案 1 :(得分:0)

默认情况下,Web Api中的基本类型参​​数永远不会绑定到请求的主体。

如果您想强制将bool参数与请求正文绑定,则需要使用FromBodyAttribute对其进行修饰:

[HttpPost, Route("Test")]
public IHttpActionResult Test([FromBody] bool sample = false)
{             
    return Ok();
}

请注意即使您这样做,您的请求也无法用于Web Api。必须使用特定格式传递单个基本类型参​​数。在您的情况下,您的请求正文必须如下:

=true

更好的方法是将Action参数转换为类:

public class TestModel
{
    public bool Sample { get; set; }
}

[HttpPost, Route("Test")]
public IHttpActionResult Test(TestModel model)
{
    return Ok();
}

这样您就可以将Json对象作为请求体发送,如:

{
    "sample": true
}

这是一个如何实现这样结果的小例子:

var parameterDictionary = parameter.Split("=").ToDictionary(s => s[0], s => bool.Parse(s[1]));
var json = JsonConvert.SerializeObject(parameterDictionary);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var respFeed = await client.PostAsync(apiUrl, content);

答案 2 :(得分:0)

首先,将方法签名更改为

public IHttpActionResult Test([FromBody]bool sample = false)

因为原始类型是从URL / Query String解析而不是body。通过添加FromBody属性将强制它从正文中解析。

接下来,既然你说参数值为var参数=" sample = true&#34 ;;,请将参数构造更改为

var jsonParam = new { sample = parameter.split('=')[1]}; // I'm leaving null checks and validation for simplicity
var Context = new StringContent(JsonConvert.SerializeObject(jsonParam), Encoding.UTF8, "application/json");