2008-11-10 11 views
222

क्या एएसपी.नेट एमवीसी मार्ग होना संभव है जो इसके मार्ग को निर्धारित करने के लिए सबडोमेन जानकारी का उपयोग करता है? उदाहरण के लिए:क्या सबडोमेन के आधार पर एएसपी.नेट एमवीसी मार्ग बनाना संभव है?

  • user1 .domain.com एक ही स्थान पर
  • user2 .domain.com दूसरे करने के लिए चला जाता है को जाता है?

या, क्या मैं इसे बना सकता हूं ताकि ये दोनों username पैरामीटर के साथ एक ही नियंत्रक/क्रिया पर जाएं?

+0

मैंने बहु-किरायेदार अनुप्रयोगों के लिए एक समान प्रकार की चीज लागू की, लेकिन कस्टम रूट क्लास के बजाय एक सार आधार नियंत्रक का उपयोग करना। इस पर मेरा ब्लॉग पोस्ट है [यहां] (http://lukesampson.com/post/303245177/subdomains-for-a-single-plication-with-asp-net-mvc)। –

+6

इस दृष्टिकोण पर विचार करना सुनिश्चित करें: [http://blog.tonywilliams.me.uk/asp-net-mvc-2-routing-subdomains-to-areas ](http://blog.tonywilliams.me.uk/ एएसपी-नेट-एमवीसी -2-रूटिंग-सबडोमेन-टू-एरिया) मैंने पाया कि यह मेरे ऐप में अन्य उत्तरों की तुलना में बहुतायत को पेश करने के लिए बेहतर होगा, क्योंकि एमवीसी क्षेत्र किरायेदार-विशिष्ट नियंत्रकों और विचारों को पेश करने का एक अच्छा तरीका है संगठित तरीका – trebormf

+2

@trebormf - मुझे लगता है कि आपको इसे एक उत्तर के रूप में जोड़ना चाहिए, यही वह है जो मैंने अपने समाधान के आधार के रूप में उपयोग किया। – Shagglez

उत्तर

162

आप इसे एक नया मार्ग बनाकर और अपने वैश्विक.एक्सएक्स में रजिस्टर रूट्स में मार्ग संग्रह में जोड़कर कर सकते हैं। नीचे एक कस्टम मार्ग की एक बहुत ही सरल उदाहरण है:

public class ExampleRoute : RouteBase 
{ 

    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
     var url = httpContext.Request.Headers["HOST"]; 
     var index = url.IndexOf("."); 

     if (index < 0) 
      return null; 

     var subDomain = url.Substring(0, index); 

     if (subDomain == "user1") 
     { 
      var routeData = new RouteData(this, new MvcRouteHandler()); 
      routeData.Values.Add("controller", "User1"); //Goes to the User1Controller class 
      routeData.Values.Add("action", "Index"); //Goes to the Index action on the User1Controller 

      return routeData; 
     } 

     if (subDomain == "user2") 
     { 
      var routeData = new RouteData(this, new MvcRouteHandler()); 
      routeData.Values.Add("controller", "User2"); //Goes to the User2Controller class 
      routeData.Values.Add("action", "Index"); //Goes to the Index action on the User2Controller 

      return routeData; 
     } 

     return null; 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
    { 
     //Implement your formating Url formating here 
     return null; 
    } 
} 
+1

विस्तृत नमूने के लिए धन्यवाद लेकिन मैं निष्पादित करने के तरीके का पालन नहीं कर रहा हूं Global.asax से जोड़ें। – justSteve

+4

मैंने रूट सबडोमेन रूट कहा और इसे इस तरह के पहले मार्ग के रूप में जोड़ा: मार्ग। जोड़ें (नया सबडोमेन रूट()); –

+6

क्या इस दृष्टिकोण के लिए संभावित उप-डोमेन की सूची हार्ड-कोडिंग की आवश्यकता है? –

3

हां लेकिन आपको अपना मार्ग हैंडलर बनाना होगा।

आम तौर पर मार्ग डोमेन से अवगत नहीं है क्योंकि एप्लिकेशन किसी भी डोमेन पर तैनात किया जा सकता है और मार्ग एक तरफ या किसी अन्य परवाह नहीं करेगा। लेकिन आपके मामले में आप डोमेन से नियंत्रक और कार्रवाई का आधार बनाना चाहते हैं, इसलिए आपको एक कस्टम मार्ग बनाना होगा जो डोमेन से अवगत है।

22

यह मेरा काम नहीं है, लेकिन मैं इस जवाब पर इसे जोड़ने के लिए किया था।

यहां इस समस्या का एक बड़ा समाधान है। मार्टिन बल्लियाव ने कोड लिखा जो एक डोमेन रूट क्लास बनाता है जिसका उपयोग सामान्य रूटिंग के समान ही किया जा सकता है।

http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx

नमूना उपयोग इस तरह होगा ...

routes.Add("DomainRoute", new DomainRoute( 
    "{customer}.example.com", // Domain with parameters 
    "{action}/{id}", // URL with parameters 
    new { controller = "Home", action = "Index", id = "" } // Parameter defaults 
)) 

;

+5

के लिए अनुशंसा करें इस समाधान में कोई समस्या है। मान लें, आप सबडोमेन को विभिन्न उपयोगकर्ताओं के रूप में संभालना चाहते हैं: मार्ग। जोड़ें ("एसडी", नया डोमेन रूट ("उपयोगकर्ता}। लॉक्लहोस्ट", "", नया {नियंत्रक = "होम", एक्शन = "इंडेक्सफॉर यूज़र", उपयोगकर्ता = " यू 1 "})); यह होमपेज को भी कैश करता है। यह उत्पन्न होने वाले रेगेक्स की वजह से है। इसे ठीक करने के लिए, आप DomainRoute में CreateRegex विधि की एक प्रति बना सकते हैं।सीएस, इसे CreateDomainRegex नाम दें, इस लाइन पर * को + + स्रोत = स्रोत में बदलें। बदलें ("}", @ "> ([a-zA-Z0 -9 _] *)"); और GetRouteData विधि में डोमेन regx के लिए इस नई विधि का उपयोग करें: डोमेनRegex = CreateDomainRegex (डोमेन); –

+0

मुझे नहीं पता कि मैं इस कोड को क्यों नहीं चला सकता ... मुझे बस 'सर्वर नहीं मिला' त्रुटि प्राप्त होती है ... मतलब है कि कोड मेरे लिए काम नहीं कर रहा है ... क्या आप कोई अन्य कॉन्फ़िगरेशन या कुछ सेट कर रहे हैं ?! –

+0

मैंने इस https://gist.github.com/IDisposable/77f11c6f7693f9d181bb – IDisposable

50

करने के लिए कब्जा उपडोमेन जबकि मानक MVC5 मार्ग को बनाए रखना सुविधाओं, निम्नलिखित SubdomainRoute वर्ग Route से प्राप्त का उपयोग करें।

साथ ही, SubdomainRoute उपडोमेन वैकल्पिक रूप से एक क्वेरी पैरामीटर, बनाने sub.example.com/foo/bar और example.com/foo/bar?subdomain=sub समकक्ष के रूप में निर्दिष्ट करने की अनुमति देता है। इससे आपको DNS सबडोमेन कॉन्फ़िगर किए जाने से पहले परीक्षण करने की अनुमति मिलती है। क्वेरी पैरामीटर (उपयोग में होने पर) Url.Action, आदि द्वारा उत्पन्न नए लिंक के माध्यम से प्रचारित किया जाता है।

क्वेरी पैरामीटर विजुअल स्टूडियो 2013 के साथ configure with netsh or run as Administrator के बिना स्थानीय डिबगिंग को भी सक्षम बनाता है। डिफ़ॉल्ट रूप से, आईआईएस एक्सप्रेस केवल लोकलहोस्ट तक सीमित नहीं होता है जब गैर-ऊंचा हो; यह समानार्थी होस्टनामों से sub.localtest.me जैसे बाध्य नहीं होगा।

class SubdomainRoute : Route 
{ 
    public SubdomainRoute(string url) : base(url, new MvcRouteHandler()) {} 

    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
     var routeData = base.GetRouteData(httpContext); 
     if (routeData == null) return null; // Only look at the subdomain if this route matches in the first place. 
     string subdomain = httpContext.Request.Params["subdomain"]; // A subdomain specified as a query parameter takes precedence over the hostname. 
     if (subdomain == null) { 
      string host = httpContext.Request.Headers["Host"]; 
      int index = host.IndexOf('.'); 
      if (index >= 0) 
       subdomain = host.Substring(0, index); 
     } 
     if (subdomain != null) 
      routeData.Values["subdomain"] = subdomain; 
     return routeData; 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
    { 
     object subdomainParam = requestContext.HttpContext.Request.Params["subdomain"]; 
     if (subdomainParam != null) 
      values["subdomain"] = subdomainParam; 
     return base.GetVirtualPath(requestContext, values); 
    } 
} 

सुविधा के लिए, अपने RegisterRoutes विधि से निम्नलिखित MapSubdomainRoute विधि कॉल बस के रूप में आप के सादे पुराने MapRoute:

static void MapSubdomainRoute(this RouteCollection routes, string name, string url, object defaults = null, object constraints = null) 
{ 
    routes.Add(name, new SubdomainRoute(url) { 
     Defaults = new RouteValueDictionary(defaults), 
     Constraints = new RouteValueDictionary(constraints), 
     DataTokens = new RouteValueDictionary() 
    }); 
} 

अंत में, सुविधा (उप डोमेन का उपयोग करने के लिए या तो एक सच्चे उप डोमेन या एक प्रश्न से पैरामीटर), Subdomain संपत्ति के साथ नियंत्रक बेस क्लास बनाने में मददगार है:

protected string Subdomain 
{ 
    get { return (string)Request.RequestContext.RouteData.Values["subdomain"]; } 
} 
+1

मैंने रूट मान के रूप में सबडोमेन हमेशा उपलब्ध कराने के लिए कोड अपडेट किया। यह सबडोमेन तक पहुंच को सरल बनाता है। –

+0

मुझे यह पसंद है। बहुत सरल, और मेरे प्रोजेक्ट के लिए पर्याप्त से अधिक। – SoonDead

+0

यह एक अच्छा जवाब है। क्या रूट गुणों के साथ काम करने का कोई तरीका है? मैं इस काम को "subdomain.domain.com/portal/register" जैसे पथों के लिए बनाने की कोशिश कर रहा हूं और विशेषताओं का उपयोग करके यह आसान हो जाएगा। –

4

वेब एपीआई का उपयोग करते समय सबडोमेन को कैप्चर करने के लिए, subdomain क्वेरी पैरामीटर इंजेक्ट करने के लिए एक्शन चयनकर्ता को ओवरराइड करें। फिर उप डोमेन क्वेरी पैरामीटर अपने नियंत्रकों के कामों में इस तरह का उपयोग करें: जब स्थानीय होस्ट बजाय का उपयोग कर वास्तविक होस्ट नाम की जब से तुम हाथ से क्वेरी पैरामीटर निर्दिष्ट कर सकते हैं

public string Get(string id, string subdomain) 

यह दृष्टिकोण सुविधाजनक डिबगिंग बनाता है (देखें standard MVC5 routing answer ब्योरा हेतु)।

class SubdomainActionSelector : IHttpActionSelector 
{ 
    private readonly IHttpActionSelector defaultSelector; 

    public SubdomainActionSelector(IHttpActionSelector defaultSelector) 
    { 
     this.defaultSelector = defaultSelector; 
    } 

    public ILookup<string, HttpActionDescriptor> GetActionMapping(HttpControllerDescriptor controllerDescriptor) 
    { 
     return defaultSelector.GetActionMapping(controllerDescriptor); 
    } 

    public HttpActionDescriptor SelectAction(HttpControllerContext controllerContext) 
    { 
     var routeValues = controllerContext.Request.GetRouteData().Values; 
     if (!routeValues.ContainsKey("subdomain")) { 
      string host = controllerContext.Request.Headers.Host; 
      int index = host.IndexOf('.'); 
      if (index >= 0) 
       controllerContext.Request.GetRouteData().Values.Add("subdomain", host.Substring(0, index)); 
     } 
     return defaultSelector.SelectAction(controllerContext); 
    } 
} 

WebApiConfig.Register को यह जोड़कर डिफ़ॉल्ट कार्रवाई चयनकर्ता बदलें::

config.Services.Replace(typeof(IHttpActionSelector), new SubdomainActionSelector(config.Services.GetActionSelector())); 
+0

किसी को भी ऐसे मुद्दे हैं जहां वेब डेटा एपीआई नियंत्रक पर रूट डेटा नहीं दिखता है और नियंत्रक के अंदर Request.GetRouteData का निरीक्षण नहीं कर रहा है? –

1

एक नया मार्ग हैंडलर कि मेजबान यूआरएल में पारित देखेंगे परिभाषित करने के बाद यह कार्रवाई चयनकर्ता के लिए कोड है, आप आधार नियंत्रक के विचार के साथ जा सकते हैं जो उस साइट के बारे में जागरूक है जिसके लिए इसे एक्सेस किया जा रहा है। यह इस तरह दिखता है:

public abstract class SiteController : Controller { 
    ISiteProvider _siteProvider; 

    public SiteController() { 
     _siteProvider = new SiteProvider(); 
    } 

    public SiteController(ISiteProvider siteProvider) { 
     _siteProvider = siteProvider; 
    } 

    protected override void Initialize(RequestContext requestContext) { 
     string[] host = requestContext.HttpContext.Request.Headers["Host"].Split(':'); 

     _siteProvider.Initialise(host[0]); 

     base.Initialize(requestContext); 
    } 

    protected override void OnActionExecuting(ActionExecutingContext filterContext) { 
     ViewData["Site"] = Site; 

     base.OnActionExecuting(filterContext); 
    } 

    public Site Site { 
     get { 
      return _siteProvider.GetCurrentSite(); 
     } 
    } 

} 

ISiteProvider एक सरल अंतरफलक है:

public interface ISiteProvider { 
    void Initialise(string host); 
    Site GetCurrentSite(); 
} 

मैं तुम्हें Luke Sampson Blog

1

करने के लिए जाने का उल्लेख आप विभिन्न डोमेन वाले अपने प्रोजेक्ट में MultiTenancy क्षमताओं दे रही है पर देख रहे हैं/प्रत्येक किरायेदार के लिए सबडोमेन, आपको सासकिट पर एक नज़र रखना चाहिए:

https://github.com/saaskit/saaskit

कोड उदाहरण यहाँ देखा जा सकता: http://andrewlock.net/forking-the-pipeline-adding-tenant-specific-files-with-saaskit-in-asp-net-core/

संपादित करें: आप अपने ASP.NET कोर परियोजना में SaasKit उपयोग करने के लिए कोई चाहते हैं, तो आप कर सकते हैं http://benfoster.io/blog/saaskit-multi-tenancy-made-easy

कुछ ASP.NET कोर का उपयोग उदाहरण MVC6 के लिए डोमेन रूटिंग की मार्टेन के कार्यान्वयन पर एक नज़र: https://blog.maartenballiauw.be/post/2015/02/17/domain-routing-and-resolving-current-tenant-with-aspnet-mvc-6-aspnet-5.html

हालांकि उन gists बनाए रखा और की जरूरत नहीं कर रहे हैं ASP.NET कोर की नवीनतम रिलीज के साथ काम करने बदलाव किया जाना है। कोड को

सीधा लिंक: https://gist.github.com/maartenba/77ca6f9cfef50efa96ec#file-domaintemplateroutebuilderextensions-cs

+0

बहुतायत की तलाश नहीं है - लेकिन टिप के लिए धन्यवाद! –

2

में ASP.NET कोर, मेजबान Request.Host.Host के माध्यम से उपलब्ध है। यदि आप किसी क्वेरी पैरामीटर के माध्यम से होस्ट को ओवरराइड करने की अनुमति देना चाहते हैं, तो पहले Request.Query देखें।

routes.Routes.Add(new HostPropagationRouter(routes.DefaultHandler)); 

और HostPropagationRouter इस तरह परिभाषित:

/// <summary> 
/// A router that propagates the request's "host" query parameter to the response. 
/// </summary> 
class HostPropagationRouter : IRouter 
{ 
    readonly IRouter router; 

    public HostPropagationRouter(IRouter router) 
    { 
     this.router = router; 
    } 

    public VirtualPathData GetVirtualPath(VirtualPathContext context) 
    { 
     if (context.HttpContext.Request.Query.TryGetValue("host", out var host)) 
      context.Values["host"] = host; 
     return router.GetVirtualPath(context); 
    } 

    public Task RouteAsync(RouteContext context) => router.RouteAsync(context); 
} 
2

मैं

एक मेजबान क्वेरी पैरामीटर, नया मार्ग आधारित URL पर आने वाले में प्रचार app.UseMvc मार्ग विन्यास के लिए इस कोड को जोड़ने के लिए पैदा करने के लिए library for subdomain routing बनाया जो आप इस तरह के एक मार्ग बना सकते हैं। यह वर्तमान में .NET कोर 1.1 और .NET Framework 4.6.1 के लिए काम कर रहा है लेकिन निकट भविष्य में अपडेट किया जाएगा। Startup.cs में
1) मानचित्र उपडोमेन मार्ग

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    var hostnames = new[] { "localhost:54575" }; 

    app.UseMvc(routes => 
    { 
     routes.MapSubdomainRoute(
      hostnames, 
      "SubdomainRoute", 
      "{username}", 
      "{controller}/{action}", 
      new { controller = "Home", action = "Index" }); 
    )}; 

2) नियंत्रकों/HomeController.cs

public IActionResult Index(string username) 
{ 
    //code 
} 

3) यही कारण है कि lib भी आप URL बनाने के लिए अनुमति देगा: यह है कि यह कैसे काम कर रहा है और रूपों। कोड:

@Html.ActionLink("User home", "Index", "Home" new { username = "user1" }, null) 

तैयार करेगा <a href="http://user1.localhost:54575/Home/Index">User home</a> उत्पन्न यूआरएल भी वर्तमान मेजबान स्थान और स्कीमा पर निर्भर करेगा।
आप BeginForm और UrlHelper के लिए HTML मददगार का भी उपयोग कर सकते हैं। यदि आप चाहें तो टैग टैगर्स नामक नई सुविधा का भी उपयोग कर सकते हैं (FormTagHelper, AnchorTagHelper)
उस lib में अभी तक कोई दस्तावेज नहीं है, लेकिन कुछ परीक्षण और नमूने प्रोजेक्ट हैं, इसलिए इसे अन्वेषण करने में संकोच न करें।

संबंधित मुद्दे