惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Jina AI
Jina AI
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
P
Privacy & Cybersecurity Law Blog
SecWiki News
SecWiki News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
Engineering at Meta
Engineering at Meta
Hugging Face - Blog
Hugging Face - Blog
PCI Perspectives
PCI Perspectives
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
The Exploit Database - CXSecurity.com
博客园_首页
Latest news
Latest news
T
Threat Research - Cisco Blogs
N
News and Events Feed by Topic
TaoSecurity Blog
TaoSecurity Blog
罗磊的独立博客
月光博客
月光博客
C
Cisco Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
V2EX
Last Week in AI
Last Week in AI
Cloudbric
Cloudbric
MyScale Blog
MyScale Blog
Spread Privacy
Spread Privacy
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
P
Proofpoint News Feed
G
GRAHAM CLULEY
N
News and Events Feed by Topic
MongoDB | Blog
MongoDB | Blog
N
Netflix TechBlog - Medium
M
MIT News - Artificial intelligence
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
人人都是产品经理
人人都是产品经理
K
Kaspersky official blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
量子位
I
Intezer
Microsoft Azure Blog
Microsoft Azure Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
A
About on SuperTechFans
D
DataBreaches.Net
宝玉的分享
宝玉的分享
S
Security @ Cisco Blogs
Help Net Security
Help Net Security
Hacker News - Newest:
Hacker News - Newest: "LLM"

博客园 - I,Robot

短网址的简单实现 怎样在前端Javascript中调用C#方法(4)验证授权 怎样在前端Javascript中调用C#方法(2)传递参数(附源码+高手勿入) 怎样在前端Javascript中调用C#方法(1)简单实现(附源码) 闲来无事,写了段js仿google首页动画,附源码下载 终于请了个客服值夜班了,嘿嘿,不是18K月薪 我的编程之路 说再见的那一刻,我都不敢回头多看你们一眼… 终于解决了”SQL多表连接查询C#化”这的问题 趣味算法:国王和100个囚犯(据说是腾讯的面试题) 提交备案申请4年后,网站备案号终于下来了,可惜网站跟域名早已不见了 我的山寨HTC(5)-电池 我的山寨HTC(4)-U盘 我的山寨HTC(3)-WIFI 我的山寨HTC(2)-GPS 我的山寨HTC(1)-购机 eBay中国上海总部之行20091020 eBay中国2009开发者论坛上海之行 在一个没有爱心的城市,谈何文明,谈何和谐
怎样在前端Javascript中调用C#方法(3)使用特性Attribute
I,Robot · 2012-03-09 · via 博客园 - I,Robot

为什么要这样做?对比其它实现方式的优势?

有不少朋友问到这些问题,所以这篇先把这两个问题先解释一下。后台处理Ajax请求无论使用aspx、asmx、ashx、还是IHttpHandler来处理,情况都跟下面差不多:

//aspx、asmx、ashx、IHttpHandler中的方法
public string GetMemberName(int id){
return new Member().GetMemberName(id);
}

public class Member{
public string GetMemberName(int id){
//do something with id;
return memberName;
}
}

也就是说,无论我们使用哪种实现,基本上都是一个转接,将接收到的请求转接到对应的业务类中处理(除非您的项目不介意业务代码分散在aspx、asmx、ashx、IHttpHandler等各个角落)。
而文章中提出的这种方法,就是希望能够创建一个中间代理将请求直接转接到业务类的方法上,只需要在业务类中定义好方法,前端就可以直接通过指定的链接调用,不需要再去定义一个aspx或ashx。
接下来再来介绍这篇文章我们要实现的内容。

为什么要这使用特性Attribute?

上篇文章中有朋友回复说接收的参数只支持Form提交的数据,能不能加上QueryString?当然是可以的,所以我们在这里引入了特性Attribute,用来解决传入参数的取值问题。
为了方便以后的扩展,我们首先定义了一个抽象类ParameterAttribute。

定义ParameterAttribute:

[AttributeUsage(AttributeTargets.Parameter)]
public abstract class ParameterAttribute : Attribute {

public object DefaultValue { get; set; }

public string Name { get; set; }

public ParameterAttribute() { }

public ParameterAttribute(string name, object defaultValue) {
Name = name;
DefaultValue = defaultValue;
}

public virtual object GetValue(System.Web.HttpContext context, Type parameterType) {
object value = GetParameterValue(context) ?? DefaultValue;
if (parameterType.FullName == "System.String") {
return value;
}
if (value.GetType().FullName == "System.String") {
if (string.IsNullOrEmpty((string)value)) {
value = DefaultValue;
}
}
return Convert.ChangeType(value, parameterType);
}

public abstract object GetParameterValue(System.Web.HttpContext context);
}

ParameterAttribute类继承自Attribute,并且限定了该类只能应用到参数上。同时还定义了一个属性DefaultValue,一个抽象方法GetParameterValue,有的朋友可能会问为什么DefaultValue不用泛型实现,原因是继承自Attribute的类不能使用泛型。
下面我们再定义一个FormAttribute来处理通过Form方式提交的参数。

定义FormAttribute:

public class FormAttribute : ParameterAttribute {

public FormAttribute() { }

public FormAttribute(string name) : base(name, null) { }

public FormAttribute(string name, object defaultValue) : base(name, defaultValue) { }

public override object GetParameterValue(System.Web.HttpContext context) {
return context.Request.Form[Name];
}
}

实际上这个类的定义很简单,仅仅是返回一个Request.Form中的值而已,既然如此,那QueryString实现起来也是一件很简单的事情了,复制代码改改名称得到QueryStringAttribute:

定义QueryStringAttribute:

public class QueryStringAttribute : ParameterAttribute {

public QueryStringAttribute() { }

public QueryStringAttribute(string name) : base(name, null) { }

public QueryStringAttribute(string name, object defaultValue) : base(name, defaultValue) { }

public override object GetParameterValue(System.Web.HttpContext context) {
return context.Request.QueryString[Name];
}
}

修改后的Factory.Execute方法:

void Execute(HttpContext context) {
//根据请求的Url,通过反射取得处理该请求的类
string url = context.Request.Url.AbsolutePath;
string[] array = url.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string typename = "Biz";
for (int x = 1; x < array.Length - 1; x++) {
typename += "." + array[x];
}
Type type = this.GetType().Assembly.GetType(typename, false, true);
if (type != null) {
//取得类的无参数构造函数
var constructor = type.GetConstructor(new Type[0]);
//调用构造函数取得类的实例
var obj = constructor.Invoke(null);
//查找请求的方法
var method = type.GetMethod(System.IO.Path.GetFileNameWithoutExtension(url));
if (method != null) {
var parameters = method.GetParameters();
object[] args = null;
if (parameters.Length > 0) {
args = new object[parameters.Length];
for (int x = 0; x < parameters.Length; x++) {
var parameterAttr = (Attribute.GetCustomAttribute(parameters[x], typeof(ParameterAttribute)) as ParameterAttribute) ?? new FormAttribute();
parameterAttr.Name = parameterAttr.Name ?? parameters[x].Name;
args[x] = parameterAttr.GetValue(context, parameters[x].ParameterType);
}
}
//执行方法并输出响应结果
context.Response.Write(method.Invoke(obj, args));
}
}
}

仅仅是比上次示例的代码多了两行而已。在没有定义ParameterAttribute的情况下默认使用FormAttribute。
为了方便演示代码,我们修改了Javascript代码。

修改后的前端Javascript代码:

$(function () {
//绑定按钮点击事件
$("#btnAction").click(function () {
$.post("/Ajax/News/Plus.aspx?y=" + $("input[name='y']").val() + "&num3=" + $("input[name='z']").val(), { x: $("input[name='x']").val() }, function (txt) {
$("#result").val(txt);
}, "text");
});
});

上面可以看到,我们为了演示参数可以取别名,将参数z修改成了num3,Html代码也稍作修改。

修改后的前端Html代码:

<input type="text" name="x" value="1" class="txt" />
<input type="button" disabled="disabled" value="+" class="txt btn" />
<input type="text" name="y" value="2" class="txt" />
<input type="button" disabled="disabled" value="+" class="txt btn" />
<input type="text" name="z" value="" class="txt" />
<input id="btnAction" type="button" value="=" class="txt btn" />
<input type="text" readonly="readonly" id="result" class="txt" />

运行示例后,即可看到我们想要的效果了。至此,我们就已经解决了支持参数从QueryString取值的问题,同时还可以实现扩展从其它方式取值,比如:Cookie、Session、Application、甚至Database,这里我就不再一一实现了,有兴趣的朋友不妨自已动手试试?

示例项目源代码:

几天篇文章都是半夜整理的,还要附带写示例代码,觉得有帮助的朋友不妨点下推荐给点鼓励,谢谢!

未完待续...