当前位置:编程学习 > JAVA >>

怎样在前端Javascript中调用C#方法(3)使用特性Attribute

上一篇:http://www.zzzyk.com/kf/201203/122299.html 

为什么要这样做?对比其它实现方式的优势?
有不少朋友问到这些问题,所以这篇先把这两个问题先解释一下。后台处理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 () {补充:软件开发 , C# ,

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,