Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVC 2.0、StructureMap、区域和重复的控制器名称_C#_Asp.net Mvc 2_Structuremap_Asp.net Mvc Areas - Fatal编程技术网

C# MVC 2.0、StructureMap、区域和重复的控制器名称

C# MVC 2.0、StructureMap、区域和重复的控制器名称,c#,asp.net-mvc-2,structuremap,asp.net-mvc-areas,C#,Asp.net Mvc 2,Structuremap,Asp.net Mvc Areas,我有点问题。我有一个区域叫框架。这个区域有一个家庭控制器。该站点的默认设置还具有主控制器 我想用它来做的是,每个控制器/动作都有一个适合IFrame的版本,以及一个普通站点的版本。我是通过母版页来实现这一点的,网站母版页有许多不同于框架版的内容占位符。出于这个原因,我不能只交换母版页。例如,将显示一个非常基本的版本,其中只包含您的帐户信息,以便在外部站点中使用。将显示相同的数据,但在默认站点内 我的IoC容器是structuremap。所以,我找到了。这是我目前的设置 结构映射初始化 Objec

我有点问题。我有一个区域叫框架。这个区域有一个家庭控制器。该站点的默认设置还具有主控制器

我想用它来做的是,每个控制器/动作都有一个适合IFrame的版本,以及一个普通站点的版本。我是通过母版页来实现这一点的,网站母版页有许多不同于框架版的内容占位符。出于这个原因,我不能只交换母版页。例如,将显示一个非常基本的版本,其中只包含您的帐户信息,以便在外部站点中使用。将显示相同的数据,但在默认站点内

我的IoC容器是structuremap。所以,我找到了。这是我目前的设置

结构映射初始化

ObjectFactory.Initialize(x =>
            {
                x.AddRegistry(new ApplicationRegistry());
                x.Scan(s =>
                {
                    s.AssembliesFromPath(HttpRuntime.BinDirectory);
                    s.AddAllTypesOf<IController>()
                        .NameBy(type => type.Namespace + "." + type.Name.Replace("Controller", ""));
                });
            });
区域路线

context.MapRoute(
                "Framed_default",
                "Framed/{controller}/{action}/{id}",
                new { area = "Framed", controller = "Home", action = "Index", id = UrlParameter.Optional },
                new string[] { "MySite.Areas.Framed.Controllers" }
            );
按照的建议,我使用名称空间作为第四个参数

应用程序启动,只是为了证明初始化的顺序

protected void Application_Start()
        {
            InitializeControllerFactory();

            AreaRegistration.RegisterAllAreas();

            RouteConfiguration.RegisterRoutes();
        }
控制器厂

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            IController result = null;
            if (controllerType != null)
            {
                result = ObjectFactory.GetInstance(controllerType)
                    as IController;
            }
            return result;
        }
因此,当我点击/Home/Index时,它会传入正确的控制器类型。当我点击/Framed/Home/Index时,controllerType为null,这是一个错误,因为没有返回任何控制器


就好像MVC完全忽略了我的领域。这是怎么回事?我做错了什么?

如果有人试图做类似的事情,我使用了这篇文章中的想法:我必须完全转储使用区域,自己实现一些东西

我有Controllers/HomeController.cs和Controllers/Framed/HomeController.cs

我有一个类ControllerBase,/controllers中的所有控制器都从中继承。我有一个从ControllerBase继承的AreaController,其中/controllers/Framed中的所有控制器都从中扩展

这是我的区域控制器课程

public class AreaController : ControllerBase
    {
        private string Area
        {
            get
            {
                return this.GetType().Namespace.Replace("MySite.Controllers.", "");
            }
        }
        protected override ViewResult View(string viewName, string masterName, object model)
        {
            string controller = this.ControllerContext.RequestContext.RouteData.Values["controller"].ToString();

            if (String.IsNullOrEmpty(viewName))
                viewName = this.ControllerContext.RequestContext.RouteData.Values["action"].ToString();

            return base.View(String.Format("~/Views/{0}/{1}/{2}.aspx", Area, controller, viewName), masterName, model);
        }

        protected override PartialViewResult PartialView(string viewName, object model)
        {
            string controller = this.ControllerContext.RequestContext.RouteData.Values["controller"].ToString();

            if (String.IsNullOrEmpty(viewName))
                viewName = this.ControllerContext.RequestContext.RouteData.Values["action"].ToString();

            PartialViewResult result = null;

            result = base.PartialView(String.Format("~/Views/{0}/{1}/{2}.aspx", Area, controller, viewName), model);

            if (result != null)
                return result;

            result = base.PartialView(String.Format("~/Views/{0}/{1}/{2}.ascx", Area, controller, viewName), model);

            if (result != null)
                return result;

            result = base.PartialView(viewName, model);

            return result;
        }
    }
我必须重写view和partialview方法。这样,我的“区域”中的控制器可以使用视图和分区的默认方法,并支持添加的文件夹结构

至于视图,我有Views/Home/Index.aspx和Views/Framed/Home/Index.aspx。我使用的路线如帖子所示,但以下是我的路线以供参考:

var testNamespace = new RouteValueDictionary();
            testNamespace.Add("namespaces", new HashSet<string>(new string[] 
            { 
                "MySite.Controllers.Framed"
            }));

            //for some reason we need to delare the empty version to support /framed when it does not have a controller or action
            routes.Add("FramedEmpty", new Route("Framed", new MvcRouteHandler())
            {
                Defaults = new RouteValueDictionary(new
                {
                    controller = "Home",
                    action = "Index",
                    id = UrlParameter.Optional
                }),
                DataTokens = testNamespace
            });

            routes.Add("FramedDefault", new Route("Framed/{controller}/{action}/{id}", new MvcRouteHandler())
            {
                Defaults = new RouteValueDictionary(new
                {
                    //controller = "Home",
                    action = "Index",
                    id = UrlParameter.Optional
                }),
                DataTokens = testNamespace
            });

var defaultNamespace = new RouteValueDictionary();
            defaultNamespace.Add("namespaces", new HashSet<string>(new string[] 
            { 
                "MySite.Controllers"
            }));

routes.Add("Default", new Route("{controller}/{action}/{id}", new MvcRouteHandler())
                {
                    Defaults = new RouteValueDictionary(new
                    {
                        controller = "Home",
                        action = "Index",
                        id = UrlParameter.Optional
                    }),
                    DataTokens = defaultNamespace
                });
var testNamespace=newRouteValueDictionary();
添加(“名称空间”,新哈希集(新字符串[])
{ 
“MySite.Controllers.Framed”
}));
//由于某些原因,当没有控制器或操作时,我们需要删除空版本以支持/构建它
添加(“FramedEmpty”,新路由(“Framed”,新MvcRouteHandler())
{
默认值=新建RouteValueDictionary(新建
{
controller=“Home”,
action=“Index”,
id=UrlParameter。可选
}),
DataTokens=testNamespace
});
Add(“FramedDefault”,新路由(“Framed/{controller}/{action}/{id}”,新MvcRouteHandler())
{
默认值=新建RouteValueDictionary(新建
{
//controller=“Home”,
action=“Index”,
id=UrlParameter。可选
}),
DataTokens=testNamespace
});
var defaultNamespace=new RouteValueDictionary();
添加(“名称空间”,新哈希集(新字符串[])
{ 
“MySite.Controllers”
}));
Add(“默认”,新路由(“{controller}/{action}/{id}”,新MvcRouteHandler())
{
默认值=新建RouteValueDictionary(新建
{
controller=“Home”,
action=“Index”,
id=UrlParameter。可选
}),
DataTokens=defaultNamespace
});

现在我可以在同一个站点上转到/Home/Index或/Framed/Home/Index,并使用共享控件获得两个不同的视图。理想情况下,我希望一个控制器返回两个视图中的一个,但我不知道如果没有两个控制器,该如何工作。

我在使用带区域的Structuremap时遇到类似问题。我有一个名为Admin的区域,每当您尝试转到/Admin时,它都会以空控制器类型进入StructureMap控制器工厂

我通过以下博客帖子修复了它:

如果控制器是admin,则必须在默认路由上添加一个不匹配的约束

以下是我的默认路线定义:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "MyController", action = "AnAction", id = UrlParameter.Optional },
    new { controller = new NotEqualConstraint("Admin")},
    new string[] {"DailyDealsHQ.WebUI.Controllers"} 
);
下面是NotEqualConstraint的实现:

public class NotEqualConstraint : IRouteConstraint
{
    private string match = String.Empty;

    public NotEqualConstraint(string match)
    {
        this.match = match;
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        return String.Compare(values[parameterName].ToString(), match, true) != 0;
    }
}
可能还有其他方法可以解决这个问题,但这为我解决了:)

public class NotEqualConstraint : IRouteConstraint
{
    private string match = String.Empty;

    public NotEqualConstraint(string match)
    {
        this.match = match;
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        return String.Compare(values[parameterName].ToString(), match, true) != 0;
    }
}