代码之家  ›  专栏  ›  技术社区  ›  Joseph

有没有办法在中添加默认视图和默认控制器ASP.NETMVC 2?

  •  3
  • Joseph  · 技术社区  · 14 年前

    我真正想做的是重新定义约定,做到以下几点:

    对于控制器及其各自的操作:

    如果发出了一个URL请求,并且没有一个具有提供的操作的控制器,那么执行一些“default”函数,我将在应用程序中提供这些函数。我认为这可以通过使用Func<>来实现,但我不确定在何处插入此功能。

    对于视图:

    如果控制器的操作正在请求视图,并且没有与控制器的操作正在请求的视图匹配的视图,则返回此“默认”视图。

    编辑

    这是我想要达到的目标的一个例子。

    我有一个非常简单的观点,类似于:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
    
    Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
    
    <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
        <%: Html.LabelForModel() %>
    </asp:Content>
    
    <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    
        <%: Html.EditorForModel() %>
    
    </asp:Content>
    

    假设我有一个Customer类,控制器动作对Customer对象做了一些事情,然后

    return View(someCustomer);
    

    4 回复  |  直到 14 年前
        1
  •  1
  •   Clicktricity    14 年前

    首先,创建一个带有“Default”操作的“DefaultController”。

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        try
        {
            return base.GetControllerInstance(requestContext, controllerType);
        }
    
        catch (HttpException ex)
        {
            int httpCode = ex.GetHttpCode();
            if(httpCode == (int)HttpStatusCode.NotFound)
            {
                IController controller = new DefaultController();
                ((DefaultController)controller).DefaultAction();
                return controller;
            }
            else
            {
                throw ex;
            }
        }
    }
    

    然后在全球.asax启动。

    要捕获调用现有控制器但操作不存在时的情况,请重写HandleUnknownAction方法,最好是在基类中:

    public class BaseController : Controller
    {
        protected override void HandleUnknownAction(string actionName)
        {
            RouteData.Values["action"] = "DefaultAction";
    
            if ( this.ActionInvoker.InvokeAction(this.ControllerContext, "DefaultAction"))
                   return;
    
            base.HandleUnknownAction(actionName);
        }
    }
    

    public class MyWebFormViewEngine : WebFormViewEngine
    {
        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            ViewEngineResult result = null;
    
            result = base.FindView(controllerContext, viewName, masterName, useCache);
    
            if (result == null || result.View == null)
               result = base.FindView(controllerContext, "Default", masterName, useCache);
    
            return result;
        }
    }
    

    把这个登记在你的邮箱里全球.asax:

    protected void Application_Start()
    {
        ViewEngines.Engines.Clear();
        ViewEngines.Engines.Add(new MyWebFormViewEngine());
    
        RegisterRoutes(RouteTable.Routes);
    // etc
    }
    

        2
  •  2
  •   Robert Koritnik    14 年前

    为什么不用路由解决控制器/动作问题?

    routes.MapRoute(
        "Root",
        "",
        new { controller = "Home", action = "Index" }
    );
    
    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional },
        // constraints for certain controllers (add actions if needed as well)
        new { controller = "Home|ControllerOne|ControllerTwo|..."}
    );
    
    // catch any request route and handle by the same controller/action
    routes.MapRoute(
        "NonExisting",
        "{path*}",
        new { controller = "Default", action = "Any" }
    );
    

    关于视图

    如果您的控制器总是被捕获,那么您不必担心视图。因此,如果您的最后一个路由解析为任何内容并始终显示相同的内容,则控制器永远不会请求不存在的视图。

    编辑关于视图(基于您的评论)

    如果我理解你评论中的观点,你就必须创建一个单独的视图引擎,它可以通过提供一个指向精确的aspx文件的额外视图路径来解决所有问题。

    Views/{0}/{1}.aspx . 然后可以添加一行,如 Views/General/Default.aspx

        3
  •  0
  •   Buildstarted    14 年前

    你可以这样做。我不确定捕获所有404(包括图像和其他内容文件)是否会产生任何性能影响或任何其他问题

    protected void Application_Error(object sender, EventArgs e) {
        HttpException httpException = Server.GetLastError() as HttpException;
        if (httpException != null) {
            switch (httpException.GetHttpCode()) {
                case 404:
                    //we couldn't find the controller or action
    
                    //setup a new route to your default controller assigned
                    //to handle unknown routes
                    RouteData routeData = new RouteData();
                    routeData.Values.Add("controller", "YourDefault");
    
                    //create an instance of your controller and execute it
                    IController yourDefaultController = new YourDefaultController();
                    yourDefaultController.Execute(new RequestContext(
                            new HttpContextWrapper(Context), routeData));
                    break;
            }
        }
    
    }
    
        4
  •  0
  •   Charlino    14 年前

    我想您可能想创建一个自定义控制器工厂。我自己没有做过,但这应该是一个简单的谷歌(touchwood)。

    意见

    HTHs公司,
    查尔斯