为复杂的数据传输对象定义路由

define routing for complex data transport objects

能够像这样定义路由:

Route("Calculator/AddTwoNumbers/a/{a}/b/{a}")]
public IHttpActionResult AddTwoNumbers(double a, double b)

非常适合调用这样的端点:

http://localhost:64466/Calculator/AddTwoNumbers/a/1/b/2

我很好奇在 payload/data 传输对象 (DTO) 变得更加复杂(即分层)的情况下该怎么做。以上面的例子为例,这可能是一个对应的DTO:

public class PayLoad
{
    public double a { get; set; }
    public double b { get; set; }
}

像这样:

Route("Calculator/AddTwoNumbers/a/{a}/b/{a}")]
public IHttpActionResult AddTwoNumbers(PayLoad payLoad)

不起作用,因为在 asp.net mvc 中似乎没有 'model binding' (?)。

如果 DTO 更复杂,我该怎么办?

您需要使用 [FromUri] 属性修饰 payLoad 参数定义:

public IHttpActionResult AddTwoNumbers([FromUri] PayLoad payLoad)

MSDN

我觉得有2种方法可以解决用WepApi获取数据:
1- 使用 [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 Get([FromUri] GeoPoint location) { ... }
}

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

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

2- 使用 [FromBody]: 要强制 Web API 从请求正文中读取简单类型,请将 [FromBody] 属性添加到参数中:

public HttpResponseMessage Post([FromBody] string name) { ... }

此代码解释如下:Parameter Binding in ASP.NET Web API