2016-04-19 38 views
0

我在我的.NET Web API中使用參數綁定(請參見下面的類)。在我的控制器操作中,我有三個參數,每個參數都是可選的(我在方法參數列表中有默認值)。但是,我無法弄清楚如何讓我的HttpParameterBinding類忽略缺少的參數。如果我使用以下網址提出請求:如何在.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. 

我試過只是在我HttpParameterBinder如果不設置值Descriptor.ParameterName沒有出現在Query String中,但是這產生了與上述相同的錯誤。任何想法如何我可以讓HttpParameterBinding只是沒有價值的行動方法,如果它沒有找到對應的值在請求數據?


我的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

爲什麼你不能使用int?而不是int在函數參數 –

+0

我不知道我明白。我在函數參數中使用了'int'。除非你想到與我不同的功能。 – Trevor

+1

我的意思是可空int(int?) –

回答

1

使用可空int(int?)而不是隻在您的函數參數int類型。