Загрузил проекты примеров
This commit is contained in:
486
KhvAdmDataAdapter/App_Code/Handler.cs
Normal file
486
KhvAdmDataAdapter/App_Code/Handler.cs
Normal file
@ -0,0 +1,486 @@
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Lers.Data;
|
||||
using Lers.Core;
|
||||
using Lers.Utils;
|
||||
|
||||
namespace Lers.Web.DataAdapter.KhvAdm
|
||||
{
|
||||
/// <summary>
|
||||
/// Реализует обработчик запроса на выдачу данных в формате экспорта, утвержденном администрацией г. Хабаровск
|
||||
/// </summary>
|
||||
internal class Handler: IHttpHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Используется в качестве источника при протоколировании.
|
||||
/// </summary>
|
||||
private static readonly string CLASS_NAME = typeof(Handler).FullName;
|
||||
|
||||
/// <summary>
|
||||
/// Начальная дата для экспорта данных
|
||||
/// Берется из параметра dateFrom
|
||||
/// </summary>
|
||||
private DateTime beginDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Конечная дата для экспорта данных
|
||||
/// Берется из параметра dateTo
|
||||
/// </summary>
|
||||
private DateTime endDate = DateTime.Now;
|
||||
|
||||
/// <summary> Тип временных меток: 1 - часовые, 0 - суточные; -1 - и часовые и суточные </summary>
|
||||
private int dataPeriodType = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Экземпляр класса для подключения к серверу ЛЭРС УЧЕТ
|
||||
/// </summary>
|
||||
private LersServer server;
|
||||
|
||||
/// <summary>
|
||||
/// Протоколирует в файл
|
||||
/// </summary>
|
||||
private Logger logger;
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает значение, позволяющее определить, может ли другой запрос использовать экземпляр класса IHttpHandler.
|
||||
/// </summary>
|
||||
bool IHttpHandler.IsReusable
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получает информацию о запросе
|
||||
/// </summary>
|
||||
/// <returns>Информация о запросе</returns>
|
||||
private string GetRequestInfo()
|
||||
{
|
||||
if (HttpContext.Current == null || HttpContext.Current.Request == null)
|
||||
return "<Не удалось получить дополнительную информацию о запросе>";
|
||||
|
||||
HttpRequest currentRequest = HttpContext.Current.Request;
|
||||
|
||||
// Адрес, с которого пришёл запрос (может быть адрес прокси)
|
||||
string publicAddress = currentRequest.ServerVariables["REMOTE_ADDR"];
|
||||
|
||||
// Локальный адрес компа, заполняется при перенаправлении запроса через прокси
|
||||
string localAddress = currentRequest.ServerVariables["HTTP_X_FORWARDED_FOR"];
|
||||
|
||||
|
||||
StringBuilder info = new StringBuilder();
|
||||
|
||||
info.AppendFormat("IP-адрес запроса: {0}.\r\nИсходный IP-адрес запроса: {1}\r\n", publicAddress, localAddress);
|
||||
|
||||
info.AppendFormat("Адрес web-страницы: {0}\r\n", currentRequest.Url);
|
||||
|
||||
return info.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обрабатывает веб запрос. Исходная точка в HttpHandler
|
||||
/// </summary>
|
||||
/// <param name="context">Контекст Http запроса</param>
|
||||
void IHttpHandler.ProcessRequest(HttpContext context)
|
||||
{
|
||||
InitLogger();
|
||||
|
||||
try
|
||||
{
|
||||
string msg = "Получен запрос на экспорт данных в формате ДГК.\r\n" + GetRequestInfo();
|
||||
|
||||
LogInfo(msg);
|
||||
|
||||
Init();
|
||||
|
||||
// Разбираем входные параметры
|
||||
ParseInputParams();
|
||||
|
||||
// Экспортируем данные
|
||||
ExportData();
|
||||
|
||||
if (context.Response.IsClientConnected)
|
||||
LogInfo("Данные успешно отправлены.");
|
||||
}
|
||||
catch (ConfigurationErrorsException ex)
|
||||
{
|
||||
LogError(ex.Message);
|
||||
}
|
||||
catch (Lers.Networking.RequestTimeoutException exc)
|
||||
{
|
||||
LogError("Вышло время ожидания на выполнение операции.\r\n");
|
||||
}
|
||||
catch (Lers.Networking.ServerConnectionException exc)
|
||||
{
|
||||
LogError("Ошибка при попытки установить соединение с сервером ЛЭРС УЧЕТ.\r\n");
|
||||
}
|
||||
catch (Lers.Networking.AuthorizationFailedException exc)
|
||||
{
|
||||
LogError("Ошибка при попытки установить соединение с сервером ЛЭРС УЧЕТ.\r\n");
|
||||
}
|
||||
catch (VersionMismatchException exc)
|
||||
{
|
||||
LogError("Ошибка при попытки установить соединение с сервером ЛЭРС УЧЕТ.\r\n");
|
||||
}
|
||||
catch(Exception exc)
|
||||
{
|
||||
string msg = "Ошибка экспорта данных в формате ДГК. ";
|
||||
LogError(msg);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.logger.LogDebug("Закрываем подключение...", CLASS_NAME);
|
||||
|
||||
if(server != null && server.IsConnected)
|
||||
server.Disconnect(2000);
|
||||
|
||||
this.logger.Close();
|
||||
|
||||
context.Response.End();
|
||||
}
|
||||
}
|
||||
|
||||
#region Протоколирование
|
||||
|
||||
/// <summary>
|
||||
/// Протоколирует сообщение об ошибке
|
||||
/// </summary>
|
||||
/// <param name="message">Текст сообщения</param>
|
||||
private void LogError(string message)
|
||||
{
|
||||
this.logger.LogError("Dgk:\t" + message, CLASS_NAME);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Протоколирует информационное сообщение
|
||||
/// </summary>
|
||||
/// <param name="message">Текст сообщения</param>
|
||||
private void LogInfo(string message)
|
||||
{
|
||||
this.logger.LogMessage("Dgk:\t" + message, CLASS_NAME);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Протоколирует отладочное сообщение
|
||||
/// </summary>
|
||||
/// <param name="message">Текст сообщения</param>
|
||||
private void LogDebug(string message)
|
||||
{
|
||||
this.logger.LogDebug("Dgk:\t" + message, CLASS_NAME);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Протоколирует предупреждающее сообщение
|
||||
/// </summary>
|
||||
/// <param name="message">Текст сообщения</param>
|
||||
private void LogWarning(string message)
|
||||
{
|
||||
this.logger.LogWarning("Dgk:\t" + message, CLASS_NAME);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Инициализирует логгер
|
||||
/// </summary>
|
||||
private void InitLogger()
|
||||
{
|
||||
// Считываем путь до журнала протокола
|
||||
string logFile = System.Configuration.ConfigurationManager.AppSettings["DataAdapterFileLogPath"] ?? "";
|
||||
|
||||
if (logFile == "")
|
||||
logFile = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\LERS\Logs\Web\DataAdapter.log";
|
||||
|
||||
// Если каталога нет, создаем его
|
||||
if (!Directory.Exists(Path.GetDirectoryName(logFile)))
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(logFile));
|
||||
|
||||
bool debug = false;
|
||||
|
||||
// Считываем значение включено ли протоколирование отладочных сообщений
|
||||
string fileLogDebug = System.Configuration.ConfigurationManager.AppSettings["DataAdapterFileLogDebug"] ?? "";
|
||||
|
||||
if (fileLogDebug == "1")
|
||||
debug = true;
|
||||
|
||||
this.logger = Logger.Create(logFile);
|
||||
|
||||
this.logger.LogDebugMessages = debug;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Инициализация и разбор входных параметров
|
||||
|
||||
/// <summary>
|
||||
/// Инициализация
|
||||
/// </summary>
|
||||
private void Init()
|
||||
{
|
||||
LogDebug("Инициализация...");
|
||||
|
||||
// Отключаем буферизацию
|
||||
HttpContext.Current.Response.BufferOutput = false;
|
||||
|
||||
// ServerAddress
|
||||
string serverAddress = ConfigurationManager.AppSettings["ServerAddress"] ?? "";
|
||||
|
||||
if (serverAddress == "")
|
||||
serverAddress = "localhost";
|
||||
|
||||
// ServerPort
|
||||
int serverPort;
|
||||
|
||||
if (!Int32.TryParse(ConfigurationManager.AppSettings["ServerPort"], out serverPort))
|
||||
serverPort = 10000;
|
||||
|
||||
// Login
|
||||
string login = ConfigurationManager.AppSettings["AdmLogin"];
|
||||
|
||||
if(string.IsNullOrEmpty(login))
|
||||
throw new ConfigurationErrorsException("В конфигурации приложения отсутствует параметр: AdmLogin");
|
||||
|
||||
// Password
|
||||
string password = ConfigurationManager.AppSettings["AdmPassword"];
|
||||
|
||||
if(string.IsNullOrEmpty(password))
|
||||
throw new ConfigurationErrorsException("В конфигурации приложения отсутствует параметр: AdmPassword");
|
||||
|
||||
LogDebug("Инициализация завершена.");
|
||||
|
||||
// Соединяемся
|
||||
|
||||
LogDebug("Соединение с сервером ЛЭРС УЧЕТ...");
|
||||
|
||||
this.server = new LersServer();
|
||||
|
||||
this.server.VersionMismatch += server_VersionMismatch;
|
||||
|
||||
System.Security.SecureString securePassword = Networking.SecureStringHelper.ConvertToSecureString(password);
|
||||
|
||||
this.server.Connect(serverAddress, (ushort)serverPort, new Networking.BasicAuthenticationInfo(login, securePassword));
|
||||
|
||||
LogDebug("Соединение установлено.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обработчик ошибки несовместимости версий сервера и фреймворка
|
||||
/// </summary>
|
||||
void server_VersionMismatch(object sender, VersionMismatchEventArgs e)
|
||||
{
|
||||
#if DEBUG
|
||||
e.Ignore = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Разбор входных параметров
|
||||
/// </summary>
|
||||
private void ParseInputParams()
|
||||
{
|
||||
NameValueCollection paramCollection = HttpContext.Current.Request.Params;
|
||||
|
||||
DateTime result;
|
||||
|
||||
// Начальная дата
|
||||
if (TryParseDateParam(paramCollection, "dateFrom", out result))
|
||||
beginDate = result;
|
||||
|
||||
// Конечная дата
|
||||
if (TryParseDateParam(paramCollection, "DateTo", out result))
|
||||
endDate = result;
|
||||
|
||||
// Из регламента:
|
||||
// ДГК может в любое время выполнять запросы данных за произвольный период,
|
||||
// но на глубину не более чем два месяца, включая отчетный.
|
||||
|
||||
// Комментарий Клауса:
|
||||
// Если запрашивается большой интервал, то подрезаем его с начала,
|
||||
// иначе получаем исключение "Слишком большой размер пакета ( > 20МБ )
|
||||
|
||||
// Если запрашивается интервал больше 3 месяцев, подрезаем его с начала.
|
||||
if(((TimeSpan)endDate.Subtract(beginDate)).TotalDays > 60)
|
||||
{
|
||||
beginDate = endDate.Subtract(new TimeSpan(60, 0, 0, 0));
|
||||
|
||||
LogWarning("Интервал выборки данных превышает 60 дней. Дата начала интервала заменена на " + beginDate);
|
||||
}
|
||||
|
||||
//Если интервал не корректный то устанавливаем интервал по умолчанию
|
||||
if (beginDate > endDate)
|
||||
{
|
||||
beginDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
|
||||
|
||||
endDate = DateTime.Now;
|
||||
|
||||
LogWarning("Конечная дата периода превышает начальную. Параметры были установлены по умолчанию.");
|
||||
}
|
||||
|
||||
// Тип данных
|
||||
if (!Int32.TryParse(paramCollection["PeriodType"], out dataPeriodType))
|
||||
dataPeriodType = -1; // Суточные и часовые
|
||||
|
||||
// По умолчанию выдаем и суточные и часовые данные
|
||||
if (dataPeriodType != -1 && dataPeriodType != 0 && dataPeriodType != 1)
|
||||
dataPeriodType = -1;
|
||||
|
||||
LogDebug(String.Format("параметры запроса: beginDate = {0}, endDate = {1}, dataPeriodType = {2}",
|
||||
beginDate, endDate, dataPeriodType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Пытается разобрать параметр дата задающую начало и конец периода
|
||||
/// </summary>
|
||||
/// <param name="paramCollection">Коллекция параметров, полученная из HttpContext.Request.Params</param>
|
||||
/// <param name="paramName">Имя параметра для разбора</param>
|
||||
/// <param name="value">Дата полученная из указанного параметра</param>
|
||||
/// <returns>Результат разбора: true - успех, false - провал.</returns>
|
||||
private bool TryParseDateParam(NameValueCollection paramCollection, string paramName, out DateTime result)
|
||||
{
|
||||
result = new DateTime();
|
||||
|
||||
// Проверяем есть ли вообще параметры, есть ли необходимый нам параметр, не пустой ли он
|
||||
if (paramCollection.Count > 0 &&
|
||||
!String.IsNullOrEmpty(paramCollection[paramName]))
|
||||
{
|
||||
if (DateTime.TryParseExact(paramCollection[paramName], "yyyyMMddHHmm", null, System.Globalization.DateTimeStyles.AssumeLocal, out result))
|
||||
return true;
|
||||
|
||||
if (DateTime.TryParseExact(paramCollection[paramName], "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out result))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Выдача данных
|
||||
|
||||
/// <summary>
|
||||
/// Экспортирует данные потребления указанного типа
|
||||
/// </summary>
|
||||
/// <param name="measurePoint">Точка учета</param>
|
||||
/// <param name="isDay">Тип данных: true - суточные, false - часовые</param>
|
||||
private void ExportConsumption(MeasurePoint measurePoint, bool isDay)
|
||||
{
|
||||
// TODO: Сократить количество запросов на сервер, одновременно запрашивая суточные и часовые данные
|
||||
|
||||
// Получаем данные потребления по точке учета
|
||||
MeasurePointConsumptionRecordCollection consumption = measurePoint.Data.GetConsumption(beginDate, endDate, ((isDay) ? DeviceDataType.Day : DeviceDataType.Hour));
|
||||
|
||||
// Измеряемый ресурс
|
||||
int systemTypeId = (int)measurePoint.SystemType;
|
||||
|
||||
// Номер точки учета
|
||||
int number = measurePoint.Number ?? 0;
|
||||
|
||||
string output = "";
|
||||
|
||||
foreach (MeasurePointConsumptionRecordWater dataRecord in consumption)
|
||||
{
|
||||
if (dataRecord.M_in == null)
|
||||
continue;
|
||||
|
||||
// Накапливаем данные в строке
|
||||
output = number + ";"
|
||||
+ ((isDay) ? dataRecord.DateTime.ToString("yyyy-MM-dd") : dataRecord.DateTime.ToString("yyyy-MM-dd HH:mm"))
|
||||
+ ";2;"
|
||||
+ systemTypeId + ";"
|
||||
+ (dataRecord.T_in ?? 0) + ";"
|
||||
+ (dataRecord.T_out == null ? "" : dataRecord.T_out.ToString()) + ";"
|
||||
+ (dataRecord.M_in ?? 0) + ";"
|
||||
+ (dataRecord.M_out == null ? "" : dataRecord.M_out.ToString()) + ";"
|
||||
+ (dataRecord.Q_in == null? "" : dataRecord.Q_in.ToString()) + ";"
|
||||
+ (dataRecord.Q_out == null ? "" : dataRecord.Q_out.ToString()) + ";"
|
||||
+ (dataRecord.P_in == null ? "" : dataRecord.P_in.ToString()) + ";"
|
||||
+ (dataRecord.P_out == null ? "" : dataRecord.P_out.ToString()) + ";"
|
||||
+ (dataRecord.WorkTime == null ? "" : dataRecord.WorkTime.ToString()) + ";"
|
||||
+ Convert.ToInt32(isDay) + ";\n";
|
||||
|
||||
// Выдаем браузеру
|
||||
HttpContext.Current.Response.Write(output);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Отправляет заголовок
|
||||
/// </summary>
|
||||
private void SendHeader()
|
||||
{
|
||||
HttpResponse response = HttpContext.Current.Response;
|
||||
|
||||
// Определяем имя файла
|
||||
string fileName = "" + ((beginDate != DateTime.MinValue) ? beginDate.ToString("yyyyMMddHHmm") : "")
|
||||
+ "-" + ((endDate != DateTime.MinValue) ? endDate.ToString("yyyyMMddHHmm") : "")
|
||||
+ ((dataPeriodType > -1) ? "_" + dataPeriodType : "")
|
||||
+ ".csv";
|
||||
|
||||
// Подготавливаем заголовок
|
||||
// Ставим в качестве ответа, файл в кодировке по умолчанию
|
||||
response.ContentEncoding = System.Text.Encoding.Default;
|
||||
response.ContentType = "application/x-download";
|
||||
response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName));
|
||||
|
||||
// Выдаем браузеру заголовок данных потребления
|
||||
response.Write("MeasurePointID;DataDate;DataSource;ResourceTypeID;T_in;T_out;M_in;M_out;H_in;H_out;P_in;P_out;WorkTime;IsDay\n");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Экспортирует данные потребления
|
||||
/// </summary>
|
||||
private void ExportData()
|
||||
{
|
||||
LogDebug("Отправка данных для администрации г. Хабаровска в ответ на запрос...");
|
||||
|
||||
SendHeader();
|
||||
|
||||
MeasurePoint[] measurePoints = this.server.MeasurePoints.GetList(MeasurePointType.Regular);
|
||||
|
||||
// Выдаем все суточные данные потребления
|
||||
if (dataPeriodType == 0 || dataPeriodType == -1)
|
||||
{
|
||||
foreach (MeasurePoint measurepoint in measurePoints)
|
||||
{
|
||||
// Выгружаем данные только по воде
|
||||
if (measurepoint.SystemType != SystemType.ColdWater && measurepoint.SystemType != SystemType.HotWater && measurepoint.SystemType != SystemType.Heat)
|
||||
continue;
|
||||
|
||||
ExportConsumption(measurepoint, true);
|
||||
|
||||
if (!HttpContext.Current.Response.IsClientConnected)
|
||||
{
|
||||
LogDebug("Клиент был отключен от веб-сервера.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Выдаем все часовые данные потребления
|
||||
if (dataPeriodType == 1 || dataPeriodType == -1)
|
||||
{
|
||||
foreach (MeasurePoint measurepoint in measurePoints)
|
||||
{
|
||||
// Выгружаем данные только по воде
|
||||
if (measurepoint.SystemType != SystemType.ColdWater && measurepoint.SystemType != SystemType.HotWater && measurepoint.SystemType != SystemType.Heat)
|
||||
continue;
|
||||
|
||||
ExportConsumption(measurepoint, false);
|
||||
|
||||
if (!HttpContext.Current.Response.IsClientConnected)
|
||||
{
|
||||
LogDebug("Клиент был отключен от веб-сервера.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
267
KhvAdmDataAdapter/App_Code/Logger.cs
Normal file
267
KhvAdmDataAdapter/App_Code/Logger.cs
Normal file
@ -0,0 +1,267 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Lers.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Протоколирует сообщения в файл.
|
||||
/// </summary>
|
||||
public class Logger : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Тип сообщения в журнале.
|
||||
/// </summary>
|
||||
private enum LogType
|
||||
{
|
||||
/// <summary>
|
||||
/// Отладочное сообщение.
|
||||
/// </summary>
|
||||
Debug = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Информационное сообщение.
|
||||
/// </summary>
|
||||
Info = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Предупреждение.
|
||||
/// </summary>
|
||||
Warning = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Ошибка.
|
||||
/// </summary>
|
||||
Error = 3,
|
||||
}
|
||||
|
||||
private Stream stream;
|
||||
|
||||
private StreamWriter streamWriter;
|
||||
|
||||
/// <summary>
|
||||
/// Определяет, нужно ли протоколировать отладочные сообщения.
|
||||
/// </summary>
|
||||
public bool LogDebugMessages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Определяет, нужно ли протоколировать идентификатор потока
|
||||
/// </summary>
|
||||
public bool LogThreadId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Инициализирует новый экземпляр класса.
|
||||
/// </summary>
|
||||
/// <param name="stream">Поток записи.</param>
|
||||
private Logger(Stream stream)
|
||||
{
|
||||
if (stream == null)
|
||||
throw new ArgumentNullException("stream");
|
||||
|
||||
this.stream = stream;
|
||||
this.streamWriter = new StreamWriter(stream, Encoding.UTF8);
|
||||
|
||||
WritePreamble();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создает новый экземпляр, протоколирующий сообщения в указанный файл.
|
||||
/// </summary>
|
||||
/// <param name="fileName">Имя файла журнала.</param>
|
||||
/// <returns>Возвращает экземпляр <see cref="Logger"/>.</returns>
|
||||
public static Logger Create(string fileName)
|
||||
{
|
||||
// Если папка не существует, то создаем её.
|
||||
|
||||
string logDirectory = Path.GetDirectoryName(fileName);
|
||||
|
||||
if (!Directory.Exists(logDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(logDirectory);
|
||||
}
|
||||
|
||||
// Открываем файловый поток на запись. Если файл уже существует, то будем дописывать в него,
|
||||
// если нет - создаем новый файл.
|
||||
|
||||
FileMode fileMode;
|
||||
|
||||
if (File.Exists(fileName))
|
||||
fileMode = FileMode.Append;
|
||||
else
|
||||
fileMode = FileMode.CreateNew;
|
||||
|
||||
FileStream stream = new FileStream(fileName, fileMode, FileAccess.Write, FileShare.Read);
|
||||
|
||||
// Создаем новый экземпляр класса и возвращаем его.
|
||||
|
||||
try
|
||||
{
|
||||
return new Logger(stream);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// При ошибке закрываем файловый поток.
|
||||
|
||||
stream.Close();
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Закрывает файл журнала.
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Протоколирует информационное сообщение.
|
||||
/// </summary>
|
||||
/// <param name="message">Текст сообщения.</param>
|
||||
/// <param name="source">Источник сообщения.</param>
|
||||
public void LogMessage(string message, string source)
|
||||
{
|
||||
Log(LogType.Info, message, source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Протоколирует предупреждающее сообщение.
|
||||
/// </summary>
|
||||
/// <param name="message">Текст сообщения.</param>
|
||||
/// <param name="source">Источник сообщения.</param>
|
||||
public void LogWarning(string message, string source)
|
||||
{
|
||||
Log(LogType.Warning, message, source);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Протоколирует сообщение об ошибке.
|
||||
/// </summary>
|
||||
/// <param name="message">Текст сообщения.</param>
|
||||
/// <param name="source">Источник сообщения.</param>
|
||||
public void LogError(string message, string source)
|
||||
{
|
||||
Log(LogType.Error, message, source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Протоколирует отладочное.
|
||||
/// </summary>
|
||||
/// <param name="message">Текст сообщения.</param>
|
||||
/// <param name="source">Источник сообщения.</param>
|
||||
public void LogDebug(string message, string source)
|
||||
{
|
||||
// Отладочные сообщения протоколируем только если включено.
|
||||
|
||||
if (this.LogDebugMessages)
|
||||
Log(LogType.Debug, message, source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Протоколирует сообщение в журнал.
|
||||
/// </summary>
|
||||
/// <param name="logType">Важность сообщения.</param>
|
||||
/// <param name="message">Текст сообщения.</param>
|
||||
/// <param name="source">Источник сообщения.</param>
|
||||
private void Log(LogType logType, string message, string source)
|
||||
{
|
||||
CheckDisposed();
|
||||
|
||||
if (message == null)
|
||||
throw new ArgumentNullException("message");
|
||||
|
||||
if (source == null)
|
||||
throw new ArgumentNullException("source");
|
||||
|
||||
// Сонхронизируем доступ из разных потоков.
|
||||
|
||||
lock (this.streamWriter)
|
||||
{
|
||||
// Записываем строку и очищаем буфер, чтобы строка сразу появилась в лог-файле.
|
||||
|
||||
if(this.LogThreadId)
|
||||
this.streamWriter.WriteLine("{0:dd-MM-yyyy HH:mm:ss.fff}\t{1}:{2:000}\t{3}\t\t\t{4}",
|
||||
DateTime.Now, FormatLogType(logType), Thread.CurrentThread.ManagedThreadId, message, source);
|
||||
else
|
||||
this.streamWriter.WriteLine("{0:dd-MM-yyyy HH:mm:ss.fff}\t{1}\t{2}\t\t\t{3}", DateTime.Now, FormatLogType(logType), message, source);
|
||||
|
||||
this.streamWriter.Flush();
|
||||
}
|
||||
|
||||
// В отладочной версии дополнительно протоколируем в окно Output отладчика.
|
||||
|
||||
#if DEBUG
|
||||
System.Diagnostics.Debugger.Log((int)logType, source, message + "\r\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Записывает заголовок в файл журнала.
|
||||
/// </summary>
|
||||
private void WritePreamble()
|
||||
{
|
||||
this.streamWriter.WriteLine("========================================");
|
||||
this.streamWriter.WriteLine("== Журнал открыт " + DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss.fff"));
|
||||
this.streamWriter.WriteLine("========================================");
|
||||
|
||||
this.streamWriter.Flush();
|
||||
}
|
||||
|
||||
private static string FormatLogType(LogType logType)
|
||||
{
|
||||
switch (logType)
|
||||
{
|
||||
case LogType.Debug:
|
||||
return "D";
|
||||
|
||||
case LogType.Info:
|
||||
return "I";
|
||||
|
||||
case LogType.Warning:
|
||||
return "W";
|
||||
|
||||
case LogType.Error:
|
||||
return "E";
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("logType");
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
private bool isDisposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Проверяет, что экземпляр не уничтожен.
|
||||
/// </summary>
|
||||
private void CheckDisposed()
|
||||
{
|
||||
if (this.isDisposed)
|
||||
throw new ObjectDisposedException("Использование экземпляра невозможно, т.к. объект был закрыт.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Освобождает ресурсы.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (!this.isDisposed)
|
||||
{
|
||||
this.streamWriter.Close();
|
||||
this.stream.Close();
|
||||
|
||||
this.streamWriter = null;
|
||||
this.stream = null;
|
||||
|
||||
this.isDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
85
KhvAdmDataAdapter/KhvAdmDataAdapter.csproj
Normal file
85
KhvAdmDataAdapter/KhvAdmDataAdapter.csproj
Normal file
@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{0C6B7048-E464-439D-82CD-99532A932E5A}</ProjectGuid>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Lers.Web.DataAdapter.KhvAdm</RootNamespace>
|
||||
<AssemblyName>Lers.KhvAdmDataAdapter</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<TargetFrameworkProfile />
|
||||
<UseIISExpress>false</UseIISExpress>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Lers.System">
|
||||
<HintPath>..\..\Lers.System\bin\x86\Debug\Lers.System.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.configuration" />
|
||||
<Reference Include="System.Web" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="App_Code\Handler.cs" />
|
||||
<Compile Include="App_Code\Logger.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>False</AutoAssignPort>
|
||||
<DevelopmentServerPort>89</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>
|
||||
</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
</CustomServerUrl>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
28
KhvAdmDataAdapter/KhvAdmDataAdapter.sln
Normal file
28
KhvAdmDataAdapter/KhvAdmDataAdapter.sln
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KhvAdmDataAdapter", "KhvAdmDataAdapter.csproj", "{0C6B7048-E464-439D-82CD-99532A932E5A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0C6B7048-E464-439D-82CD-99532A932E5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0C6B7048-E464-439D-82CD-99532A932E5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0C6B7048-E464-439D-82CD-99532A932E5A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0C6B7048-E464-439D-82CD-99532A932E5A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0C6B7048-E464-439D-82CD-99532A932E5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0C6B7048-E464-439D-82CD-99532A932E5A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0C6B7048-E464-439D-82CD-99532A932E5A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0C6B7048-E464-439D-82CD-99532A932E5A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
36
KhvAdmDataAdapter/Properties/AssemblyInfo.cs
Normal file
36
KhvAdmDataAdapter/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Управление общими сведениями о сборке осуществляется с помощью
|
||||
// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
|
||||
// связанные со сборкой.
|
||||
[assembly: AssemblyTitle("ЛЭРС УЧЕТ. Адаптер данных для администрации г. Хабаровска")]
|
||||
[assembly: AssemblyDescription("Выполняет преобразование данных в формат экспорта администрации г. Хабаровска")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("ООО \"Хабаровский центр энергоресурсосбережения\"")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyProduct("Система диспетчеризации ЛЭРС УЧЕТ")]
|
||||
[assembly: AssemblyCopyright("© 2000-2011, Хабаровский центр энергоресурсосбережения")]
|
||||
[assembly: AssemblyTrademark("Внимание: Данная компьютерная программа защищена законами об авторских правах и международными соглашениями. Незаконное воспроизведение или распространения данной программы или любой ее части влечет гражданскую и уголовную ответственность.")]
|
||||
|
||||
// Параметр ComVisible со значением FALSE делает типы в сборке невидимыми
|
||||
// для COM-компонентов. Если требуется обратиться к типу в этой сборке через
|
||||
// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
|
||||
[assembly: Guid("a0027496-d7ea-4530-9e78-3033f1d4e2c7")]
|
||||
|
||||
// Сведения о версии сборки состоят из следующих четырех значений:
|
||||
//
|
||||
// Основной номер версии
|
||||
// Дополнительный номер версии
|
||||
// Номер построения
|
||||
// Редакция
|
||||
//
|
||||
// Можно задать все значения или принять номер построения и номер редакции по умолчанию,
|
||||
// используя "*", как показано ниже:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
40
KhvAdmDataAdapter/web.config
Normal file
40
KhvAdmDataAdapter/web.config
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<connectionStrings/>
|
||||
<system.web>
|
||||
<!--
|
||||
Значение параметра compilation debug="true" означает,
|
||||
что в компилированную страницу будут вставлены отладочные символы. Так как этот
|
||||
параметр влияет на производительность,
|
||||
следует устанавливать в нем значение True только на этапе разработки.
|
||||
-->
|
||||
<compilation debug="true" targetFramework="4.0"/>
|
||||
<!--
|
||||
Раздел <customErrors> позволяет настраивать
|
||||
параметры действий на случай возникновения необработанных ошибок
|
||||
во время выполнения запроса. А именно,
|
||||
он позволяет разработчикам настраивать HTML-страницы
|
||||
с сообщениями об ошибках, которые будут отображаться вместо трассировки стека ошибок.
|
||||
-->
|
||||
<customErrors mode="Off"/>
|
||||
<!-- Секция работает для IIS 5/6 и класического режима IIS 7.0-->
|
||||
<httpHandlers>
|
||||
<add verb="GET" path="KhvAdmImport.aspx" type="Lers.Web.DataAdapter.KhvAdm.Handler, Lers.KhvAdmDataAdapter"/>
|
||||
</httpHandlers>
|
||||
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="KhvAdmDataHandler" path="KhvAdmImport.aspx" verb="GET" type="Lers.Web.DataAdapter.KhvAdm.Handler, Lers.KhvAdmDataAdapter"/>
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
<appSettings>
|
||||
<add key="ServerAddress" value="localhost"/>
|
||||
<add key="ServerPort" value="10000"/>
|
||||
<add key="AdmLogin" value="Admin"/>
|
||||
<add key="AdmPassword" value="Admin"/>
|
||||
<!--Необходимо указывать абсолютный путь-->
|
||||
<add key="DataAdapterFileLogPath" value=""/>
|
||||
<add key="DataAdapterFileLogDebug" value="1"/>
|
||||
</appSettings>
|
||||
</configuration>
|
Reference in New Issue
Block a user