Есть ли способ добавить представление по умолчанию и контроллер по умолчанию в ASP.NET MVC 2? - PullRequest
3 голосов
/ 29 сентября 2010

Что я действительно хотел бы сделать, так это переопределить условные обозначения для выполнения следующих действий:

Для контроллеров и их соответствующих действий:

Если сделан запрос URL, ине является контроллером с предоставленным действием, тогда выполняйте некоторую функцию «по умолчанию», которую я поставил бы себе в приложении.Я думаю, что это может быть достигнуто с помощью 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);

Проблема здесь в том, что я не определил ни одного View для обработки Customer.В этом случае я хочу, чтобы мой движок представлений (или кто-то другой отвечает за это) сказал: «Хорошо, нет представления, напрямую связанного с клиентами, вместо этого я буду использовать представление по умолчанию».

Ответы [ 4 ]

2 голосов
/ 30 сентября 2010

Почему бы не решить проблему с контроллером / действием при маршрутизации?

Маршрутизация может иметь ограничения, верно? Так почему бы не решить проблему с несуществующим контроллером / действием, использующим это?

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, которая бы сработала. Когда он будет искать конкретное представление, оно будет соответствовать одному, если оно существует, но если оно не будет, оно милостиво упадет к представлению по умолчанию.

1 голос
/ 30 сентября 2010

Вы запрашиваете несколько различных компонентов.

Сначала создайте «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;
        }
    }
}

Затем зарегистрируйте фабрику этого контроллера при запуске Global.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;
    }
}

и зарегистрируйте это в своем Global.asax:

protected void Application_Start()
{
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new MyWebFormViewEngine());

    RegisterRoutes(RouteTable.Routes);
// etc
}

Надеюсь, это поможет ...

0 голосов
/ 29 сентября 2010

Контроллеры и действия

Думаю, вы захотите создать собственную фабрику контроллеров. Я сам этого не делал, но это должен быть простой гугл (дрова).

Просмотры

Вы должны изучить создание собственного движка представления (или просто расширить движок представления по умолчанию), чтобы искать разные файлы по умолчанию.

HTHS,
Charles

0 голосов
/ 29 сентября 2010

Вы могли бы сделать это так.Я не уверен в каких-либо последствиях для производительности или любых других проблемах, которые могут возникнуть при захвате всех 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;
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...