MVC 2.0,StructureMap,面积和重复控制器名称 [英] MVC 2.0, StructureMap, Areas, and Duplicate Controller Names

查看:146
本文介绍了MVC 2.0,StructureMap,面积和重复控制器名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有点问题。我有一个叫做帧的区域。这个地区有一个家居控制器。该网站的默认也有一个家居控制器。

I have a bit of a problem. I have an area called Framed. This area has a home controller. The default for the site also has a home controller.

我试图用这个做的是有一个版本,每个控制器/操作是适合的IFrame,以及一个版本是正常的网站。我这样做是通过母版页和网站母版有很多不同的内容占位比镜框版本。出于这个原因,我不能只是换母版页和缩小。例如, http://example.com/Framed/Account/Index 将呈现一个非常基础的版本在外部网站使用的只是你的帐户信息。 http://example.com/Account/Index 将显示相同的数据,但是默认的站点内。

What I'm trying to do with this is have a version of each controller/action that is suitable for an IFrame, and a version that is the normal site. I do this through Master pages, and the site masterpage has many different content place holders than the framed version. For this reason I can't just swap the master page in and out. For example, http://example.com/Framed/Account/Index will show a very basic version with just your account info for use in an external site. http://example.com/Account/Index will show the same data, but inside the default site.

我的IoC容器是structuremap。于是,我找到的http://odeto$c$c.com/Blogs/scott/archive/2009/10/19/mvc-2-areas-and-containers.aspx和<一个href=\"http://odeto$c$c.com/Blogs/scott/archive/2009/10/13/asp-net-mvc2-$p$pview-2-areas-and-routes.aspx\" rel=\"nofollow\">http://odeto$c$c.com/Blogs/scott/archive/2009/10/13/asp-net-mvc2-$p$pview-2-areas-and-routes.aspx.下面是我的当前设置。

My IoC container is structuremap. So, I found http://odetocode.com/Blogs/scott/archive/2009/10/19/mvc-2-areas-and-containers.aspx and http://odetocode.com/Blogs/scott/archive/2009/10/13/asp-net-mvc2-preview-2-areas-and-routes.aspx. Here's my current setup.

Structuremap初始化

Structuremap Init

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

在这里,我通过调试中发现的问题是,由于控制器具有相同的名称(HomeController中),它只注册了第一个,这是默认的主控制器。我的创意和附加的命名空间,以便将登记所有我的控制器。

The problem here that I found through debugging is that because the controllers have the same name (HomeController), it only registers the first one, which is the default home controller. I got creative and appended the namespace so that it would register all of my controllers.

默认路由

routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
                new[] { "MySite.Controllers" }
                );

区域航线

context.MapRoute(
                "Framed_default",
                "Framed/{controller}/{action}/{id}",
                new { area = "Framed", controller = "Home", action = "Index", id = UrlParameter.Optional },
                new string[] { "MySite.Areas.Framed.Controllers" }
            );

由于建议菲尔哈克,我使用命名空间作为第四个参数

As recommended by Phil Haack, I am using the namespaces as the 4th parameter

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

app start, just to prove the order of initialization

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

所以,当我打/首页/指数,它通过在正确的控制器类型。当我打/帧/首页/指数,controllerType是空的,因为返回哪些错误没有控制器。

So, when I hit /Home/Index, it passes in the correct controller type. When I hit /Framed/Home/Index, controllerType is null, which errors because no controller is returned.

这是因为如果MVC是完全无视我的领域。这里发生了什么?我在做什么错了?

It's as if MVC is ignoring my area altogether. What's going on here? What am I doing wrong?

推荐答案

在情况下,任何人试图做同样的事情,我使用这个职位的想法:<一href=\"http://stackoverflow.com/questions/43201/categories-of-controllers-in-mvc-routing-duplicate-controller-names-in-separat\">http://stackoverflow.com/questions/43201/categories-of-controllers-in-mvc-routing-duplicate-controller-names-in-separat我干脆用地区倾倒和实施自己的东西。

In case anyone tries to do something similar, I used the idea from this post: http://stackoverflow.com/questions/43201/categories-of-controllers-in-mvc-routing-duplicate-controller-names-in-separat I had to dump using areas altogether and implement something myself.

我控制器/ HomeController.cs和控制器/帧/ HomeController.cs

I have Controllers/HomeController.cs and Controllers/Framed/HomeController.cs

我有一个类ControllerBase这在/控制器的所有控制器继承。我有AreaController从ControllerBase继承这在所有的控制器/控制器/帧的扩展。

I have a class ControllerBase which all controllers in /Controllers inherit from. I have AreaController which inherits from ControllerBase which all controllers in /Controllers/Framed extend from.

下面是我区控制器类

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

我不得不重写视图和partialview方法。这样一来,在我的区的控制器,可以使用视图和谐音的默认方法,并支持添加的文件夹结构。

I had to override the view and partialview methods. This way, the controllers in my "area" can use the default methods for views and partials and support the added folder structures.

至于意见,我查看/主页/的Index.aspx和视图/帧/主页/的Index.aspx。我使用了路由如图所示的职位,但这里是我的样子,以供参考:

As for the Views, I have Views/Home/Index.aspx and Views/Framed/Home/Index.aspx. I use the routing as shown in the post, but here's how mine looks for reference:

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

现在我可以去同一个站点/主页/索引或/帧/首页/指数,并得到了共享控制两种不同的意见。理想情况下,我想一个控制器来回报2次,但我不知道如何使这项工作,而2个控制器。

Now I can go /Home/Index or /Framed/Home/Index on the same site and get two different views with a shared control. Ideally I'd like one controller to return one of 2 views, but I have no idea how to make that work without 2 controllers.

这篇关于MVC 2.0,StructureMap,面积和重复控制器名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆