Обновление объекта отчета в проекте ASP .NET MVC с помощью Ajax

16.08.2017

Технология ajax далеко не нова и существенно ускоряет работу веб приложений. Кроме того, не маловажна и визуальная составляющая. Согласитесь, не очень-то приятно, когда при каждом нажатии на веб-кнопку обновляется вся страница. Если ваш интернет не очень быстр, эта процедура вызывает раздражение, так как все элементы пропадают и возникают заново. Хорошо, когда лишь часть веб страницы обновляется. Именно это и обеспечивает ajax. Скрипт передает запрос серверу на обновление нужной части информации. Затем, скрипт вставляет обновленные данные в нужное место на странице.

В этой странице я хочу рассмотреть простой способ применения ajax для обновления информации в проекте ASP .Net MVC. Этот подход называют «ненавязчивый Ajax» - Microsoft Unobtrusive Ajax. Суть заключается в использовании библиотеки Unobtrusive. Которая, с помощью хэлперов позволяет использовать ajax не написав ни единой строчки кода на JavaScript.

Пример будет очень прост, из расчета на новичков. Итак, приступим. Для использования в своем MVC проекте компонента WebReport генератора отчетов FastReport.Net, нужно провести некоторую настройку. А именно внести правки в файлы Web.Config и добавить нужные библиотеки.

Добавляем библиотеки FastReport и FastReport.Web в свой проект.

В Web.config, который расположен в корне проекта добавляем обработчик:

1
2
3
4
5
<system.webServer> 
 <handlers>
 <add name="FastReportHandler" path="FastReport.Export.axd" verb="*" type="FastReport.Web.Handlers.WebExport"/>
 </handlers>
 </system.webServer>

Добавляем пространства имен в файл Web.config, который лежит в папке Views.

1
2
3
4
 <namespaces>
 <add namespace="FastReport" />
 <add namespace="FastReport.Web" />
 </namespaces>

В файле _Layout.cshtml подключаем скрипты и стили в секции <head>:

1
2
3
4
<head>
@WebReportGlobals.Scripts()
@WebReportGlobals.Styles() 
</head>

Теперь переходим к HomeController.cs. Здесь мы размещаем логику работы с отчетом:

Я создал объект отчета глобальным:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using FastReport.Web;
using System.Web.UI.WebControls;
using System.Globalization;
using WebLocalization.Models;
 
namespace WebLocalization.Controllers
{
 public class HomeController : Controller
 {
 private WebReport webReport = new WebReport(); //объект отчета доступен внутри класса
 private string report_path = "J:\\Program Files (x86)\\FastReports\\FastReport.Net\\Demos\\Reports\\"; //директория отчетов
 
 public ActionResult Index()
 {
 SetReport(); //метод загрузки отчета и БД 
 ViewBag.WebReport = webReport; //передаем веб отчет во View
 return View();
 }
 
 public void SetReport()
 {
 System.Data.DataSet dataSet = new System.Data.DataSet(); //создаем набор данных
 dataSet.ReadXml(report_path + "nwind.xml"); //загружаем xml базу данных
 webReport.Report.RegisterData(dataSet, "NorthWind"); //регистрируем источник данных в объекте отчета
 webReport.Report.Load(report_path + "Simple Interactive.frx"); //загружаем отчет в объект WebReport 
 webReport.Width = Unit.Percentage(100);
 webReport.Height = Unit.Percentage(100);
 }
} 

Как видите, в методе Index только загружается отчет и передается в представление с помощью ViewBag. Загрузку отчета я вынес в отдельный метод SetReport().

А теперь рассмотрим представление Index.cshtml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.migrate/jquery-migrate-1.2.1.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.1/jquery.validate.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/5.2.2/jquery.validate.unobtrusive.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.min.js"></script>
@{
 ViewBag.Title = "Home Page";
}
 @using (Ajax.BeginForm("Update", "Home", new AjaxOptions
 {
 UpdateTargetId = "UpdateHere"
 //HttpMethod = "POST",
 //InsertionMode = InsertionMode.Replace,
 }))
 {
 @Html.CheckBox("condition", true)
 <input id="sel" type="submit" value="Select" />
 }
 <div id="UpdateHere">
 @ViewBag.WebReport.GetHtml()
 </div>
</div>

В начале я решил загрузить нужные библиотеки онлайн с официального источника https://www.asp.net/ajax/cdn. Но вы вполне можете установить пакет библиотек с помощью NuGet.

Наибольший интерес вызывает хэлпер Ajax.BeginForm(). Первые два параметра указывают на экшен (метод) и контроллер. Метод Update нам предстоит создать чуть позже. Этот хэлпер очень похож на Html.BeginForm(). Лишь один параметр добавился – AjaxOptions. Вы можете прочитать подробно об этих опциях в MSDN. Самый главный из них – UpdateTargetId. Как вы поняли он указывает на идентификатор элемента в котором будут отображаться изменения. В нашем случае это - <div id="UpdateHere">. Но в нем уже отображается элемент @ViewBag.WebReport.GetHtml(). Это сделано для того, чтобы при первой загрузке страницы выводить отчет из метода Index.

Внутри хэлпера я вывожу CheckBox и кнопку. Флажок будет указывать на состояние панели инструментов отчета – включена/отключена.

Вернемся к контроллеру:     

1
2
3
4
5
6
7
 public ActionResult Index(string condition)
 {
 SetReport();
 ToolbarCondition(condition);
 ViewBag.WebReport = webReport; 
 return View();
 }

В метод Index мы передаем параметр condition – состояние флажка в представлении. Еще добавился вызов метода ToolbarCondition(condition). Он будет обрабатывать параметр и включать или отключать панель инструментов отчета. Давайте напишем этот метод:

1
2
3
4
5
6
7
public void ToolbarCondition(string condition)
 {
 if (condition=="true")
 webReport.ShowToolbar = true;
 else
 webReport.ShowToolbar = false;
 }

А теперь добавим еще один метод, который будет возвращать частичное представление. Это нужно, чтобы Ajax запрос обновлял лишь часть страницы, а не всю целиком:

1
2
3
4
5
6
7
8
[HttpPost]
 public ActionResult Update(string condition)
 {
 SetReport();
 ToolbarCondition(condition);
 ViewBag.WebReport = webReport;
 return PartialView("Update");
 }

Строка [HttpPost] указывает, что метод принимает Post запрос. Наш экшен принимает параметр condition, также, как и Index. По сути все повторяется, только в итоге мы получим частичное представление, которое будет вставлено в представление Index. Теперь нам нужно добавить это представление. Делаем правый клик по имени метода:

И выбираем Add View…:

 

Добавляем новое представление. Отредактируем его:

@ViewBag.WebReport.GetHtml()

Вот и весь код, который я поместил в нем.

Можно запускать приложение:

Включаем флажок и нажимаем кнопку:

При этом обновился лишь объект WebReport, а не вся страница. Это особенно полезно, когда у вас на странице множество информации и ее полная перезагрузка вызовет ощутимые временны'е и ресурсные затраты.

14 марта 2023

Будущее генерации отчетов с помощью Blazor WebAssembly

Пошаговая инструкция по созданию демо приложения на .NET 6 и 7 прямо в браузере с помощью Blazor WebAssembly в FastReport .NET.
14 февраля 2023

Как настроить веб-сервер Apache2 для FastReport .NET

Запускаем веб-сервер Apache2 в операционной системе Linux для FastReport .NET и .NET 5 с помощью нескольких простых команд.
12 июля 2022

Как отобразить много отчетов на одной странице в Blazor

Работа из кода Blazor-приложения для одновременного отображения различных отчётов с фильтрацией данных по условию пользователя.