2013-07-02 5 views
12

MVCで作業を開始したばかりですが、疑問があります。MVCの公開NonActionメソッドの目的

Nonactionメソッドの代わりに、コントローラにプライベートメソッドを作成することも、モデル内にメソッドを書き込んでコントローラから呼び出すこともできます。

したがって、MVCで公開NonActionメソッドを使用する実際の目的は何ですか?

+0

あなたが何を探しているのかわかりません - 何らかの理由で公開する必要があるが、そのような方法では表示しない方法がある場合...またはあなたの質問は「人々が公開方法を使用する理由」です。 –

+1

@AlexeiLevenkov:はい、私の質問は、人々がパブリックノンアクションメソッドを使用する理由です。彼らはプライベートメソッドを使用することもできます。 – ChandniShah

答えて

6

私は、属性だけ良く柔軟性のためにここだと思います(私はより良いアドレスにコメントで質問を答えを再構築しました)。フレームワーク設計者として、エンドユーザからの符号化制約を可能な限り緩和したい。パブリックな非行動を持たないという要件は「一般的に」良いと思うかもしれませんが、一部のプロジェクトでは制限が厳しいかもしれません。[NonAction]を追加すると、(悪い設計でも導入された)問題が解決されます。もちろん、この属性を使用する必要はありません。したがって、フレームワークデザイナの観点からは勝利です。

もう1つの理由は、以前のMVCバージョンでは、[Action]とマークされているメソッドは、アクションとみなされます。したがって、彼らが要件を緩和したとき(そしてすべてのパブリックメソッドがアクションとして扱われるようになったとき)、開発者はあまり混乱しないように[NonAction]を保持しました。 NonActionを使用して一般的に


は、悪い習慣です - 正確にあなたが述べた理由のために。何かが行動であってはならない場合、最初は publicであってはなりません。コントローラ上の公共の非アクションメソッドを持つ

問題は、彼らは人々があなたのコントローラをインスタンス化し、メソッドを呼び出して、代わりに一般的なロジックを分離するのに誘惑作ることです:

はと

public class MyController : IController 
{ 
    public ActionResult Foo(long orderId) 
    { 
     var order = new OrdersController().GetOrder(orderId); //GetOrder is public 
     ... 
    } 
} 

を比較します

public class MyController : IController 
{ 
    public ActionResult Foo(long orderId) 
    { 
     var order = _orderService.GetOrder(orderId); 
     ... 
    } 
} 

第1のアプローチでは、コントローラと直感的ではないコード間の結合が増加します。コードは、リファクタリングするのが難しくなり、模擬/テストするのが面倒になります。

公開アクション以外の方法は、通常の操作として扱われ、外部から呼び出すことができるため、セキュリティホールです([NonAction]とマークするのを忘れた場合、または一般公開から変更することを忘れた場合)。私はオリジナルの質問は、必然的に属性を付けることを絶対に忘れないことを意味していることを意味していますが、もしあなたが望むなら何が起こるかを理解することもちょっと重要です;)そうですね、 「属性を忘れること」は、「方法を非公開にすることを忘れる」ことに比べて、理論的には可能性が高い。


は時々、人々は何かが、それは最も可能性の高い別のクラスに分離することができ、別々にテストアクションではありませんときpublic非作用を有することは、再びユニットテストのために必要であるが、と言います。 internalInternalsVisibleToを使用して推奨される方法です - また、さえそれはテスト目的のための方法publicマーキング、何らかの理由で実行可能ではない場合にのみは悪い癖があります。

+0

機能呼び出しのようなアクションメソッドの中間操作で使用できるので、非アクションメソッドではなく非公開を推奨します。今、彼らはそのコントローラの外で呼び出すことはできません。これまでのところ非常に良い。質問 - 私はなぜ 'Non-Action'メソッドを使うべきですか?あなたはそれの使用の重要性を教えていただけますか? –

+0

_ "なぜ[[NonAction]を使用するのですか?" "_ - あなたはそれを使う必要はありません。 ASP.NET MVCを作成した人々は、設計の間違いのあるプロジェクトでもフレームワークを利用できるようにしたいので、属性が存在するということです。 – andreister

+0

okありがとうございます。しかし、 'Non Action'メソッドを使用している間、それらの悪い習慣は含まれていますか? –

1

このような状況は、そのメソッドの単体テストを実行する必要があるなどのいくつかのテストフレームワークの要件によって引き起こされる可能性がありますが、悪い設計ですが変更することはできません。

デフォルトでは、MVCフレームワークは、コントローラクラスのすべてのパブリックメソッドをアクションメソッドとして扱います。コントローラクラスにパブリックメソッドが含まれていて、アクションメソッドにしたくない場合は、そのメソッドをNonActionAttribute属性でマークする必要があります。

真の目的は、与えられた制御方法がアクションでないMVCフレームワークを通知する非アクションメソッドへのアクセスを制限するために公共NonAction

を使用します。

URLにNonAction属性のメソッドを実行しようとすると、要求に対する応答としてエラー404が表示されます。

参考:詳細についてはhttp://msdn.microsoft.com/en-us/library/dd410269%28v=vs.90%29.aspx

http://weblogs.asp.net/gunnarpeipman/archive/2011/04/09/asp-net-mvc-using-nonactionattribute-to-restrict-access-to-public-methods-of-controller.aspx

+1

NonActionAttributeの使い方を知っています。私の本当の疑問は、Nonactionメソッドを使用する本当の理由は何かです。 – ChandniShah

+0

@ ChandniShah、URL上で 'NonAction'属性を持つメソッドを実行しようとすると、リクエストに対する応答としてエラー404が発生します。 – Satpal

+0

しかし、非公開のメソッドの代わりに私はプライベートメソッドを使うこともできます。その場合にも私はエラーが発生します。なぜ私はpuble非アクションメソッドを使用する必要がありますか? – ChandniShah

0

URLは大文字と小文字を区別していないときにこれが有益です。あなたが要求ホーム/についてを持っている場合、例えば、これはアクションだけでなく、ホーム/についてについてにHomeControllerに行くようにすることは、同じコントローラと同じアクションメソッドに起こっています。

public class HomeController:Controller 
{ 
.... 
    public ViewResult About() 
    { 
     return View(); 
    } 

    public ViewResult aBOut() 
    { 
     return View(); 
    } 
} 

枠組み以下

等が呼び出すためにどのabout関数を決定し、呼が曖昧であることを告げる例外をスローすることができません。もちろん

enter image description here

この問題を解決する一つの方法は、アクション名を変更することです。

何らかの理由でアクション名を変更したくない場合、これらの関数の1つがアクションでない場合、この非アクションメソッドをNonAction属性で飾ることができます。例:

[NonAction] 
public ActionResult aBOut() 
{ 
    return View(); 
} 
0

カスタムASPパイプラインでバインディングドライバとしてコントローラを使用していますが、各ドライバは結果ページの1つのセクション(部分表示)のレンダリングを担当します。セクションでは、(例えば、現在のセクションが編集可能な場合または単に読み取り専用)現在のユーザの許可を解決するためのページや他の上でご注文解決する

[NonAction] 
publi int GetOrder() 

:その後、我々のようなパブリックメソッドを使用しています。

コントローラについては、要求を処理する方法としてだけでなく、レンダリングページ用のカスタムフレームワークを構築するためのツールとして考える必要はありません。このようにして、私たちはコントローラの責任を常に1つのタスクに任せ、ドメインの懸念を分けています。

0

デフォルトでは、MVCフレームワークは、コントローラクラスのすべてのパブリックメソッドをアクションメソッドとして扱います。コントローラクラスにパブリックメソッドが含まれていて、アクションメソッドにしたくない場合は、そのメソッドにNonActionAttribute属性を設定する必要があります。

+0

コントローラでNon Actionを使用する利点は何ですか? –

+0

長時間実行され、非CPUにバインドされた要求に対しては、非アクションメソッドを使用できます。これにより、要求の処理中にWebサーバーが作業を実行できないようにすることができます。 – Duk

0

ASP.NETは高度にカスタマイズ可能です。 MVC HTTPハンドラをオーバーライドすることによって、フレームワークのデフォルトの動作を変更するとします。おそらく、使用されているコントローラに応じてロギングロジックをカスタマイズする必要があります。一部のコントローラでは、IControllerLogger GetLogger()メソッドを使用してILoggingControllerインターフェイスを実装しています。このメソッドでは、非アクションのパブリックメソッドを記述する必要があります。

関連する問題