2016-08-31 11 views
-1

異なる署名を持つ複数のメソッドがあり、それぞれのメソッドにカスタムログ例外を含むtry-catchブロックがあります。 (複数のコントローラで同じ構造)。C#パラメータとしての機能 - メソッドの構造を繰り返す

public class TestController : BaseController 
{ 
    public static ActionResult One(int param1, string param2) 
    { 
     try 
     { 
      // Do something 
     } 
     catch (Exception e) 
     { 
      LogException(e.Message); 
      AddModelError(e.Message); 
     } 
     return View("ViwName1"); 
    } 

    public static ActionResult Two(Date param3, bool param4) 
    { 
     try 
     { 
      // Do something 
     } 
     catch (Exception e) 
     { 
      LogException(e.Message); 
      AddModelError(e.Message); 
     } 
     return View("ViwName2"); 
    } 
} 

私は

public class TestController : BaseController 
{ 
    public static ActionResult One(int param1, string param2) 
    { 
     // Do something (*) 
     // Call "ActionWithTryCatch" method that has a "function argument" to "Do something (*)" 
    } 

    public ActionResult ActionWithTryCatch(MyDelegate del, string viewName) 
    { 
     try 
     { 
      return del.Invoke(); 
     } 
     catch (Exception e) 
     { 
      LogException(e.Message); 
      AddModelError(e.Message); 
     } 
     return View(viewName); 
    } 
} 

¿私はそれをどのように行うことができ、他のすべてのメソッドのtry-catchブロックを回避し、実行するための方法がありますかしら?私は代理人を使用している例を見てきましたが、それは強く型付けされていることを理解しています。ありがとう!

+0

奇妙な構成の構文を解析できません。 'ActionWithTryCatch'の中で、' del.Invoke() 'が' One() 'と' service.MethodTwo(param3、param4);で 'service.MethodOne(param1、param2);を実行するようにしたいのですか? 'Two()'で? –

+0

もしそうなら、簡単です: 'public ActionResult ActionWithTryCatch(action act、String viewName){try {act();例えば、ActionWithTryCatch(()=> service.MethodTwo(param3、param4)、 "ViewName2"); –

+0

として呼び出すか、あるいは 'public ActionResult ActionWithTryCatch(Func del 、string viewName) '? ( 'return del.Invoke();'デリゲートは 'ActionResult'を返すようです)... –

答えて

1

に見recommand (AOP)。しかし、コントローラ上のすべてのアクションに特定のTry Catchエラー処理ロジックを適用したいのであれば、AOPフレームワーク全体を取り込む価値はないでしょう。代わりにHandleErrorAttributeを利用するか、コントローラークラスのOnExceptionメソッドをオーバーライドすることができます。あなたはあなただけのベースコントローラクラスにオーバーライドさonExceptionをロジックを移動して、あなたのすべてを持つことができ、さらにその後、抽象的にそれを望んでいた場合

public class TestController 
{ 
    private TestService service; 

    public TestController(TestService service) 
    { 
     this.service = service; 
    } 

    public ActionResult One(int param1, string param2) 
    { 
     this.service.MethodOne(param1, param2); 
     return View("ViwName1"); 
    } 

    public ActionResult Two(Date param3, bool param4) 
    { 
     this.service.MethodTwo(param3, param4); 
     return View("ViwName2"); 
    } 

    protected override void OnException(ExceptionContext filterContext) 
    { 
     LogException(filterContext.Exception.Message); 
     AddModelError(filterContext.Exception.Message); 

     var errorView = new ViewResult { ViewName = "~/Path/To/Error/View" }; 
     filterContext.Result = errorView; 
    } 
} 

:あなたはこのようなあなたのコントローラーを書くことができたとえば

コントローラはベースコントローラから継承します。

あなたはMVCで統一エラー処理のいくつかの追加の方法を確認したい場合は、あまりにもこのブログをチェックアウト:あなたがしているパターンを実装する上で主張すれば、https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging

UPDATE私のコメントパー

をあなたはgilmishalの答えのこの修正版を使うことができると説明しています。

public class TestController 
{ 
    private TestService service; 

    public TestController(TestService service) 
    { 
     this.service = service; 
    } 

    public ActionResult One(int param1, string param2) 
    { 
     return this.ActionWithTryCatch(() => this.service.MethodOne(param1, param2), "ViwName1"); 
    } 

    public ActionResult Two(Date param3, bool param4) 
    { 
     return this.ActionWithTryCatch(() => this.service.MethodTwo(param3, param4), "ViwName2"); 
    } 

    public IActionResult ActionWithTryCatch(Action action, string viewName) 
    { 
     try 
     { 
      action.Invoke(); 
     } 
     catch (Exception e) 
     { 
      LogException(e.Message); 
      AddModelError(e.Message); 
     } 

     return View(viewName); 
    } 
} 
+0

それは私の目的のための解決策ですが、現在のアクションからどのようにリダイレクトできるのか知っていますか?つまり、「One」にエラーがある場合、「ViwName1」にリダイレクトしたいと思います。ありがとうございます!! –

+0

あなたが描いている振る舞いは素晴らしいパターンのようには見えません。 try ... catchでコードの最上位層をラップするだけで例外を処理するのではなく、実際に試してみるべきです。エラーが起こる可能性がある特定のコードブロックをキャッチするべきです。あなたのサービスは、その戻り値はエラーがあったかどうかを示すはずです。それから、あなたが望むビューに戻り、そこにエラーメッセージを表示することができます。私はあなたがそれを使用することを主張する場合は、記述しているパターンを実装する方法の例を含めるために私の答えを更新しました。 – sam2929

+0

はい、そうです。あなたの時間と説明をありがとう;) –

0

jsでこの関数にパラメータを渡す必要がある場合、作成したこのメソッドは正しく動作しません。したがって、パラメータのないメソッドだけを呼び出すと仮定しています。

MyDelegateの代わりにFunc<IActionResult>を使用できます。

public TResult ActionWithTryCatch<TResult>(Func<TResult> del, string viewName) 
{ 
    try 
    { 
     return del.Invoke(); 
    } 
    catch (Exception e) 
    { 
     LogException(e.Message); 
     AddModelError(e.Message); 
     throw; 
    } 
} 

これはjavascriptの実装と似ていますが、未処理の例外が発生した場合には500のhttpの結果を返します。

あなたはIActionResult戻り値の型したい場合は、このようにそれを呼び出す必要があります -

ActionWithTryCatch<IActionResult>(MethodThatReturnsIActionResult, viewName); 

を、私はあなたが記述されているパターンは、アスペクト指向プログラミングの形に近いgenerics

+0

この機能を呼び出せますか?動的コードを実行するための "Func del"パラメータの送信方法はわかりません。私は別の方法でそれを見るために質問を変更しました。ありがとうございました。 –

+0

あなたの答えをありがとう! –

関連する問題