Чистая маршрутизация ASP.NET к классу, а не к странице aspx - PullRequest
0 голосов
/ 08 января 2012

Мне нужно выполнить маршрутизацию в существующем приложении asp.net, а не в asp.net mvc (да, я знаю, что должен конвертировать, но, скажем, сейчас это невозможно, поэтому не говорите мне :)) - как я могу выполнить маршрутизацию к обычному классу вместо страницы aspx, поскольку весь пример кода, который я вижу, всегда со страницей aspx, как здесь:

http://msdn.microsoft.com/en-us/magazine/dd347546.aspx

Точнее, я хочу сделать что-то похожее на маршрутизацию MVC Controller: контроллер, например, product - это чистый класс, доступ к которому вы получаете через http://domain.com/product

Ответы [ 3 ]

5 голосов
/ 08 января 2012

ASP.NET MVC и ASP.NET Web Forms используют одну и ту же инфраструктуру маршрутизации, в которой обеим фреймворкам в конечном итоге потребуется IHttpHandler для обработки HTTP-запроса:

Интерфейс IHttpHandler является частью ASP.NET с начало, а веб-форма (System.Web.UI.Page) является IHttpHandler.

(из статьи в MSDN, указанной в вопросе)

В ASP.NET MVC используется класс System.Web.Mvc.MvcHandler, , который затем делегируется контроллеру для дальнейшей обработки запроса. В веб-формах ASP.NET обычно используется класс System.Web.UI.Page, представляющий файл .aspx, но также может использоваться pure IHttpHandler, связанный с файлом .ashx.

Таким образом, вы можете направить обработчик .ashx в качестве альтернативы странице веб-форм .aspx. Оба реализуют IHttpHandler (как и MvcHandler), но с первым это все, что он делает. И это как можно ближе к «чистому классу», обрабатывающему (маршрутизируемый) запрос. А поскольку часть обработчика является просто интерфейсом, вы можете наследовать от своего собственного класса.

<%@ WebHandler Language="C#" Class="LightweightHandler" %>

using System.Web;

public class LightweightHandler : YourBaseClass, IHttpHandler
{
  public void ProcessRequest(HttpContext context)
  {
    context.Response.ContentType = "text/plain";
    context.Response.Write("Hello world!");
  }

  public bool IsReusable { get { return false; } }
}

Обратите внимание, что IRouteHandler просто нужно вернуть экземпляр IHttpHandler:

public IHttpHandler GetHttpHandler(RequestContext requestContext);

Возможно, вам придется перепрыгнуть через несколько обручей, чтобы создать экземпляр вашего обработчика, используя BuildManager *, если вы используете файлы .ashx. Если нет, вы можете просто создать экземпляр своего класса и вернуть его:

public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
  // In case of an .ashx file, otherwise just new up an instance of a class here
  IHttpHandler handler = 
    BuildManager.CreateInstanceFromVirtualPath(path, typeof(IHttpHandler)) as IHttpHandler;

  // Cast to your base class in order to make it work for you
  YourBaseClass instance = handler as YourBaseClass;
  instance.Setting = 42;
  instance.DoWork();

  // But return it as an IHttpHandler still, as it needs to do ProcessRequest
  return handler;
}

См. Ответы на этот вопрос для более глубокого анализа маршрутизации чистых IHttpHandlers: Можно ли использовать маршрутизацию ASP.NET для создания «чистых» URL-адресов для обработчиков .ashx (IHttpHander)?

** Я не совсем уверен в примере BuildManager, кто-то, пожалуйста, поправьте меня, если я ошибся в этой части *

2 голосов
/ 08 января 2012

Если вы можете обновить с 3.5 до 4.0, WebForms лучше поддерживает маршрутизацию. В Global.asax вам нужно делать только такие вещи:

void Application_Start(object sender, EventArgs e) 
{
    RouteTable.Routes.MapPageRoute("default", string.Empty, "~/default.aspx");       
}

Я не совсем понимаю, что такое "чистый класс", но, надеюсь, если обновление до версии 4.0 - вариант, это может помочь вам.

2 голосов
/ 08 января 2012

Если вы не можете переключиться на ASP.NET MVC и маршрутизация обработчиков .ashx не соответствует вашим требованиям, вы можете обратиться к Nancy, легкому веб-фреймворку 1002 *.

Вот пример из введения (см. Ссылку в предыдущем абзаце):

public class Module : NancyModule
{
  public Module() : base("/foo")
  {
    Get["/"] = parameters => {
      return "This is the site route";
    };

    Delete["/product/{id}"] = parameters => {
      return string.Concat("You requested that the following product should be deleted: ", parameters.id);
    };
  }
}

Этот класс будет обрабатывать запросы к / foo и / foo / product / 42.Вы также можете использовать представления с этой средой для более сложного (HTML) ответа.

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