সাবডোমেনের ভিত্তিতে এটিএসপি নেট নেট এমভিসি রুট করা কি সম্ভব?


235

এএসপি.নেট এমভিসি রুটটি কি সম্ভব যা এর রুট নির্ধারণের জন্য সাবডোমেন তথ্য ব্যবহার করে? উদাহরণ স্বরূপ:

  • user1 .domain.com এক জায়গায় যায়
  • ইউজার 2 .ডোমেন.কম আর একজন যায়?

বা, আমি কি এটি উভয়ই usernameপ্যারামিটারের সাথে একই নিয়ামক / অ্যাকশনে যেতে পারি?


আমি বহু-ভাড়াটে অ্যাপ্লিকেশনগুলির জন্য একই ধরণের জিনিস বাস্তবায়ন করেছি, তবে কাস্টম রুট শ্রেণির পরিবর্তে একটি বিমূর্ত বেস কন্ট্রোলার ব্যবহার করছি। এটিতে আমার ব্লগ পোস্টটি এখানে
লুক স্যাম্পসন

6
এই পদ্ধতির বিষয়টি বিবেচনা করতে ভুলবেন না: http://blog.tonywilliams.me.uk/asp-net-mvc-2-routing-subdomains-to-areas আমি আমার অ্যাপ্লিকেশনটিতে অন্যান্য উত্তরগুলির তুলনায় বহুজাতিকতা পরিচয় করিয়ে দেওয়ার জন্য ভাল বলে মনে করেছি , কেননা এমভিসি অঞ্চলগুলি ভাড়াটে-নির্দিষ্ট নিয়ন্ত্রক এবং সংযুক্ত পদ্ধতিতে মতামত প্রবর্তনের একটি দুর্দান্ত উপায়।
ট্রবার্মফ

2
@ ট্রেবার্মফ - আমি মনে করি আপনার উত্তর হিসাবে এটি যুক্ত করা উচিত, এটিই আমার সমাধানের ভিত্তি হিসাবে আমি শেষ করেছি।
শেগলেজ

@ শেগলেজ - ধন্যবাদ এটি একটি উত্তর ছিল, কিন্তু একজন মডারেটর কারণ হিসাবে বুঝতে পারছি না বলে এটি একটি মন্তব্যে রূপান্তর করে।
trebormf

5
টনির মতো ভেঙে গেছে। এখানে আমার জন্য কাজ করেছেন এমন একটি এখানে রয়েছে: blog.tonywilliams.me.uk/…
রনি ওভারবি

উত্তর:


168

আপনি এটি একটি নতুন রুট তৈরি করে এবং এটি আপনার Global.asax- এর RegisterRoutes এ রুট সংগ্রহের সাথে যুক্ত করে করতে পারেন। নীচে কাস্টম রুটের খুব সাধারণ উদাহরণ দেওয়া হল:

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 থেকে যুক্ত করুন।
জাস্টসটিভ

4
আমি রুটটিকে সাবডোমেনআরউট বলেছি এবং এটিকে প্রথম রুট হিসাবে যুক্ত করেছি: রুটস.এড করুন (নতুন সাবডোমেনরৌট ());
জেফ হ্যান্ডলি

6
এই পদ্ধতির জন্য কি সম্ভাব্য সাব-ডোমেনগুলির একটি তালিকা হার্ড-কোডিংয়ের প্রয়োজন?
ম্যাক্সিম ভি ভি পাভলভ

2
না, আপনি "সাবডোমেন" এর মতো একটি ডেটাবেস ক্ষেত্র যুক্ত করতে পারেন যা আপনি কোনও নির্দিষ্ট ব্যবহারকারীর জন্য সাবডোমেন বা অন্য যে কোনও কিছুর জন্য প্রত্যাশা করছেন যা হবেন, তবে কেবল সাবডোমেইনে একটি অনুসন্ধান করুন।
রায়ান হেইস

1
কেউ এর ওয়েবফর্ম সংস্করণ সুপারিশ করতে পারে?
ম্যাথিউটি

52

করার সময় মান MVC5 রাউটিং বৈশিষ্ট্য ধারনকারী সাবডোমেন ক্যাপচার , নিম্নলিখিত ব্যবহার SubdomainRouteক্লাস থেকে উদ্ভূত Route

অতিরিক্তভাবে, SubdomainRouteসাবডোমেনটিকে বিকল্পভাবে ক্যোয়ারি প্যারামিটার , তৈরি sub.example.com/foo/barএবং example.com/foo/bar?subdomain=subসমতুল্য হিসাবে নির্দিষ্ট করার অনুমতি দেয় । এটি আপনাকে ডিএনএস সাবডোমেনগুলি কনফিগার করার আগে পরীক্ষার অনুমতি দেয়। ক্যোয়ারী প্যারামিটার (যখন ব্যবহৃত হবে) Url.Actionইত্যাদি দ্বারা নির্মিত নতুন লিঙ্কগুলির মাধ্যমে প্রচারিত হয় etc.

ক্যোয়ারী প্যারামিটার নেট নেট দিয়ে কনফিগার না করে বা প্রশাসক হিসাবে চালানো ছাড়াই ভিজ্যুয়াল স্টুডিও 2013 এর সাথে স্থানীয় ডিবাগিং সক্ষম করে । ডিফল্টরূপে, আইআইএস এক্সপ্রেস কেবল binds স্থানীয় হোস্টের যখন অ উঁচু; এটি 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);
    }
}

সুবিধার্থে MapSubdomainRouteআপনার RegisterRoutesপদ্ধতি থেকে নিম্নলিখিত পদ্ধতিটি কল করুন ঠিক যেমন আপনি পুরানো বলে মনে করেন 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
আমি সাবডোমেনটিকে সর্বদা রুটের মান হিসাবে উপলব্ধ করার জন্য কোডটি আপডেট করেছি। এটি সাবডোমেনে অ্যাক্সেসকে সহজতর করে।
এডওয়ার্ড ব্রে

আমি এই পছন্দ। খুব সহজ, এবং আমার প্রকল্পের জন্য যথেষ্ট বেশি।
শীঘ্রই ডেড

এটি একটি দুর্দান্ত উত্তর। রুটের বৈশিষ্ট্যগুলি নিয়ে কাজ করার কোনও উপায় আছে কি? আমি "subdomain.domain.com/portal/register" এর মতো পাথের জন্য এই কাজটি করার চেষ্টা করছি এবং বৈশিষ্ট্যগুলি ব্যবহার করা এটি আরও সহজ করে তুলবে।
নিখুঁত_ইলেমেন্ট

@ পারফেক্ট_এলিমেন্ট - কনভেনশন ভিত্তিক রুটের মতো অ্যাট্রিবিউট রুটগুলি এক্সটেনসেবল নয়। এরকম কিছু করার একমাত্র উপায় হ'ল আপনার নিজস্ব অ্যাট্রিবিউট রাউটিং সিস্টেমটি তৈরি করা।
নাইটওয়েল 888

23

এটি আমার কাজ নয়, তবে এই উত্তরে আমাকে এটি যুক্ত করতে হয়েছিল।

এই সমস্যার একটি দুর্দান্ত সমাধান এখানে। মার্টিন বালিয়াউউ এমন একটি কোড লিখেছেন যা একটি ডোমেনরউট শ্রেণি তৈরি করে যা সাধারণ রাউটিংয়ের সাথে একইভাবে ব্যবহার করা যেতে পারে।

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) "})); এটি হোমপেজেও ক্যাশে করে। এটি হ'ল উত্সাহিত রেগেক্সের কারণে। এটির সমাধানের জন্য, আপনি ডোমেনআরটেক্সগুলিতে ক্রিয়েটরেজেক্স পদ্ধতির একটি অনুলিপি তৈরি করতে পারেন, এটির নাম দিন ক্রিয়েটডোমাইনআরেজেক্স, এই লাইনের * টিটিকে +: উত্স = উত্স.রেপ্লেস ("}", @ "> ([a- zA-Z0-9: _] *)) "); এবং GetRouteData পদ্ধতিতে ডোমেন রেজেক্সের জন্য এই নতুন পদ্ধতিটি ব্যবহার করুন: ডোমেনরেজিএক্স = তৈরিডোমেনরজেজ (ডোমেন);
গর্কেম প্যাকাসি

আমি জানি না কেন আমি এই কোডটি চালাতে পারি না ... আমি কেবল SERVER NOT FOUNDত্রুটি পেয়েছি ... মানে কোডটি আমার পক্ষে কাজ করছে না ... আপনি অন্য কোনও কনফিগারেশন বা কিছু সেট করছেন ?!
ডাঃ টিজে


1
এমআইভিসি অ্যাপ্লিকেশন। ডিএনএসফিক্স কী?
হাবো

আমরা কেবল
ওয়েবকনফাইগের

4

ওয়েব এপিআই ব্যবহার করার সময় সাবডোমেন ক্যাপচার করতে , কোনও subdomainক্যোয়ারী প্যারামিটার ইনজেক্ট করার জন্য অ্যাকশন নির্বাচনকারীকে ওভাররাইড করুন । তারপরে আপনার কন্ট্রোলারের ক্রিয়ায় সাবডোমেন ক্যোয়ারী প্যারামিটারটি ব্যবহার করুন:

public string Get(string id, string subdomain)

প্রকৃত হোস্ট নামের পরিবর্তে লোকালহোস্ট ব্যবহার করার সময় আপনি হাতের মাধ্যমে ক্যোয়ারী প্যারামিটারটি নির্দিষ্ট করতে পারবেন বলে এই পদ্ধতিটি ডিবাগটিকে সুবিধাজনক করে তুলেছে ( বিশদগুলির জন্য মানক এমভিসি 5 রাউটিং উত্তরটি দেখুন)। এটি অ্যাকশন সিলেক্টরের কোড:

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()));

রুটে ডেটা ওয়েব এপিআই কন্ট্রোলারে উপস্থিত না হয়ে এবং অনুরোধটি পরীক্ষা করে নিচ্ছে এমন সমস্যা রয়েছে এমন যে কেউ আছে? নিয়ামকের অভ্যন্তরে গেটআরটডেটা কোনও মান দেখাচ্ছে না?
অ্যালান ম্যাকডোনাল্ড

3

হ্যাঁ তবে আপনাকে নিজের রুট হ্যান্ডলার তৈরি করতে হবে।

সাধারণত রুটটি ডোমেন সম্পর্কে সচেতন নয় কারণ অ্যাপ্লিকেশনটি কোনও ডোমেনে স্থাপন করা যেতে পারে এবং রুটটি কোনওভাবে বা অন্য কোনওভাবে যত্ন করে না। তবে আপনার ক্ষেত্রে আপনি নিয়ন্ত্রণকারীর ভিত্তি তৈরি করতে এবং ডোমেনটি বন্ধ করতে চান, সুতরাং আপনাকে একটি কাস্টম রুট তৈরি করতে হবে যা ডোমেন সম্পর্কে সচেতন।


3

আমি সাবডোমেন রাউটিংয়ের জন্য লাইব্রেরি তৈরি করেছি যা আপনি এই জাতীয় একটি রুট তৈরি করতে পারেন। এটি বর্তমানে একটি নেট কোর 1.1 এবং। নেট ফ্রেমওয়ার্ক 4.6.1 এর জন্য কাজ করছে তবে অদূর ভবিষ্যতে আপডেট হবে। এটি এটি কীভাবে কাজ করছে:
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) কন্ট্রোলার / হোমকন্ট্রোলার.সি

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

3) এই লিবিও আপনাকে ইউআরএল এবং ফর্মগুলি তৈরি করতে দেয়। কোড:

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

উত্পন্ন করবে <a href="http://user1.localhost:54575/Home/Index">User home</a> জেনারেট করা URL টি বর্তমান হোস্ট অবস্থান এবং স্কিমা উপর নির্ভর করবে।
এছাড়াও আপনি জন্য HTML সাহায্যকারী ব্যবহার করতে পারেন BeginFormএবং UrlHelper। আপনি যদি পছন্দ করেন তবে আপনি ট্যাগ হেল্পার্স ( FormTagHelper, AnchorTagHelper) নামে নতুন বৈশিষ্ট্যটিও ব্যবহার করতে পারেন
That এই লাইবটিতে এখনও কোনও ডকুমেন্টেশন নেই, তবে কিছু পরীক্ষা এবং নমুনা প্রকল্প রয়েছে যাতে এটি অন্বেষণে নির্দ্বিধায় হন।


2

ইন ASP.NET কোর , হোস্ট মাধ্যমে উপলব্ধ Request.Host.Host। আপনি যদি কোনও ক্যোয়ারী প্যারামিটারের মাধ্যমে হোস্টকে ওভাররাইড করার অনুমতি দিতে চান তবে প্রথমে চেক করুন Request.Query

হোস্ট ক্যোয়ারী প্যারামিটারকে নতুন রুট-ভিত্তিক ইউআরএলে প্রচার করতে, এই কোডটি app.UseMvcরুট কনফিগারেশনে যুক্ত করুন:

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);
}

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();
}

আমি আপনাকে লুক স্যাম্পসন ব্লগে যেতে বলি


1

যদি আপনি প্রতিটি ভাড়াটে ব্যক্তির জন্য বিভিন্ন ডোমেন / সাবডোমেনগুলি দিয়ে আপনার প্রকল্পে মাল্টিটেন্সি ক্ষমতা দেওয়ার দিকে তাকিয়ে থাকেন তবে আপনার সাসকিটের দিকে নজর দেওয়া উচিত:

https://github.com/saaskit/saaskit

কোড উদাহরণগুলি এখানে দেখা যাবে: http://benfoster.io/blog/saaskit-m Multi-tenancy- made-easy

কিছু ASP.NET কোর ব্যবহার উদাহরণ: http://andrewlock.net/forking-the-pipeline-adding-tenant-specific-files-with-saaskit-in-asp-net-core/

সম্পাদনা: আপনি যদি আপনার এএসপি.নেট কোর প্রকল্পে সাসকিট ব্যবহার করতে না চান তবে আপনি এমভিসি 6 এর জন্য মার্টেনের ডোমেন রাউটিংয়ের বাস্তবায়নটি একবার দেখে নিতে পারেন: https://blog.maartenballiauw.be/post/2015/02/17/domain -routing-এবং-সমাধানে বর্তমান-ভাড়াটিয়া-সঙ্গে-aspnet-MVC-6-aspnet-5.html

তবে এই গিস্টগুলি বজায় রাখা হয় না এবং এএসপি.নেট কোরের সর্বশেষতম প্রকাশের সাথে কাজ করার জন্য টুইট করা দরকার।

কোডের সরাসরি লিঙ্ক: https://gist.github.com/maartenba/77ca6f9cfef50efa96ec#file-domaintemplateroutebuilderextensions-cs


বহুজাতিকত্ব খুঁজছেন না - তবে টিপটির জন্য ধন্যবাদ!
ড্যান এস্পারজা

0

কয়েক মাস আগে আমি একটি বৈশিষ্ট্য বিকাশ করেছি যা নির্দিষ্ট ডোমেনগুলিতে পদ্ধতি বা নিয়ন্ত্রণকারীকে সীমাবদ্ধ করে।

এটি ব্যবহার করা বেশ সহজ:

[IsDomain("localhost","example.com","www.example.com","*.t1.example.com")]
[HttpGet("RestrictedByHost")]
public IActionResult Test(){}

আপনি এটিকে সরাসরি একটি নিয়ামকের উপরও প্রয়োগ করতে পারেন।

public class IsDomainAttribute : Attribute, Microsoft.AspNetCore.Mvc.Filters.IAuthorizationFilter
{

    public IsDomainAttribute(params string[]  domains)
    {
        Domains = domains;
    }

    public string[] Domains { get; }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var host = context.HttpContext.Request.Host.Host;
        if (Domains.Contains(host))
            return;
        if (Domains.Any(d => d.EndsWith("*"))
                && Domains.Any(d => host.StartsWith(d.Substring(0, d.Length - 1))))
            return;
        if (Domains.Any(d => d.StartsWith("*"))
                && Domains.Any(d => host.EndsWith(d.Substring(1))))
            return;

        context.Result = new Microsoft.AspNetCore.Mvc.NotFoundResult();//.ChallengeResult
    }
}

সীমাবদ্ধতা: আপনি বিভিন্ন ফিল্টার সহ বিভিন্ন পদ্ধতিতে দুটি একই রুট রাখতে সক্ষম নাও হতে পারেন যার অর্থ নিম্নলিখিতটি সদৃশ রুটের ব্যতিক্রম হতে পারে:

[IsDomain("test1.example.com")]
[HttpGet("/Test")]
public IActionResult Test1(){}

[IsDomain("test2.example.com")]
[HttpGet("/Test")]
public IActionResult Test2(){}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.