zoukankan      html  css  js  c++  java
  • 怎样在前端Javascript中调用C#方法(3)使用特性Attribute

    为什么要这样做?对比其它实现方式的优势?
    有不少朋友问到这些问题,所以这篇先把这两个问题先解释一下。后台处理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,这里我就不再一一实现了,有兴趣的朋友不妨自已动手试试?
    示例项目源代码:
    几天篇文章都是半夜整理的,还要附带写示例代码,觉得有帮助的朋友不妨点下推荐给点鼓励,谢谢!

    未完待续...
  • 相关阅读:
    MM-RGV、AGV 、IGV是什么
    WDA-FPM-4-用OVP做查询跳转到明细
    WDA-FPM-3-SEARCH(OIF)
    WDA-FPM-2-APPLICATION-TABSTRIP(OIF)
    WDA-FPM-1-Roadmap(GAF)
    WDA-BOPF业务对象处理框架
    WDA-WebDynpro Demo & FPM Demo
    WDA-参考路径
    MM-库存表
    洗礼灵魂,修炼python(12)--python关键词,包
  • 原文地址:https://www.cnblogs.com/robot/p/2386083.html
Copyright © 2011-2022 走看看