Одно веб-приложение MVC с несколькими URL-адресами, перенаправляемое на разные контроллеры [replicate]

Перечисление возможностей, разрешенных грамматикой:

>>> seq[:]                # [seq[0],   seq[1],          ..., seq[-1]    ]
>>> seq[low:]             # [seq[low], seq[low+1],      ..., seq[-1]    ]
>>> seq[:high]            # [seq[0],   seq[1],          ..., seq[high-1]]
>>> seq[low:high]         # [seq[low], seq[low+1],      ..., seq[high-1]]
>>> seq[::stride]         # [seq[0],   seq[stride],     ..., seq[-1]    ]
>>> seq[low::stride]      # [seq[low], seq[low+stride], ..., seq[-1]    ]
>>> seq[:high:stride]     # [seq[0],   seq[stride],     ..., seq[high-1]]
>>> seq[low:high:stride]  # [seq[low], seq[low+stride], ..., seq[high-1]]

Конечно, если (high-low)%stride != 0, то конечная точка будет немного ниже high-1.

Если stride отрицательно, порядок изменяется немного, так как мы отсчитываем:

>>> seq[::-stride]        # [seq[-1],   seq[-1-stride],   ..., seq[0]    ]
>>> seq[high::-stride]    # [seq[high], seq[high-stride], ..., seq[0]    ]
>>> seq[:low:-stride]     # [seq[-1],   seq[-1-stride],   ..., seq[low+1]]
>>> seq[high:low:-stride] # [seq[high], seq[high-stride], ..., seq[low+1]]

Расширенные нарезки (с запятыми и эллипсами) в основном используются только специальными структурами данных (например, Numpy) ; основные последовательности не поддерживают их.

>>> class slicee:
...     def __getitem__(self, item):
...         return `item`
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
227
задан tereško 13 July 2012 в 07:47
поделиться

8 ответов

Вы можете сделать это, создав новый маршрут и добавив его в коллекцию маршрутов в RegisterRoutes в своем global.asax. Ниже приведен очень простой пример пользовательского маршрута:

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;
    }
}
166
ответ дан Jon Cahill 27 August 2018 в 05:10
поделиться

После определения нового обработчика маршрута, который будет смотреть на хост, переданный в URL , вы можете пойти с идеей базового контроллера, который знает о том, к какому узлу он обращается. Это выглядит так:

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
ответ дан Amirhossein Mehrvarzi 27 August 2018 в 05:10
поделиться

Чтобы захватить субдомен при использовании веб-API, переопределите селектор действий, чтобы ввести параметр запроса subdomain. Затем используйте параметры запроса поддомена в действиях ваших контроллеров следующим образом:

public string Get(string id, string subdomain)

Этот подход делает отладку удобной, поскольку вы можете указать параметр запроса вручную при использовании localhost вместо фактическое имя хоста (подробности см. в стандартном ответе маршрутизации MVC5 ). Это код для Action Selector:

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()));
51
ответ дан Community 27 August 2018 в 05:10
поделиться

Если вы ищете возможности MultiTenancy для вашего проекта с разными доменами / поддоменами для каждого арендатора, вы должны посмотреть на SaasKit:

https://github.com/saaskit / saaskit

Примеры кода можно увидеть здесь: http://benfoster.io/blog/saaskit-multi-tenancy-made-easy

Некоторые примеры с использованием ядра ASP.NET: http://andrewlock.net/forking-the-pipeline-adding-tenant-specific-files-with-saaskit-in-asp-net-core/

EDIT: Если вы не хотите использовать SaasKit в своем основном проекте ASP.NET, вы можете взглянуть на реализацию Мартинской маршрутизации домена для MVC6: https: //blog.maartenballiauw

Однако эти Gists не поддерживаются и должны быть настроены для работы с последней версией ядра ASP.NET.

Прямая ссылка на код: https://gist.github.com/maartenba/77ca6f9cfef50efa96ec# файл-domaintemplaterout ebuilderextensions-CS

1
ответ дан Darxtar 27 August 2018 в 05:10
поделиться

В ядре ASP.NET хост доступен через Request.Host.Host. Если вы хотите разрешить переопределение хоста через параметр запроса, сначала проверьте Request.Query.

Чтобы заставить параметр запроса узла распространяться на новые URL-адреса на основе маршрутов, добавьте этот код в 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);
}
2
ответ дан Edward Brey 27 August 2018 в 05:10
поделиться

Это не моя работа, но я должен был добавить ее в этот ответ.

Вот отличное решение этой проблемы. Maartin Balliauw написал код, который создает класс DomainRoute, который можно использовать очень похоже на обычную маршрутизацию.

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

;

22
ответ дан Jim Blake 27 August 2018 в 05:10
поделиться

Я создал библиотеку для маршрутизации поддоменов , которую вы можете создать таким маршрутом. Он работает в настоящее время для .NET Core 1.1 и .NET Framework 4.6.1, но будет обновлен в ближайшем будущем. Вот как это работает: 1) Маршрут субдомена карты в Startup.cs

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> Сгенерированный URL-адрес также будет зависеть от текущего местоположения хоста и схемы. Вы также можете использовать html-помощники для BeginForm и UrlHelper. Если вам нравится, вы также можете использовать новую функцию, называемую помощниками тегов (FormTagHelper, AnchorTagHelper). У lib еще нет документации, но есть некоторые тесты и примеры проектов, поэтому не стесняйтесь исследовать их.

3
ответ дан Mariusz 27 August 2018 в 05:10
поделиться

Да, но вы должны создать свой собственный обработчик маршрута.

Как правило, маршрут не знает о домене, потому что приложение может быть развернуто в любом домене, и маршрут не будет волновать так или иначе. Но в вашем случае вы хотите установить контроллер и действие из домена, поэтому вам нужно будет создать настраиваемый маршрут, который будет знать о домене.

3
ответ дан Nick Berardi 27 August 2018 в 05:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: