Записки программиста, обо всем и ни о чем. Но, наверное, больше профессионального.

2013-11-05

ashx include

Есть в мире MS Windows такой веб-сервер, называется IIS. Для этого веб-сервера довольно удобно писать обработчики запросов, используя файлы типа ashx (generic handler). Несмотря на все усилия Микрософт, для написания таких обработчиков нет необходимости в Visual Studio. Хотя .Net используется, куда ж без него.

Типичный файл (load.ashx) выглядит примерно так:
<%@ WebHandler Language="C#" Class="load" Debug="true" %>

using System;
using System.IO;
using System.Web;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Web.Caching;

public class load: IHttpHandler {
    // Override the ProcessRequest method.
    public void ProcessRequest(HttpContext context) {
        var saveid = String.Empty;
        // only for GET method
        saveid = context.Request.QueryString["map"];
        var path =
            VUtils.storeconfFromJson(
                VUtils.loadConfig(
                    VUtils.storageConfigFilename(context))
            ).fileStoragePath;
        var fname = String.Format(@"{1}/map.{0}.js", saveid, path);
        context.Response.ContentType = "application/json";
        context.Response.ContentEncoding = Encoding.UTF8;
        context.Response.Write(string.Format("{{file: '{0}'}}", fname));
    }

    // Override the IsReusable property.
    public bool IsReusable {
        get { return false; }
    }
}
Из этого файла, для краткости, вырезан вспомогательный код, в частности класса «VUtils».

И вот тут я подхожу к главному. Как бы сделать так, чтобы повторно используемый код вынести в отдельный файл?
Хочу аналог директивы «include», как в C/C++.

Ответ неожиданно прост, хотя в интернетах и не находится: используй «CompilerOptions», Люк.

Пример. Выношу библиотеку кода в отдельный файл lib.cs:
using System;
using System.IO;
using System.Web;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Web.Caching;

public class VUtils {

    public class VStoreConfig {
        public string fileStoragePath { get; set; }
    }

    public static string computeSHA1Hash(string val) {
        if(val.Equals("")) { return ""; }
        byte[] data = System.Text.Encoding.UTF8.GetBytes(val);
        System.Security.Cryptography.SHA1 sha = new System.Security.Cryptography.SHA1Managed();
        byte[] res = sha.ComputeHash(data);
        return System.BitConverter.ToString(res).Replace("-", "").ToUpper();
    }

    public static string storageConfigFilename(HttpContext context) {
        return context.Server.MapPath("~/store.config");
    }

    private static object _lockobject = new object();

    public static string loadConfig(string fileName) {
        string config = string.Empty;
        lock(_lockobject) {
            if(System.IO.File.Exists(fileName)) {
                using(System.IO.StreamReader file = new System.IO.StreamReader(fileName)) {
                    config = file.ReadToEnd();
                }
            }
        }
        return config;
    }

    public static VStoreConfig storeconfFromJson(string confJson) {
        var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
        var cnf = jss.Deserialize<VStoreConfig>(confJson);
        return cnf;
    }
}

В обработчике запроса load.ashx меняю заголовок:
<%@ WebHandler Language="C#" Class="load" Debug="true" CodeBehind="lib.cs" CompilerOptions="c:\Inetpub\wwwroot\miniportal\store\lib.cs" %>

...
public class load: IHttpHandler {
... 
        var path =
            VUtils.storeconfFromJson(
                VUtils.loadConfig(
                    VUtils.storageConfigFilename(context))
            ).fileStoragePath;
...
И этого достаточно. В коде класса «load» я могу пользоваться классами из библиотеки lib.cs.

Для завершения картины, вот полный код другого обработчика, save.ashx:
<%@ WebHandler Language="C#" Class="store" Debug="true" CodeBehind="lib.cs" CompilerOptions="c:\Inetpub\wwwroot\miniportal\store\lib.cs" %>

using System;
using System.IO;
using System.Web;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Web.Caching;

public class store: IHttpHandler {

    // Override the ProcessRequest method.
    public void ProcessRequest(HttpContext context) {
        var jsonString = String.Empty;
        // only for POST method
        jsonString = context.Request.Form["map"];
        if(jsonString == null) { jsonString = ""; }
        var hash = VUtils.computeSHA1Hash(jsonString);

        var path =
            VUtils.storeconfFromJson(
                VUtils.loadConfig(
                    VUtils.storageConfigFilename(context))
            ).fileStoragePath;
        var fname = String.Format(@"{1}/map.{0}.js", hash, path);

        System.IO.File.WriteAllText(fname, jsonString);

        context.Response.ContentType = "application/json";
        context.Response.ContentEncoding = Encoding.UTF8;
        context.Response.Write(string.Format("{{sha1: '{0}'}}", hash));
    }

    // Override the IsReusable property.
    public bool IsReusable {
        get { return false; }
    }
}
Задача решена, принцип DRY не нарушен.

Пока неясно, как избавиться от указания полного пути к файлам в директиве CompilerOptions. Но пока это не сильно мешает.


original post http://vasnake.blogspot.com/2013/10/ashx-include.html

Комментариев нет:

Отправить комментарий

Архив блога

Ярлыки

linux (241) python (191) citation (186) web-develop (170) gov.ru (159) video (124) бытовуха (115) sysadm (100) GIS (97) Zope(Plone) (88) бурчалки (84) Book (83) programming (82) грабли (77) Fun (76) development (73) windsurfing (72) Microsoft (64) hiload (62) internet provider (57) opensource (57) security (57) опыт (55) movie (52) Wisdom (51) ML (47) driving (45) hardware (45) language (45) money (42) JS (41) curse (40) bigdata (39) DBMS (38) ArcGIS (34) history (31) PDA (30) howto (30) holyday (29) Google (27) Oracle (27) tourism (27) virtbox (27) health (26) vacation (24) AI (23) Autodesk (23) SQL (23) humor (23) Java (22) knowledge (22) translate (20) CSS (19) cheatsheet (19) hack (19) Apache (16) Manager (15) web-browser (15) Никонов (15) Klaipeda (14) functional programming (14) happiness (14) music (14) todo (14) PHP (13) course (13) scala (13) weapon (13) HTTP. Apache (12) SSH (12) frameworks (12) hero (12) im (12) settings (12) HTML (11) SciTE (11) USA (11) crypto (11) game (11) map (11) HTTPD (9) ODF (9) Photo (9) купи/продай (9) benchmark (8) documentation (8) 3D (7) CS (7) DNS (7) NoSQL (7) cloud (7) django (7) gun (7) matroska (7) telephony (7) Microsoft Office (6) VCS (6) bluetooth (6) pidgin (6) proxy (6) Donald Knuth (5) ETL (5) NVIDIA (5) Palanga (5) REST (5) bash (5) flash (5) keyboard (5) price (5) samba (5) CGI (4) LISP (4) RoR (4) cache (4) car (4) display (4) holywar (4) nginx (4) pistol (4) spark (4) xml (4) Лебедев (4) IDE (3) IE8 (3) J2EE (3) NTFS (3) RDP (3) holiday (3) mount (3) Гоблин (3) кухня (3) урюк (3) AMQP (2) ERP (2) IE7 (2) NAS (2) Naudoc (2) PDF (2) address (2) air (2) british (2) coffee (2) fitness (2) font (2) ftp (2) fuckup (2) messaging (2) notify (2) sharepoint (2) ssl/tls (2) stardict (2) tests (2) tunnel (2) udev (2) APT (1) CRUD (1) Canyonlands (1) Cyprus (1) DVDShrink (1) Jabber (1) K9Copy (1) Matlab (1) Portugal (1) VBA (1) WD My Book (1) autoit (1) bike (1) cannabis (1) chat (1) concurrent (1) dbf (1) ext4 (1) idioten (1) join (1) krusader (1) license (1) life (1) migration (1) mindmap (1) navitel (1) pneumatic weapon (1) quiz (1) regexp (1) robot (1) science (1) serialization (1) spatial (1) tie (1) vim (1) Науру (1) крысы (1) налоги (1) пианино (1)