程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 怎樣在前端Javascript中調用C#方法(3)使用特性Attribute

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

編輯:C#入門知識

上一篇:http://www.BkJia.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 () {
    //綁定按鈕點擊事件
    $("#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,這裡我就不再一一實現了,有興趣的朋友不妨自已動手試試?
示例項目源代碼:
點擊下載
幾天篇文章都是半夜整理的,還要附帶寫示例代碼,覺得有幫助的朋友不妨點下推薦給點鼓勵,謝謝!

未完待續...

 

摘自 狼Robot 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved