using System; using System.IO; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Web.Http; using ZeroLevel.Services.Web; namespace ZeroLevel.WebAPI { public abstract class BaseHtmlController : BaseController { protected readonly string _baseResourcesFolder; public BaseHtmlController(string baseResourcesFolder) { _baseResourcesFolder = baseResourcesFolder; } #region Resource responce /// /// Создает ответ с JS в качетве содержимого /// /// Имя js файла /// Готовый ответ private HttpResponseMessage CreateJSResponse(HttpRequestMessage request, string filename) { var absolutePath = Path.Combine(_baseResourcesFolder, "JS", filename); return CreateFromFileResponse(request, absolutePath, "application/javascript"); } /// /// Создает ответ с CSS в качетве содержимого /// /// Имя css файла /// Готовый ответ private HttpResponseMessage CreateCSSResponse(HttpRequestMessage request, string filename) { var absolutePath = Path.Combine(_baseResourcesFolder, "CSS", filename); return CreateFromFileResponse(request, absolutePath, "text/css"); } /// /// Создает ответ с фрагментом HTML в качетве содержимого /// /// Имя файла с HTML фрагментом /// Готовый ответ protected HttpResponseMessage CreateHTMLResponse(HttpRequestMessage request, string filename) { var absolutePath = Path.Combine(_baseResourcesFolder, filename); if (false == File.Exists(absolutePath)) { absolutePath = Path.Combine(_baseResourcesFolder, "HTML", filename); } return CreateFromFileResponse(request, absolutePath, "text/html"); } /// /// Создает ответ с изображением в качестве содержимого /// /// Имя файла с изображением /// Готовый ответ public HttpResponseMessage CreateImageResponse(HttpRequestMessage request, string filename) { var absolutePath = Path.Combine(_baseResourcesFolder, "images", filename); switch (Path.GetExtension(filename).ToLower()) { case ".ico": return CreateFromFileBinaryResponse(request, absolutePath, "image/x-icon"); case ".png": return CreateFromFileBinaryResponse(request, absolutePath, "image/png"); case ".jpeg": case ".jpg": return CreateFromFileBinaryResponse(request, absolutePath, "image/jpeg"); case ".gif": return CreateFromFileBinaryResponse(request, absolutePath, "image/gif"); } return request.CreateSelfDestroyingResponse(HttpStatusCode.NotFound); } #endregion #region File system /// /// Создает ответ в текстовом представлении, из указанного файла /// /// Путь к файлу /// Mime-тип содержимого файла /// Результат private static HttpResponseMessage CreateFromFileResponse(HttpRequestMessage request, string filename, string mediaType) { try { var content = File.ReadAllText( Path.Combine(ZeroLevel.Configuration.BaseDirectory, filename), Encoding.UTF8); var response = request.CreateSelfDestroyingResponse(HttpStatusCode.OK); response.Content = new StringContent(content); response.Content.Headers.ContentType = new MediaTypeHeaderValue(mediaType); return response; } catch (Exception ex) { Log.Warning(string.Format("Не удалось загрузить файл {0} в качестве ответа типа {1}", filename, mediaType), ex.ToString()); return request.CreateSelfDestroyingResponse(HttpStatusCode.NotFound); } } /// /// Создает ответ в виде байт-массива из указанного файла /// /// Путь к файлу /// Mime-тип содержимого файла /// Результат private static HttpResponseMessage CreateFromFileBinaryResponse(HttpRequestMessage request, string filename, string mediaType) { try { var response = request.CreateSelfDestroyingResponse(); response.Content = new ByteArrayContent(File.ReadAllBytes( Path.Combine(ZeroLevel.Configuration.BaseDirectory, filename))); response.Content.Headers.ContentType = new MediaTypeHeaderValue(mediaType); return response; } catch (Exception ex) { Log.Warning(string.Format("Не удалось загрузить файл {0} в качестве ответа типа {1}", filename, mediaType), ex.ToString()); return request.CreateSelfDestroyingResponse(HttpStatusCode.NotFound); } } #endregion /// /// Выполняет поиск и возврат в качестве ответа ресурса сайта, /// javascript, css файла или файла с изображением /// /// Запрос /// Ответ protected HttpResponseMessage _GetResource(HttpRequestMessage request) { var keys = UrlUtility.ParseQueryString(request.RequestUri.Query); if (keys.ContainsKey("js")) { var filename = WepApiResourceRouter.GetJsFile(keys["js"]); return CreateJSResponse(request, filename); } else if (keys.ContainsKey("css")) { var filename = WepApiResourceRouter.GetCssFile(keys["css"]); return CreateCSSResponse(request, filename); } else if (keys.ContainsKey("html")) { var filename = WepApiResourceRouter.GetHtmlFile(keys["html"]); return CreateHTMLResponse(request, filename); } else if (keys.ContainsKey("img")) { return CreateImageResponse(request, keys["img"]); } else { var key = request.RequestUri.LocalPath.Trim('/'); if (string.IsNullOrWhiteSpace(key)) key = "index"; var filename = WepApiResourceRouter.GetHtmlFile(key); if (false == string.IsNullOrWhiteSpace(filename)) { return CreateHTMLResponse(request, filename); } } return request.CreateSelfDestroyingResponse(HttpStatusCode.NotFound); } /// /// Создает ответ в виде фрагмента HTML /// /// HTML текст /// protected static HttpResponseMessage CreateHTMLFragmentResponse(HttpRequestMessage request, string text) { var response = request.CreateSelfDestroyingResponse(); response.Content = new StringContent(text); response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html"); return response; } #region Helpers /// /// Хак для JQuery UI /// [HttpGet] [Route("images/{id}")] [Route("api/web/images/{id}")] public HttpResponseMessage Images(HttpRequestMessage request, [FromUri]string id) { return CreateImageResponse(request, id); } /// /// Выполняет поиск и возврат в качестве ответа ресурса сайта, /// javascript, css файла или файла с изображением /// /// Запрос /// Ответ [HttpGet] [Route("api/web/resources")] public HttpResponseMessage GetResource(HttpRequestMessage request) { return _GetResource(request); } #endregion } }