2016-05-17 18 views
1

が、私は以下のクラスを持っているルーティングとエラー '複数のアクションが見つかりました'特定のログを取得するための最初のものと、ログのリストを取得するためのものです。 :/ logs/123経由で特定のログのGETリクエストを行うと、最初のアクションが正しく呼び出され、同様に/ログのGETリクエストを行うと、2番目のアクションが正しく呼び出されます(そのクラスで定義されているプロパティはオプションです)常に提供する必要はありません)。これは次のように、それは、int型のidパラメーターの代わりにクラスを使用していますので、RESTfulなWeb APIが

しかし、私は最初のGETメソッドを変更したい(これは指定しています注意して異なる(単数)上記第二のアクションに入力):

async Task<IHttpActionResult> Get([FromUri]GetLogRequestDto dto) 

このGetLogRequestDtoクラスには、次のようになります。

public class GetLogRequestDto 
{ 
    [Required] 
    [Range(100, int.MaxValue)] 
    public int Id { get; set; } 
} 

このアプローチの背後にある私の推論は、私はモデルの検証が私の標準ModelStateValidationActionFilterを経る必要があり、また、特定の検証は、このクラス、R内の属性を置くことができるようにしました'int id'パラメータのアプローチを使用する場合よりも、検証を実行する必要がありません。

私もこのアプローチを実装し、ログ/ 1 /呼び出そうとすると、私は次のエラーを取得する:

Multiple actions were found that match the request

それは、これらの2つの方法でのparamsとして使用する2つの異なるタイプの区別はありません。

私が設定したデフォルトルートは次のとおりです。

config.Routes.MapHttpRoute(
       name: "controller-id", 
       routeTemplate: "{controller}/{id}", 
       defaults: new { id = RouteParameter.Optional } 
       ); 

問題があり、なぜ私が理解することはできません - それは一つの方法が、他ではないが働く理由。

答えて

0

GET要求で単一の基本型パラメータ(これは経路の一部でもあります)を処理するために複雑な型を使用するのは良い考えではありません。

このアプローチを使用すると、フレームワークはルートパラメータをその複合型にバインドできません(ルート定義には単純型でなければならないidパラメータが必要です)。

変更を元に戻し、idパラメータをもう一度intにすることを強くお勧めします。

代替方法として、this great postに従い、単純型であっても検証属性で修飾されたメソッドパラメータを検証するアクションフィルタを実装することができます。

ここでは、アクションパラメータを検証するために使用されるアクションフィルター属性を表すマークVinczeのブログ記事からの抜粋です:

public class ValidateActionParametersAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext context) 
    { 
     var descriptor = context.ActionDescriptor as ControllerActionDescriptor; 

     if (descriptor != null) 
     { 
      var parameters = descriptor.MethodInfo.GetParameters(); 

      foreach (var parameter in parameters) 
      { 
       var argument = context.ActionArguments[parameter.Name]; 

       EvaluateValidationAttributes(parameter, argument, context.ModelState); 
      } 
     } 

     base.OnActionExecuting(context); 
    } 

    private void EvaluateValidationAttributes(ParameterInfo parameter, object argument, ModelStateDictionary modelState) 
    { 
     var validationAttributes = parameter.CustomAttributes; 

     foreach (var attributeData in validationAttributes) 
     { 
      var attributeInstance = CustomAttributeExtensions.GetCustomAttribute(parameter, attributeData.AttributeType); 

      var validationAttribute = attributeInstance as ValidationAttribute; 

      if (validationAttribute != null) 
      { 
       var isValid = validationAttribute.IsValid(argument); 
       if (!isValid) 
       { 
        modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name)); 
       } 
      } 
     } 
    } 
}