我在.NET Web API中使用参数绑定(参见下面的类)。在我的控制器操作中,我有三个参数,每个参数都是可选的(我在方法参数列表中有默认值)。但是,我无法弄清楚如何使我的HttpParameterBinding类忽略缺少的参数。如果我使用以下网址发出请求:
http://localhost:3208/api/fruit?query=gr&start=0&limit=10
......一切正常。但是如果我使用以下URL(没有limit
参数):
http://localhost:3208/api/fruit?query=gr&start=0
...我收到以下错误:
The parameters dictionary contains a null entry for parameter 'limit' of non-nullable type 'System.Int32' for method 'System.Collections.Generic.IEnumerable`1[System.String] Get(System.String, Int32, Int32)' in 'WebAPITest.Controllers.Apis.TestController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
如果Descriptor.ParameterName
中Query String
未显示,我尝试在HttpParameterBinder中设置一个值,但这会产生与上面相同的错误。如果在请求数据中找不到相应的值,我怎么能让HttpParameterBinding只将值传递给action方法?
我的Web API控制器如下所示:
[TestApi]
[RoutePrefix("api")]
public class TestController : ApiController
{
[HttpGet]
[Route("fruit")]
public IEnumerable<string> Get(string query = "", int start = 0, int limit = Int32.MaxValue)
{
IEnumerable<string> fruits = new string[] {
"Apple",
"Banana",
"Cherry",
"Dragonfruit",
"Elderberry",
"Fig",
"Grape",
"Honeydew",
"Watermelon"
};
return fruits.Where(f => f.ToLower().Contains(query.ToLower())).Skip(start).Take(limit);
}
}
我的类型绑定器如下所示:
public class TestTypeBinder : HttpParameterBinding
{
public TestTypeBinder(HttpParameterDescriptor descriptor) : base(descriptor) {}
public override Task ExecuteBindingAsync(System.Web.Http.Metadata.ModelMetadataProvider metadataProvider, HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
{
object paramValue = ReadTypeFromRequest(actionContext);
SetValue(actionContext, paramValue);
TaskCompletionSource<AsyncVoid> tcs = new TaskCompletionSource<AsyncVoid>();
tcs.SetResult(default(AsyncVoid));
return tcs.Task;
}
private object ReadTypeFromRequest(HttpActionContext actionContext)
{
string dataValue = HttpUtility
.ParseQueryString(actionContext.Request.RequestUri.Query)
.Get(Descriptor.ParameterName);
if (!string.IsNullOrEmpty(dataValue)) {
if (Descriptor.ParameterType == typeof(int))
return Convert.ToInt32(dataValue);
else if (Descriptor.ParameterType == typeof(string))
return dataValue;
}
return null;
}
}
public struct AsyncVoid { }
最后,我的属性类看起来像这样:
[AttributeUsage(AttributeTargets.Class)]
public class TestApiAttribute : Attribute, IControllerConfiguration
{
public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
{
Func<HttpParameterDescriptor, HttpParameterBinding> tvParameterBinder = param => new TestTypeBinder(param);
controllerSettings.ParameterBindingRules.Insert(0, typeof(string), tvParameterBinder);
controllerSettings.ParameterBindingRules.Insert(0, typeof(int), tvParameterBinder);
}
}
答案 0 :(得分:1)
在函数参数中使用nullable int(int?)而不仅仅是int类型。