0

我在我的 Web 服务器上运行一个带有两个自定义模块的 Orchard CMS 实例,ModuleFirst并且ModuleSecond. 出于某种原因,我希望这两个网站充当具有自己的域和主页的独立网站。我无法设置其他网站或使用 Orchard 的内置租户功能。

我有的

我实现这一目标的方法如下:

  • 在 IIS 中向我的网站添加了两个绑定:first-domain.comsecond-domain.com
  • 实现了一个 ThemeSelector(我认为它就像一个 ActionFilter),它根据传入请求中 Url 的主机切换主题

    if (host.Contains("second-domain.com"))
    {
        useSecondTheme = true;
    }
    
  • 确保所有路线都是唯一的

这在大多数情况下运作良好。我可以导航到first-domain.com/foo并且second-domain.com/bar看起来我在不同的网站上。

问题

对于这两个“主页”,我无法制作独特的路线,因为我不想添加任何后缀。这两个项目都定义了一条空白路线,应该通向它们各自的主页/索引,但我不知道如何使它工作。

new RouteDescriptor {
    Priority = 90,
    Route = new Route(
        "",
        new RouteValueDictionary { // Defaults
            {"area", "ModuleFirst"},
            {"controller", "Home"},
            {"action", "Index"},
        },
        new RouteValueDictionary(), // Constraints
        new RouteValueDictionary { // Datatokens
            {"area", "ModuleFirst"}
        },
        new MvcRouteHandler())
}

new RouteDescriptor {
    Priority = 100,
    Route = new Route(
        "",
        new RouteValueDictionary { // Defaults
            {"area", "ModuleSecond"},
            {"controller", "Home"},
            {"action", "Index"},
        },
        new RouteValueDictionary(), // Constraints
        new RouteValueDictionary { // Datatokens
            {"area", "ModuleSecond"}
        },
        new MvcRouteHandler())
}

我试过的

我尝试实现一个 ActionFilter,ModuleFirst/Home/Index当带有主机 url 的请求first-domain.com到达时重定向到,ModuleSecond/Home/Index但这显然不起作用,因为它只是一遍又一遍地击中最高优先级的路由并破坏网站。

我还尝试在具有最高优先级的路由上实现自定义 RouteConstraint 以阻止所有不是来自其预期域的传入请求,假设这些请求随后会退回到较低优先级的路由。

public class SecondConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        return httpContext.Request.Url.DnsSafeHost.Contains("second-domain.com");
    }
}

使用如下:

new RouteDescriptor {
    Priority = 100,
    Route = new Route(
        "",
        new RouteValueDictionary { // Defaults
            {"area", "ModuleSecond"},
            {"controller", "Home"},
            {"action", "Index"},
        },
        new RouteValueDictionary { // Constraints
            {"isSecond", new SecondConstraint()}
        }, 
        new RouteValueDictionary { // Datatokens
            {"area", "ModuleSecond"}
        },
        new MvcRouteHandler())
}

我现在可以导航到second-domain.com很好并获得正确的页面,但导航到first-domain.com超时。不过,我还没有设法在 Orchard 中找到任何 RouteConstraints 示例,所以也许我做错了。

4

1 回答 1

0

尽管我会建议任何打算从头开始做这样的事情的人尽可能使用租户和 OAuth,正如 Bertrand 在他的评论中所建议的那样,我想到了一种相当干净的方法来完成我想要的事情。

我只使用一个,而不是使用两个单独的模块。

在我的一个模块中,我实现IRouteProvider了覆盖默认路由,该路由同时捕获first-domain.com/second-domain.com/

public class Routes : IRouteProvider
{
    public void GetRoutes(ICollection<RouteDescriptor> routes)
    {
        foreach (var routeDescriptor in GetRoutes())
            routes.Add(routeDescriptor);
    }

    public IEnumerable<RouteDescriptor> GetRoutes()
    {
        return new[] {
            new RouteDescriptor {
                Priority = 100,
                Route = new Route(
                    "",
                    new RouteValueDictionary {
                        {"area", "MyModule"},
                        {"controller", "Home"},
                        {"action", "Index"},
                    },
                    new RouteValueDictionary(),
                    new RouteValueDictionary {
                        {"area", "MyModule"}
                    },
                    new MvcRouteHandler())
            }
        };
    }
}

然后我创建了一个只有一个属性的自定义部件bool IsHomepage并将其附加到页面类型

public class SecondHomepagePart : ContentPart<SecondHomepagePartRecord>
{
    public bool IsHomepage
    {
        get { return Retrieve(r => r.IsHomepage); }
        set { Store(r => r.IsHomepage, value); }
    }
}

在驱动程序中,我确保只有一个“第二个主页”

protected override DriverResult Editor(SecondHomepagePart part, IUpdateModel updater, dynamic shapeHelper)
{
        if (updater.TryUpdateModel(part, Prefix, null, null))
        {
            if (part.IsHomepage)
            {
                var otherHomepages = _orchardServices.ContentManager.Query<SecondHomepagePart>().Where<SecondHomepagePartRecord>(r => r.IsHomepage && r.Id != part.Id).List();

                foreach (var homepagePart in otherHomepages)
                {
                    homepagePart.IsHomepage = false;
                }
            }
        }

        return Editor(part, shapeHelper);
}

然后在我的自定义中,HomeController我只检查当前域,获取带有空白的 ContentItemAutoroutePart或根据域设置为 true 的SecondHomepagePart位置IsHomepage,构建该项目的详细形状,然后在我的自定义Index.cshtml视图中显示该形状。

控制器:

public ActionResult Index()
{
        var host = HttpContext.Request.Url.DnsSafeHost;

        var model = new IndexViewModel();
        IContent homepageItem;

        if (host.Contains("first-domain.com"))
        {
            homepageItem = _homeAliasService.GetHomePage();
        }
        else
        {
            homepageItem = _orchardServices.ContentManager.Query<SecondHomepagePart>()
                .Where<SecondHomepagePartRecord>(r => r.IsHomepage)
                .List()
                .FirstOrDefault();
        }

        model.Homepage = _orchardServices.ContentManager.BuildDisplay(homepageItem, "Detail");

        return View(model);
}

看法:

@model MyModule.ViewModels.Home.IndexViewModel

@if (Model.Homepage != null)
{
    @Display(Model.Homepage)
}

我使用相同的签入IConditionProviderIThemeSelector为每个域设置层规则并自动设置适当的主题。现在我基本上有两个与外界完全不同的网站,但具有共享的内容、小部件、部件、自定义设置等。对于从相同库存但在不同品牌下销售相同产品的客户来说,这是一个快速简便的解决方案。不同的条件,以及一些对两者都不同的独家内容。

于 2017-07-05T12:20:53.803 回答