2016-12-30 1 views
0

ASP.NET MVCを使用してマルチテナントアプリケーションを構築しています。今、バグに気づいたが、完全にランダムな間隔で、間違ったテナントからのデータが別のテナントのために取り出されることがある。MVCマルチテナントが他のテナントデータをロードする

だから例えば、Tenant1はログインするが、彼らはTenant2からの情報を参照してください。私はすべてのテナントからTenantIdと同じデータベースを使用しています。

下記のように私はグローバル> Application_AcquireRequestStateからアプリケーションを起動する:

namespace MultiTenantV1 
{ 
    public class Global : HttpApplication 
    { 
     public static OrganizationGlobal Tenant; 

     void Application_Start(object sender, EventArgs e) 
     { 
      ViewEngines.Engines.Clear(); 
      ViewEngines.Engines.Add(new RazorViewEngine()); 

      AreaRegistration.RegisterAllAreas(); 
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
      BundleConfig.RegisterBundles(BundleTable.Bundles); 
      UnityWebActivator.Start(); 
     } 

     void Application_AcquireRequestState(object sender, EventArgs e) 
     { 
      // boot application 
      HttpApplication app = (HttpApplication)sender; 
      HttpContext context = app.Context; 

      // dependency runner 
      Tenant = new Tenant().Fetch(context.Request.Url); 

      // third party api calls 
      var session = HttpContext.Current.Session; 
      if (session != null) 
      { 
       if (string.IsNullOrEmpty(Session["CountryCode"] as string)) 
       { 
        string isDevelopmentMode = ConfigurationManager.AppSettings["developmentmode"]; 
        if (isDevelopmentMode == "false") 
        { 
         // api call to get country 
        } 
        else 
        { 
         // defaults 
        } 
       } 

       Tenant.CountryCode = Session["CountryCode"].ToString(); 
      } 
     } 
    } 
} 

今、私は出発点として、「テナント」オブジェクトを使用し、さらにデータのためのデータベースを照会するためにこれを使用するアプリケーション全体で。テナントが別のテナント名を見ていることがあります(他のデータも同じように見えるかどうかはわかりません)。

私はHttpContext.Request.Urlに基づいて「テナント」を初期化しています。したがって、他のテナントデータをロードする方法はありません。

誰もが任意の特定の要求のために抽出され、間違ったテナントが生じる可能性が上記のコードで、またはHttpContext.Request.Urlの私の使用中に何を見ることができますか?

答えて

1

各リクエストは静的テナントオブジェクトをオーバーライドするため、同時リクエストでは間違ったテナントが使用されます。

キーはHttpContext.Current、例えば、要求あたりのテナントを格納することです。私は、URLに基​​づいてCurrentIdを設定Application_AcquireRequestState

public string CurrentId { 
     get { 
      return (string)HttpContext.Current.Items["CurrentTenantId"]; 
     } 
     set { 
      string val = value != null ? value.ToLower() : null; 
      if (!HttpContext.Current.Items.Contains("CurrentTenantId")) { 
       HttpContext.Current.Items.Add("CurrentTenantId", val); 
      } else { 
       HttpContext.Current.Items["CurrentTenantId"] = val; 
      } 
     } 
    } 

:私は通常、このようなコードが含まれているテナントのリゾルバを使用します。

tenancyresolverは、その後CurrentIdを取得することにより、テナントを知っておく必要がありますクラスで使用されています。

+1

"この鍵は、リクエストごとにテナントを保存することです"これは問題を解決するのに十分なヒントです。ありがとう@jeroen K –

+0

@jeroen Kは、コントローラでアクセスできるようにCurrentIdプロパティを配置しますか? – Picflight

+0

@Picflight私はコントローラで使用するTenancyResolver(CurrentIdプロパティを持つ)というクラスを持っています。これはDIフレームワーク(simpleinjector)を介して注入され、要求ごとにシングルトンとして登録されます。 –

関連する問題