ASP.NET Core MVCの[コントローラ]と[NonController]

3099 ワード

Controller VS NonControllerに組み込まれた規則


ASP.NET Core MVCではMVCとWeb ApiとWeb Pagesが統一されており、同じControllerを有し、RC 2以降のバージョンではASP.NET Core MVCはPOCO Controllerをサポートしているので、Web ApiのControllerを作るときにControllerベースクラスから継承する必要はありません.
POCO Controllerはpublicであり、抽象的ではなく、継承もなく、インタフェースも実現しないControllerクラスであり、POCO Classに類似しており、Controllerで終わるだけである.
ここまで来ると、POCO ControllerでHTTPコンテキストを取得したいものはどうすればいいのかと聞かれるかもしれません.うん....これは確かに問題です...どうしようかな?ベースクラスControllerを正直に継承しましょう.VnextのPOCO Controller属性注入がキャンセルされたからです.
POCO Controllerを作成した場合、彼らの名前はControllerで終わる必要があります.そうしないと、MVCはあなたがControllerオブジェクトだとは思いません.Routeのようなマークを持っていてもだめです.
したがって、MVC Controllerを作成するには、次の2つの前提条件があります.
  • --Controllerベースクラス
  • から継承
  • --またはControllerで終わる名前
  • を使用します.
    次の例は、2つのControllerを作成するWeb Api Controllerの例です.
    [Route("api/[controller]")]public class FooController : Controller{
        [HttpGet]    public string Get()    {        return "foo";
        }
    }
     
    [Route("api/[controller]")]public class BarController{
        [HttpGet]    public string Get()    {        return "bar";
        }
    }

    最初にControllerベースクラスを継承した以上、Controllerを定義するときにController接尾辞を付けるのは余計ではないかと聞かれるかもしれません.このように書いてもいいですか.
    [Route("api/[controller]")]public class Foo : Controller{
        [HttpGet]    public string Get()    {        return "foo";
        }
    }

    はい、これも正しいです.どうしてですか.これは,継承されたベースクラスControllerがController Attributeのタグを付けられているためであり,このタグを付けた後,スキャンを構築する際にはControllerとみなされ,すなわち継承ツリー全体が有効なMVC Controllerとされているためである.
    では、ある同級生がまた聞いたが、これでいいのだろうか.
    [Route("api/[controller]")]public class Bar{
        [HttpGet]    public string Get()    {        return "bar";
        }
    }

    これはPOCOコントローラなので、MVCフレームワークに有効なコントローラだと思わせるタグはありません.このとき、フレームワークに有効なコントローラだと思わせたい場合は、Controller Attributeの方程式を追加することで、
    [Controller]
    [Route("api/[controller]")]public class Bar{
        [HttpGet]    public string Get()    {        return "bar";
        }
    }

    この時、MVCフレームワークはこれが有効なControllerだと思っています.
    同様に、ベースクラスにControllerAttributeタグがあるため、このようなコードも有効です.
    [Controller]public class ApiBase {}
     
    [Route("api/[controller]")]public class Bar : ApiBase{
        [HttpGet]    public string Get()    {        return "bar";
        }
    }

    もう1つの可能性は、クラスがある場合、それはちょうどControllerで終わりますが、実際にはControllerクラスではありません.どうすればいいのでしょうか.この場合、現在のクラスがMVCのControllerクラスではないことを宣言するNonController Attributeタグを追加する必要があります.これにより、構築時にフレームワークが間違っていることを避けることができます.
    [NonController]public class DemoController{    //   action   }

    注意すべき点は、Controller AttributeタグはController Attributeタグよりも優先度が高いため、1つのControllerが同時に2つのタグを持つ場合、NonController Attributeを基準とします.
    実際には、Controller継承ツリー全体に1つのControllerがNonController Attributeとマークされている場合、継承ツリー全体のControllerは無効なControllerとみなされます.