1

この質問はthis questionの結果です。NinjectがASP.NET MVCのカスタム検証attribubteで動作していません

私はASP.NET MVC Webアプリケーションを開発しています。私のプロジェクトでは、ビューモデルクラスにデータアノテーションを使用してリモート検証を行っています。私はデフォルトのリモート属性がサーバーの検証をサポートしていないことを知っています。私はアクションメソッドで再度検証することができます。しかし、私は懸念の分離に違反していることを望んでいません。

私はカスタムサーバークライアントのリモート検証属性を作成しようとしました。私はオンラインでコードを見つけ、それを使用しました。しかし、サーバーの検証が行われたときにエラーが表示されます。私は依存性注入のためにNinjectを使用しています。 Ninjectが検証属性に依存性を注入できないため、エラーが発生しました。下記の私のシナリオをご覧ください。

これは私のカスタムリモート検証属性です:

public class RemoteClientServerAttribute : RemoteAttribute 
    { 
     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      // Get the controller using reflection 
      Type controller = Assembly.GetExecutingAssembly().GetTypes() 
       .FirstOrDefault(type => type.Name.ToLower() == string.Format("{0}Controller", 
        this.RouteData["controller"].ToString()).ToLower()); 
      if (controller != null) 
      { 
       // Get the action method that has validation logic 
       MethodInfo action = controller.GetMethods() 
        .FirstOrDefault(method => method.Name.ToLower() == 
         this.RouteData["action"].ToString().ToLower()); 
       if (action != null) 
       { 
        // Create an instance of the controller class 
        object instance = Activator.CreateInstance(controller); 
        // Invoke the action method that has validation logic 
        object response = action.Invoke(instance, new object[] { value }); 
        if (response is JsonResult) 
        { 
         object jsonData = ((JsonResult)response).Data; 
         if (jsonData is bool) 
         { 
          return (bool)jsonData ? ValidationResult.Success : 
           new ValidationResult(this.ErrorMessage); 
         } 
        } 
       } 
      } 

      return ValidationResult.Success; 
      // If you want the validation to fail, create an instance of ValidationResult 
      // return new ValidationResult(base.ErrorMessageString); 
     } 

     public RemoteClientServerAttribute(string routeName) 
      : base(routeName) 
     { 
     } 

     public RemoteClientServerAttribute(string action, string controller) 
      : base(action, controller) 
     { 
     } 

     public RemoteClientServerAttribute(string action, string controller, 
      string areaName) 
      : base(action, controller, areaName) 
     { 
     } 
    } 

これは私のコントローラクラス

public class CategoryController : Controller 
    { 
     private ICategoryRepo categoryRepo; 

     public CategoryController() 
     { 

     } 

     public CategoryController(ICategoryRepo categoryParam) 
     { 
      this.categoryRepo = categoryParam; 
     } 
     . 
     . 
     //remote validation action 
     public JsonResult IsNameUnique(string Name) 
     { 
      IEnumerable<Category> categories = categoryRepo.Categories.Where(x => x.Name.Trim() == Name); 

      Category category = categories.FirstOrDefault(); 
      return Json(category==null, JsonRequestBehavior.AllowGet); 
     } 
} 

検証はクライアント側を通過し、サーバ側に来たとき、それはエラーをスローを開始しています。それはパラメータなしのコンストラクタを見つけることができないので、これははい、それは方法を誤り

enter image description here

を投げていないされ

は、例外を発見しました。

私はこの

public CategoryController() 
     { 
      categoryRepo = new CategoryRepo(); 
     } 

のようなパラメータなしのコンストラクタを追加しました。しかし、私がしなければ、問題は、私はNinjectを使用していた理由はまったく意味をなさない、ということです。それは依存関係を作っている。しかし、私がこのようにしないと、categoryRepoはIsNameUniqueアクションでnull例外をスローします。だから私は自分のカスタムリモート検証属性でNinjectを動作させることができますか?

+0

Activator.CreateInstanceでコントローラを作成する代わりに、NInjectにそれを与えるように依頼できますか?私はNInjectについて十分に分かりません。 –

答えて

1

は交換してみます。

object instance = DependencyResolver.Current.GetService(controller); 

object instance = Activator.CreateInstance(controller); 

私は、これは物議ServiceLocatorパターンの使用であることを指している必要があります。しかし、私はこの属性でそれをどうやってやるのかほとんど分かりません。

+0

フィルターはどうですか?私は、フィルタのコンストラクタでDIよりも属性を設定する方が簡単だと思います。この場合も同じことが成立するかもしれません。 – Max

+0

ありがとうございます。それは完全に動作します。あなたの助けを本当に感謝します。 –