3

私は新しい MVC 5 プロジェクトに取り組んでいます。これは、多くの組織や支社がページを維持できる単一のマルチ テナント サイトです。すべてのページは、次の URL 形式で始まります。

http://mysite.com/{organisation}/{branch}/...

例えば:

http://mysite.com/contours/albany/...   
http://mysite.com/contours/birkenhead/...   
http://mysite.com/lifestyle/auckland/...   

{organisation}andの{branch}前に{controller}andを付けて RouteConfig を宣言しました{action}

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

これはうまく機能しています。ただし、すべての単一のコントローラーの上部に、organisationおよびを調べる同一のコードが含まれるようになりbranchました。

public ActionResult Index(string organisation, string branch, string name, int id)
{
    // ensure the organisation and branch are valid
    var branchInst = _branchRepository.GetBranchByUrlPath(organisation, branch);
    if (branchInst == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    // start the real code here...
}

私は DRY 原則 (Don't Repeat Yourself) に熱心であり、何らかの方法でその共通コードを分離し、コントローラーの署名を次のように変更できるかどうか疑問に思っています。

public ActionResult Index(Branch branch, string name, int id)
{
    // start the real code here...
}
4

3 に答える 3

1

ユーザー ID とトークンが POST 経由ですべてのコントローラー アクションに渡されるアプリケーションで、同様のことを行う必要がありました (非常に古いレガシー認証を行っていたため)。

BaseController を宣言し、各コントローラーにその基本コントローラーを継承させました。したがって、ベースを継承する各コントローラーは、標準の uid およびトークン プロパティ (必要な場合) へのアクセス権を既に持っており、これらのプロパティは、各アクションの開始時に HTTP コンテキストから既に取得されています。

public abstract class BaseController : Controller
    {
        #region Properties

        protected string uid;
        protected string token;

        #endregion

        #region Event overloads

        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {    
            try
            {
                uid = requestContext.HttpContext.Request["uid"];
                token = requestContext.HttpContext.Request["token"];

                if (uid != null && token != null)
                {
                    ViewBag.uid = uid;

                    if (!token.Contains("%"))
                        ViewBag.token = requestContext.HttpContext.Server.UrlEncode(token);
                    else
                        ViewBag.token = token;

                    base.Initialize(requestContext);
                }
                else
                {
                    requestContext.HttpContext.Response.Redirect(ConfigurationManager.AppSettings.GetValues("rsLocation")[0]);
                }
            }
            // User ID is not in the query string
            catch (Exception ex)
            {
                requestContext.HttpContext.Response.Redirect(ConfigurationManager.AppSettings.GetValues("redirectLocation")[0]);
            }
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

        #endregion
    }

これで、「実際の」コントローラーでベースコントローラーを継承できます。

public class TestController : BaseController
    {
        #region Controller actions

        //
        // GET: /Index/     

        [Authorize]
        public ViewResult Index()
        {
             //blah blah blah
        }
     }

あなたの場合、uid とトークンの代わりに組織とブランチを探しますが、それは同じ考えです。

于 2013-10-08T19:19:26.573 に答える