Статьи

jQuery для Asp.net MVC предварительного просмотра 3

Итак, у меня наконец-то появилась возможность сесть и закончить предварительный просмотр jQuery для Asp.net Mvc 3. Если вы еще не читали статью Скотта о предварительном просмотре 3 , вам обязательно следует сделать это перед прочтением этого.

Итак, в предварительном просмотре 3 кое-что изменилось, и я решил многое изменить в jQuery для Asp.net mvc ( jqmvc ). Начнем с самого радикального: я бросил ajax.master. Этот маленький «фреймворк» отныне не зависит от специальной мастер-страницы на вашем сайте. Поскольку все радикально изменилось, я начну все сначала, как использовать этот проект.

В этом посте я объясню, как проект работает в глобальном масштабе. Я не буду вдаваться в подробности обо всем, но я просто объясню, что вы непосредственно коснетесь в своем приложении. В следующем посте я объясню, как использовать проект на вашем веб-сайте (до этого времени вы могли взглянуть на прилагаемый образец веб-сайта). Этот пост объяснит Ajax- и HtmlHelpers в этом проекте, а также объяснит, как выполнить ajax-запрос с использованием jQuery.

Прежде чем моя история начнется, давайте начнем со ссылок и загрузок для всех тех, кто хочет читать код, а не истории:

Применение и маршруты

Чтобы быстро приступить к работе с приложением, рекомендуется наследовать его от JqueryMvc.JqueryMvcApplication. Вы можете легко сделать это в вашем global.asax следующим образом:

<%@ Application Inherits="JqueryMvc.JqueryMvcApplication" Language="C#" %>

Это приложение устанавливает контейнер зависимостей Unity и устанавливает маршруты по умолчанию. Если вы хотите установить другой (или нет) контейнер зависимостей, вы должны переопределить InitializeContainer () и ConfigureContainer (). Сам JQueryMvc больше не зависит от контейнера зависимостей. Мне было трудно настроить маршруты по умолчанию в предпросмотре 3, если ваш сервер не поддерживает перенаправления с подстановочными знаками (как это делает веб-сервер Visual Studio). В этом случае вам нужно перехватить существующие файлы (default.aspx должен существовать, но ничего не должен делать), но вам нужно пропустить папку Content. Я придумал следующее решение:

virtual public void RequestRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//if you live on a server that doesn't need the
//default.aspx... you can delete the default.aspx,
//and routing will be skipped for existing files...
if (System.IO.File.Exists(this.Server.MapPath("~/default.aspx")))
{
routes.IgnoreRoute("{*rest}", new { rest = "^Content\\/.*" });
routes.RouteExistingFiles = true;
routes.MapRoute(
"Default.aspx",
"default.aspx",
new
{
controller = "Home",
action = "Index",
id = ""
}
};
routes.MapRoute(
"Default",
"{controller}.aspx/{action}/{id}",
new {
controller = "Home",
action = "Index",
id = "" },
new { controller = "[^\\.]*", action = "[^\\.]*" }
};
}
else
{
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" },
new { controller = "[^\\.]*", action = "[^\\.]*" }
);
}
}

Так что если в корневом каталоге вашего приложения есть default.aspx, то для routeExistingFiles будет установлено значение true. Если URL соответствует RegEx ^ Content \ /.*, маршрутизация будет остановлена ​​с использованием нового метода IgnoreRoute. Кроме того, ваши контроллеры будут расширены с помощью .aspx, чтобы убедиться, что запросы проходят цикл asp.net. Если у вас есть возможность перехватывать все входящие запросы, все, что вам нужно сделать, это удалить файл default.aspx из корня вашего веб-сайта.

Контроллеры

Как вы видели в посте Скотта, контроллеры теперь должны возвращать ActionResult. Обычным способом было бы, чтобы действие вашего контроллера возвращало результат метода View (). С jqmvc вы не должны вызывать метод View () в конце вашего действия. Конечно, если вы уверены, что хотите вернуть нормальный вид, вы все равно можете это сделать. В jqmvcесть ExtController, от которого вы должны наследовать свои контроллеры. Этот базовый класс содержит метод Action (), который принимает те же атрибуты, что и View (), но при этом решает, какой тип запроса является текущим запросом, и попытается вернуть правильный ActionResult для этого типа запроса. Это может быть либо Ajax-запрос, Json-запрос, либо обычный page-запрос. Ваш типичный контроллер с некоторыми действиями будет выглядеть так:

public class HomeController : ExtController
{
public ActionResult Index()
{
return Action();
}

public ActionResult SayHello(string name)
{
ViewData["Messages"] = new List<string.();
if (name == "Britney")
throw new Exception("Go away!");
else if (name == "Luke")
((IList)ViewData["Messages"]).Add("May the force be with you!");

if (!string.IsNullOrEmpty(name))
ViewData["HelloWorld"] = "Hi " + name + "!";

return Action();
}

public ActionResult About()
{
return Action();
}
}

Просмотры

Если jqmvc встретил текущий запрос как обычный запрос страницы, он создаст ViewResult по умолчанию, ничего особенного там нет.

Если jqmvc решил, что Json должен быть возвращен, создается JsonResult и дальнейшие действия не предпринимаются. Представленное представление будет ViewData, сериализованным в Json. ViewEngine контроллера также изменяется на JsonViewEngine, но это вызывается только в случае исключения.

Если jqmvc решил, что запрос является Ajax-запросом, он создаст обычный ViewResult, но изменит ViewLocator контроллера.
(Оффтоп: я думаю, что ошибка проектирования заключается в том, чтобы иметь viewlocator на контроллере. Он должен быть на объекте ViewResult, это единственный объект, который его использует. Возможно, это будет изменено в следующем предварительном просмотре…)
Этот AjaxViewLocator будет сначала выглядеть для файлов .ascx вместо файлов .aspx. Если он не может найти .ascx, он загрузит .aspx после этого. Вы также можете создать целевой файл .ascx: если вы выполняете ajax-запрос через нашу функцию javascript jQuery.mvc.request () (или одну из функций htmlhelper), вы должны указать цель для загруженного содержимого. Допустим, мы хотим загрузить / Home / Index в <div id = «dynamiccontent»> </ div>
AjaxViewLocator будет искать:

  1. /Views/Home/Index.dynamiccontent.ascx
  2. /Views/Home/Index.acx
  3. /Views/Home/dynamiccontent.ascx
  4. /Views/Home/Index.aspx
  5. /Views/Shared/Index.dynamiccontent.ascx
  6. /Views/Shared/Index.ascx
  7. /Views/Shared/dynamiccontent.ascx
  8. /Views/Shared/Index.aspx

Чтобы страница / Home / index была доступна как в виде ajax-запроса, так и в качестве обычного запроса, вы можете создать /Views/Home/Index.aspx, который загружает index.ascx следующим образом:

<%= Html.RenderUserControl("~/Views/Home/Index.ascx") %>

Что нужно знать

  • У нас есть несколько HelperClasses для упрощения использования jqmvc

  • Ключи ViewData «Сообщения» и «Ошибки» специально обрабатываются jqmvc.

  • Ваша страница всегда должна содержать:

    • <% = Html.RegisterJqueryMvc (Page.ClientScript)%> Чтобы зарегистрировать необходимые файлы JavaScript

    • <div id = «loading»> </ div>; или что-то еще с id = «loading». Это будет видно во время ajax-запросов

    • <div id = «errors»> </ div> для отображения ошибок

    • <div id = «messages»> </ div> для отображения сообщений (информационных)

  • У нас есть специальный заполнитель содержимого в JqueryMvc.UI.WebControls.ContentPlaceHolder. Это будет использовать AjaxViewLocator для загрузки содержимого по умолчанию. Например, если используется как это на вашей главной странице, а текущий запрос / Home / Index:
    <jq: ContentPlaceHolder ID = «maincontent» runat = «server» />
    Он будет искать контент в:

    1. /Views/Home/Index.maincontent.ascx
    2. /Views/Home/Index.acx
    3. /Views/Home/maincontent.ascx
    4. /Views/Home/Index.aspx
    5. /Views/Shared/Index.maincontent.ascx
    6. /Views/Shared/Index.ascx
    7. /Views/Shared/maincontent.ascx
    8. /Views/Shared/Index.aspx

      Таким образом, ваш index.aspx может быть просто пустой страницей, которая указывает на MasterPage с этим contentplaceholer загрузки контента по умолчанию.

      <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage %>
  • Ваши файлы ascx должны наследоваться от JqueryMvc.Mvc.ExtViewUserControl, чтобы иметь доступ к AjaxHelper (ошибка в asp.net mvc!) И чтобы сообщения и ошибки анализировались jqmvc .
  • В случае ошибки контроллер по умолчанию будет искать страницу восстановления в /Views/[ControllerName]/Rescues/error.aspx или /Views/Shared/Rescues/error.aspx (или .ascx в случае запроса ajax). Вы можете указать свои собственные спасения для различных типов ошибок, используя RescueAttribute из
  • Вам следует удалить default.aspx, если ваш сервер приложений поддерживает сопоставления с подстановочными знаками.