由于看不惯大批量的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));
}
}
网友评论