私は.NET Web APIでパラメータバインディングを使用しています(下記のクラスを参照)。私のコントローラのアクションでは、3つのパラメータがあり、それぞれオプションです(メソッドのパラメータリストにデフォルト値があります)。しかし、HttpParameterBindingクラスが欠落しているパラメータを無視する方法を理解できません。次のURLを使用してリクエストした場合:.NET Web APIでHttpParameterBindingと組み合わせてデフォルトのパラメータ値を使用する方法?
http://localhost:3208/api/fruit?query=gr&start=0&limit=10
...すべてうまく動作します。私は(limit
パラメータなし)、次のURLを使用する場合でも:
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を取得して、リクエストデータ内の対応する値が見つからない場合、アクションメソッドに値を渡さないようにする方法はありますか?
マイウェブ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);
}
}
intを使用できないのはなぜですか?関数のパラメータでintの代わりに –
私は理解していない。関数のパラメータに 'int'を使っています。あなたが私とは異なる機能を考えているのでない限り。 – Trevor
nullable int(int?) –