rksoftware

Visual Studio とか C# とかが好きです

ASP.NET MVC にコントローラーを追加する

■ コントローラークラスの基本

ASP.NET MVC のコントローラークラスは Controller クラスの派生クラスとして実装します。例えば次のように

public class HomeController : System.Web.Mvc.Controller
{
    public ActionResult Index()
    {
        return new ContentResult() { Content = "HomeController" };
    }
}

■ ルート設定の基本

前述の手順でコントローラークラスを作りましたが、コントローラークラスさえあれば、Webサイトのコントローラーとしてリクエストに応答できるわけではありません。
ルート設定が必要です。
設定を行うのは Webアプリケーションプロジェクトの App_Start フォルダの RouteConfig クラスに書かれている

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

の部分です。このコードはデフォルトのテンプレートで生まれるコードですが、要点だけ見てみましょう。

  • url: の {controller}
    クライアントからアクセスされた URL のパスの最初の部分と名前の一致する読み込まれているコントローラークラスを探します。

  • url: の {action}
    クライアントからアクセスされた URL のパスの二つ目の部分と名前の一致するメソッドを持つ読み込まれているコントローラークラスを探します。

  • url: の {id}
    defaults: の部分で id は UrlParameter.Optional と設定されているので省略可能です。今回は省略して扱うので考慮不要です。

まとめると http://localhost:xxxx/Home/Index にアクセスすると、Home クラスの Index メソッドを探します。見つかったメソッドをコントローラーとして呼び出します。

■ コントローラーの追加(普通に)

クライアントからアクセスされた URL に一致するコントローラーを探すということは、コントローラークラスを追加するとアプリケーションが受け付ける URL が増えるということです。
例えば、Wepアプリケーションプロジェクトに次のクラスを追加します。

public class MyController : System.Web.Mvc.Controller
{
    public ActionResult Index()
    {
        return new ContentResult() { Content = "MyController" };
    }
}

すると、Webアプリケーションが http://localhost:xxxx/My/Index を受け付けるようになります。

■ コントローラーの追加(DLL)

ASP.NET MVC プロジェクトはビルドすると DLL を出力します。この DLL をしかるべき場所に配置すると IIS が読み込んでくれ、Webアプリのバイナリとして扱われます。
この IIS への配置ですが、Webアプリケーションプロジェクトでない DLL を追加で配置しても読み込んでくれるようです。

例えば

  • WebApplication1 という Web アプリケーションプロジェクトを作成し配置する。
  • ClassLibraryLoad クラスライブラリプロジェクトを作成し次のクラスを作成する。
public class LoadController : Controller
{
    public ActionResult Index()
    {
        return new ContentResult() { Content = "LoadController" };
    }
}
  • ビルドして生成された ClassLibraryLoad.dllWebApplication1.dll を同じ場所にコピーする。

とすると、LoadController コントローラーが http://localhost:xxxx/Load/Index で動作するようになりました。
WebApplication1.dll バイナリを変更することなく Webアプリケーションが受け付ける URL を増やすことができるようです。

■ 循環参照する DLL でコントローラーを追加

通常は、プロジェクト(DLL)間は循環参照することはできません。例えば Visual Studio 上で

  • WebApplication1 Webアプリケーションプロジェクトに次のクラスを作成する。
public static class Dummy
{
    public static string Text { get; } = " + _dummy_";
}
  • WebApplication1 を参照する ClassLibraryLoad クラスライブラリプロジェクトを作成し次のクラスを作成する。
  • ClassLibraryLoad の機能を Webアプリケーションに組み込みたいと思い、WebApplication1 から ClassLibraryLoad を参照しようとする。

とすると、エラーになり参照を設定できません。
f:id:rksoftware:20180922133540j:plain

ここで、前述の コントローラーの追加(DLL)を思い出すと、前述の手順では参照関係のない DLL をフォルダーに置くだけで動作していました。
つまり、WebApplication1 から ClassLibraryLoad を参照は必要なさそうです。
というわけで、

  • 参照設定はせずに ClassLibraryLoad クラスライブラリプリジェクトにコントローラークラスを追加します。
public class LoadController : Controller
{
    public ActionResult Index()
    {
        return new ContentResult() { Content = "LoadController" + WebApplication1.Models.Dummy.Text };
    }
}
  • ビルドされた ClassLibraryLoad.dll をWebアプリケーションの bin フォルダーに配置します。
  • http://localhost:xxxx/Load/Index にアクセスすると次のように表示されました。
    f:id:rksoftware:20180922133623j:plain

WebApplication1.dll のバイナリを変更することなく WebApplication1 にあるクラスを使用する LoadController コントローラーを追加することができました。