如何从URI传递变量作为ASP.NET WebAPI操作方法的参数?

时间:2015-11-09 20:18:34

标签: c# json asp.net-web-api2

我以前工作过,现在我没有。但是,我看不出我做了什么让它不起作用?

这是我的MVC API控制器:

[HttpPost]
public Models.CustomerAddress Add(string Customer)
{
    //the customer is a json string
}

这是我的C#桌面客户端:

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(Shared.URL);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Shared.HeaderType));
    string jsonInput = JsonConvert.SerializeObject(customer);
    HttpContent contentPost = new StringContent(jsonInput, Encoding.UTF8, "application/json");
   var response = client.PostAsync(string.Format("http://myuri/api/Customer/Add?Customer="), contentPost).Result;
    response.EnsureSuccessStatusCode();
    string json = await response.Content.ReadAsStringAsync();
    return JsonConvert.DeserializeObject<Model.CustomerAddress>(json);
}

客户对象肯定是填充的......

这会调用我的api,但Customer字符串为null ??

3 个答案:

答案 0 :(得分:2)

使用 [FromUri]

要强制Web API从URI中读取复杂类型,请将[FromUri]属性添加到参数中。以下示例定义了GeoPoint类型,以及从URI获取GeoPoint的控制器方法。

public class GeoPoint
{
    public double Latitude { get; set; } 
    public double Longitude { get; set; }
}

public ValuesController : ApiController
{
    public HttpResponseMessage Post([FromUri] GeoPoint location) { ... }
}

客户端可以将纬度和经度值放在查询字符串中,Web API将使用它们构建GeoPoint。例如:

  

http://localhost/api/values/?Latitude=47.678558&Longitude=-122.130989

ASP.NET WebAPI:Details and examples

答案 1 :(得分:1)

客户端和服务器之间肯定存在不匹配。您的URI指定名称为Customer的参数,该参数与方法的参数匹配,但您不会向该参数提供任何值。 =符号后面没有任何内容。

在客户端代码中传递序列化对象的方式,它实际上将作为请求的主体到达服务器。要将其作为方法中的参数,您应该使用[FromBody]属性并从网址中删除&Customer=部分。

[HttpPost]
public Models.CustomerAddress Add([FromBody]string Customer)
{
    //the customer is a json string
}

这将是客户:

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(Shared.URL);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Shared.HeaderType));
    string jsonInput = JsonConvert.SerializeObject(customer);
    HttpContent contentPost = new StringContent(jsonInput, Encoding.UTF8, "application/json");
   var response = client.PostAsync("http://myuri/api/Customer/Add", contentPost).Result;
    response.EnsureSuccessStatusCode();
    string json = await response.Content.ReadAsStringAsync();
    return JsonConvert.DeserializeObject<Model.CustomerAddress>(json);
}

这是将数据传递到Post方法的更好方法,因为您不需要对其进行编码以满足URI格式的要求。在请求正文中发送数据也可以容纳更大的有效负载。

答案 2 :(得分:0)

您只需将控制器更改为:

即可
[HttpPost]
public Models.CustomerAddress Add(Customer customer)
{
    // customer gets instantiated by the model binder
}

客户现在可以发布这样的请求:

    var jsonCustomer = JsonConvert.SerializeObject(customer);
    var contentPost = new StringContent(jsonCustomer, Encoding.UTF8, "application/json");
    var response = client.PostAsync("http://myuri/api/Customer/Add", contentPost).Result;