Создание своей реализации ActionResult

Важной особенностью механизма ActionResult является то, что вы можете создать свой собственный вариант, который будет формировать результат в том виде, который вам нужен. Например, вы можете разработать класс, наследующий ActionResult, который будет возвращать клиентам результаты запроса в виде XML-разметки. Классическим примером создания своего варианта ActionResult является реализация класса, который на запрос пользователя создает ответ в виде RSS-ленты. Продемонстрируем реализацию такого класса, добавив к нашему контроллеру AdminController действие Rss, которое будет возвращать пользователю RSS-ленту со списком зарегистрированных пользователей.

Первым делом создадим класс RssResult, который наследует ActionResult, как показано в листинге 4.6.

Листинг 4.6. Класс RssResult

namespace MVCBookProject {

  using System.Web.Mvc; using System.Xml;

  using System.ServiceModel.Syndication;

  public class RssResult : ActionResult {

    public SyndicationFeed Feed { get; set; }

    public RssResult(SyndicationFeed feed)

    {

      Feed = feed;

    }

    public override void ExecuteResult(ControllerContext context)

    {

      context.HttpContext.Response.ContentType =

           "application/rss+xml";

      Rss20FeedFormatter formatter = new Rss20FeedFormatter(Feed);

      using (XmlWriter writer =

           XmlWriter.Create(context.HttpContext.Response.Output))

      {

        if (writer != null)

          formatter.WriteTo(writer);

      }

    }

  }

}

Обратите внимание, для реализации своего варианта ActionResult в классе RssResult мы перегружаем метод ExecuteResult, который и выполняет всю необходимую логику по формированию того результата, который получит клиент в своем браузере в ответ на запрос.

Использование класса RssResult ничем не отличается от применения других вариантов классов ActionResult. Добавим действие Rss в контроллер AdminControiier так, как показано во фрагменте:

[AcceptVerbs(HttpVerbs.Get)]

public RssResult Rss()

{

  MembershipProvider mp = Membership.Provider;

  int userCount;

  var users = mp.GetAllUsers(0, Int32.MaxValue, out userCount);

  List<SyndicationItem> items = new List<SyndicationItem>();

  if (userCount > 0)

  {

    string bodyTemplate = @"email: {0}, comment: {1},

          last activity: {2}, is locked: {3}, is approved: {4}";

    foreach (MembershipUser item in users)

    {

      string body = String.Format(bodyTemplate, item.Email,

            item. Comment, item. LastActivityDate,

            item.IsLockedOut, item.IsApproved);

      items.Add(new SyndicationItem(item.UserName, body, null));

    }

  }

  SyndicationFeed feed = new SyndicationFeed("Cписок пользователей",

       "http://localhost/rss", Request.Url, items);

  return new RssResult(feed);

}

Обратите внимание, что это действие возвращает результат в виде экземпляра класса RssResult, которому передается сгенерированный RSS-поток. После того как мы реализовали RssResult и действие Rss, можно попытаться запросить результат этого действия через браузер, перейдя по относительной ссылке /Admin/Rss. В итоге вы должны получить результат в виде RSS-потока, похожий на тот, который изображен на рис. 4.11.

Создание своих вариантов ActionResult — это исключительно мощное средство для расширения базовой функциональности MVC Framework. Реализуя свои экземпляры ActionResult, вы сможете генерировать ответ на клиентский запрос в любой форме с любой структурой данных.

Более 800 000 книг и аудиокниг! 📚

Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением

ПОЛУЧИТЬ ПОДАРОК