美文网首页
ashx简单封装

ashx简单封装

作者: Mrgz | 来源:发表于2019-07-29 12:29 被阅读0次

    由于看不惯大批量的ashx
    慢慢改着不自觉的就像WebApi了
    webform与webapi可以混用,参考Microsoft.Owin,但这里的只是小改ashx

    特殊性:原来的ashx只用到了Post,数据交互用json

    使用样例

    
    /* file Hello.ashx
    * 调用方式
    * url: http://xxxx/Hello.ashx?Action=SayHello
    * method:POST
    * content-type:application/json
    * data:{"name":"Jack"}
    */
    
    public class Req
    {
        public string name;
    }
    
    public class Hello:RBaseAshx 
    {
        [RAction]
        public object SayHello(string name)
        {
            return "Hello,"+name;
        }
    
        [RAction]
        public object SayHello2(Req req)
        {
            return "Hello,"+req.name;
        }
    }
    
    
    

    实现方法,原来的代码比较乱,下面的代码从原来的restfull风格临时删减而来,仅供参考

    public class RErr
    {
        public int code { get; set; }
        public string msg { get; set; }
        public static RErr Error(int code, string msg)
        {
            return new RErr() { code = code, msg = msg };
        }
        public static RErr NError(string msg)
        {
            return new RErr() { code = 0, msg = msg };
        }
        public static RErr Err400 { get { return new RErr() { code = 404, msg = "BAD REQUEST" }; } }
        public static RErr Err401 { get { return new RErr() { code = 401, msg = "UNAUTHORIZED" }; } }
        public static RErr Err403 { get { return new RErr() { code = 403, msg = "FORBIDDEN" }; } }
        public static RErr Err404 { get { return new RErr() { code = 404, msg = "NOT FOUND" }; } }
        public static RErr Err500 { get { return new RErr() { code = 500, msg = "INTERNAL SERVER ERROR" }; } }
    }
    public class RException : Exception
    {
        public RErr Err { get; set; }
        public RException()
        {
    
        }
        public RException(string msg)
        {
            Err = RErr.NError(msg);
        }
        public static RException FromRErr(RErr err)
        {
            return new RException() { Err = err };
        }
    
    }
    
    public class RActionAttribute : Attribute
    {
    }
    
    public abstract class RBaseAshx : System.Web.IHttpHandler, System.Web.SessionState.IRequiresSessionState
    {
        private HttpServerUtility _server;
    
        public HttpServerUtility Server
        {
            get { return _server; }
            set { _server = value; }
        }
        private HttpRequest _request;
    
        public HttpRequest Request
        {
            get { return _request; }
            set { _request = value; }
        }
        private HttpResponse _response;
    
        public HttpResponse Response
        {
            get { return _response; }
            set { _response = value; }
        }
        private System.Web.SessionState.HttpSessionState _session;
    
        public System.Web.SessionState.HttpSessionState Session
        {
            get { return _session; }
            set { _session = value; }
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
        protected virtual void BeforeAct()
        {
    
        }
        protected virtual void AfterAct()
        {
    
        }
    
        public virtual object DispatchAction(string action)
        {
            var mi = this.GetType().GetMethod(action, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
            if (mi == null)
            {
                return RErr.Error(404, "Action not found");
            }
            var attrs = mi.GetCustomAttributes(false);
            foreach (var attr in attrs)
            {
                if (attr is RActionAttribute)
                {
                    var paramsInfo = mi.GetParameters();
                    if (paramsInfo.Length == 0)
                    {
                        return mi.Invoke(this, null);
                    }
                    else
                    {
                        byte[] input = Request.BinaryRead(Request.TotalBytes);
                        string json = System.Text.Encoding.UTF8.GetString(input);
    
                        if (paramsInfo.Length == 1
                            && paramsInfo[0].ParameterType.IsClass
                            && paramsInfo[0].ParameterType.Equals(typeof(string)))
                        {
                            var obj = Newtonsoft.Json.JsonConvert.DeserializeObject(json, paramsInfo[0].ParameterType);
                            return mi.Invoke(this, new object[] { obj });
                        }
                        else
                        {
                            var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(json);
                            var ps = new List<object>();
    
                            foreach (var p in paramsInfo)
                            {
                                if (obj.TryGetValue(p.Name,out Newtonsoft.Json.Linq.JToken v))
                                {
                                    ps.Add(v.ToObject(p.ParameterType));
                                }
                                else
                                {
                                    ps.Add(null);
                                }
                            }
                            return mi.Invoke(this, ps.ToArray());
                        }
    
                    }
                }
            }
            return RErr.Error(404, "Action not found");
        }
    
        public void ProcessRequest(HttpContext context)
        {
            Response = context.Response;
            Request = context.Request;
            Session = context.Session;
            Server = context.Server;
    
            object result;
            try
            {
                if (Request.QueryString["Action"] == null)
                {
                    result =  RErr.Err404;
                }
                else
                {
                    this.BeforeAct();
                    result = DispatchAction(Request.QueryString["Action"].ToString());
                    this.AfterAct();
                }
    
            }
            catch (RException e)
            {
                result = e.Err;
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    if (e.InnerException is RException)
                    {
                        result = ((RException)e.InnerException).Err;
                    }
                    else
                    {
                        result = RErr.Error(500, e.InnerException.Message);
                    }
                }
                else
                {
                    result = RErr.Error(500, e.Message);
                }
            }
    
            if (result is RErr)
            {
                this.ResponseJson(result);
            }
            else
            {
                this.ResponseJson(new { code = 200, data = result });
            }
        }
    
        protected virtual T RequestJson<T>() where T : class
        {
            T reqObj = null;
            try
            {
                byte[] input = Request.BinaryRead(Request.TotalBytes);
                string json = System.Text.Encoding.UTF8.GetString(input);
                reqObj = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json);
            }
            catch (Exception e)
            {
                throw new RException() { Err = RErr.Err400 };
            }
    
            if (reqObj == null)
            {
                throw new RException() { Err = RErr.Err400 };
            }
            return reqObj;
        }
        protected virtual void ResponseJson(object obj)
        {
            Response.ContentType = "application/json";
            Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(obj));
        }
    
    }
    

    相关文章

      网友评论

          本文标题:ashx简单封装

          本文链接:https://www.haomeiwen.com/subject/yazvrctx.html