WebApi 属性路由 - 将路由参数绑定到 GET 对象
WebApi attribute routing - Bind route parameter to an object for GETs
目前,对于每个 GET,我都必须从路由参数中手动创建一个查询对象。
是否可以直接绑定到查询对象?
所以,而不是:
[Route("{id:int}")]
public Book Get(int id) {
var query = new GetBookByIdQuery {
Id = id
};
// execute query and return result
}
我可以这样做:
[Route("{id:int}")]
public Book Get(GetBookByIdQuery query) {
// execute query and return result
}
其中 GetBookByIdQuery
看起来像:
public class GetBookByIdQuery {
public int Id { get; set;}
}
您可以使用class作为参数,但由于id在方法定义中不再是参数,所以不能包含在Route中。
public class LibraryController : ApiController
{
[HttpGet]
public Book Get(GetBookByIdQuery query)
{
// Process query... & return
}
}
您可以使用 link:
来调用它
http://localhost:54556/api/Library?id=12
答案是定义你自己HttpParameterBinding
。
这是我做的例子。
首先我创建了我的 CustomParameterBinding
public class CustomParameterBinding : HttpParameterBinding
{
public CustomParameterBinding( HttpParameterDescriptor p ) : base( p ) { }
public override System.Threading.Tasks.Task ExecuteBindingAsync( System.Web.Http.Metadata.ModelMetadataProvider metadataProvider, HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken )
{
// Do your custom logic here
var id = int.Parse( actionContext.Request.RequestUri.Segments.Last() );
// Set transformed value
SetValue( actionContext, string.Format( "This is formatted ID value:{0}", id ) );
var tsc = new TaskCompletionSource<object>();
tsc.SetResult(null );
return tsc.Task;
}
}
下一步是创建自定义属性来装饰参数:
public class CustomParameterBindingAttribute : ParameterBindingAttribute
{
public override HttpParameterBinding GetBinding( HttpParameterDescriptor parameter )
{
return new CustomParameterBinding( parameter );
}
}
最后控制器看起来像:
public class ValuesController : ApiController
{
// GET api/values/5
[Route( "api/values/{id}" )]
public string Get([CustomParameterBinding] string id )
{
return id;
}
}
所以现在当我打电话给 http://localhost:xxxx/api/values/5
我得到:"This is formatted ID value:5"
要从 URI 中读取复杂类型,可以使用 [FromUri]
[Route("{id:int}")]
public Book Get([FromUri] GetBookByIdQuery query) {
// execute query and return result
}
如果您请求 api/values/2,则查询对象的 ID 属性 将为 2;
目前,对于每个 GET,我都必须从路由参数中手动创建一个查询对象。
是否可以直接绑定到查询对象?
所以,而不是:
[Route("{id:int}")]
public Book Get(int id) {
var query = new GetBookByIdQuery {
Id = id
};
// execute query and return result
}
我可以这样做:
[Route("{id:int}")]
public Book Get(GetBookByIdQuery query) {
// execute query and return result
}
其中 GetBookByIdQuery
看起来像:
public class GetBookByIdQuery {
public int Id { get; set;}
}
您可以使用class作为参数,但由于id在方法定义中不再是参数,所以不能包含在Route中。
public class LibraryController : ApiController
{
[HttpGet]
public Book Get(GetBookByIdQuery query)
{
// Process query... & return
}
}
您可以使用 link:
来调用它http://localhost:54556/api/Library?id=12
答案是定义你自己HttpParameterBinding
。
这是我做的例子。
首先我创建了我的 CustomParameterBinding
public class CustomParameterBinding : HttpParameterBinding
{
public CustomParameterBinding( HttpParameterDescriptor p ) : base( p ) { }
public override System.Threading.Tasks.Task ExecuteBindingAsync( System.Web.Http.Metadata.ModelMetadataProvider metadataProvider, HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken )
{
// Do your custom logic here
var id = int.Parse( actionContext.Request.RequestUri.Segments.Last() );
// Set transformed value
SetValue( actionContext, string.Format( "This is formatted ID value:{0}", id ) );
var tsc = new TaskCompletionSource<object>();
tsc.SetResult(null );
return tsc.Task;
}
}
下一步是创建自定义属性来装饰参数:
public class CustomParameterBindingAttribute : ParameterBindingAttribute
{
public override HttpParameterBinding GetBinding( HttpParameterDescriptor parameter )
{
return new CustomParameterBinding( parameter );
}
}
最后控制器看起来像:
public class ValuesController : ApiController
{
// GET api/values/5
[Route( "api/values/{id}" )]
public string Get([CustomParameterBinding] string id )
{
return id;
}
}
所以现在当我打电话给 http://localhost:xxxx/api/values/5
我得到:"This is formatted ID value:5"
要从 URI 中读取复杂类型,可以使用 [FromUri]
[Route("{id:int}")]
public Book Get([FromUri] GetBookByIdQuery query) {
// execute query and return result
}
如果您请求 api/values/2,则查询对象的 ID 属性 将为 2;