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 /// <summary> /// Создает ответ с JS в качетве содержимого /// </summary> /// <param name="filename">Имя js файла</param> /// <returns>Готовый ответ</returns> private HttpResponseMessage CreateJSResponse(HttpRequestMessage request, string filename) { var absolutePath = Path.Combine(_baseResourcesFolder, "JS", filename); return CreateFromFileResponse(request, absolutePath, "application/javascript"); } /// <summary> /// Создает ответ с CSS в качетве содержимого /// </summary> /// <param name="filename">Имя css файла</param> /// <returns>Готовый ответ</returns> private HttpResponseMessage CreateCSSResponse(HttpRequestMessage request, string filename) { var absolutePath = Path.Combine(_baseResourcesFolder, "CSS", filename); return CreateFromFileResponse(request, absolutePath, "text/css"); } /// <summary> /// Создает ответ с фрагментом HTML в качетве содержимого /// </summary> /// <param name="filename">Имя файла с HTML фрагментом</param> /// <returns>Готовый ответ</returns> 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"); } /// <summary> /// Создает ответ с изображением в качестве содержимого /// </summary> /// <param name="filename">Имя файла с изображением</param> /// <returns>Готовый ответ</returns> 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 /// <summary> /// Создает ответ в текстовом представлении, из указанного файла /// </summary> /// <param name="filename">Путь к файлу</param> /// <param name="mediaType">Mime-тип содержимого файла</param> /// <returns>Результат</returns> 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); } } /// <summary> /// Создает ответ в виде байт-массива из указанного файла /// </summary> /// <param name="filename">Путь к файлу</param> /// <param name="mediaType">Mime-тип содержимого файла</param> /// <returns>Результат</returns> 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 /// <summary> /// Выполняет поиск и возврат в качестве ответа ресурса сайта, /// javascript, css файла или файла с изображением /// </summary> /// <param name="request">Запрос</param> /// <returns>Ответ</returns> 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); } /// <summary> /// Создает ответ в виде фрагмента HTML /// </summary> /// <param name="text">HTML текст</param> /// <returns></returns> 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 /// <summary> /// Хак для JQuery UI /// </summary> [HttpGet] [Route("images/{id}")] [Route("api/web/images/{id}")] public HttpResponseMessage Images(HttpRequestMessage request, [FromUri]string id) { return CreateImageResponse(request, id); } /// <summary> /// Выполняет поиск и возврат в качестве ответа ресурса сайта, /// javascript, css файла или файла с изображением /// </summary> /// <param name="request">Запрос</param> /// <returns>Ответ</returns> [HttpGet] [Route("api/web/resources")] public HttpResponseMessage GetResource(HttpRequestMessage request) { return _GetResource(request); } #endregion } }