• 使用WC“.NET研究”F实现SOA面向服务编程——使用AJAX+WCF服务页面开发 狼人:


      在上一篇讲到,如果将BLL层的每一个类都转化为*.svc,这是一个不实在的想法。它会使服务变化复杂,难于管理。

      这时候,我们第一时间想到的是23个简单开发模式中的Factory,在这里,Factory正好派上用场。我们把这个Factory称之为管道(pipeline) ,通过这个管道客户端可以随意调用服务器BLL层里面的类。

      (关于管道的概念,建议参考Cory Isaacson的杰作《多核应用架构关键技术—软件管道与soa》)

      当你使用B/S方式开发UI层时,只要了解此开发模式,使用Ajax加上WCF里面的WebHttpBinding绑定和WebHttpBehavior行为,可以说是天衣无缝的组合。

      首先,开发一个数据契约,其中包括程序集名称,类名,构造函数的参数,方法名,方法中的参数:

    [DataContract]
    public class Communication
    {
    [DataMember]
    public string Assembly
    {
    get;
    set;
    }
    [DataMember]
    public string Class
    {
    get;
    set;
    }
    [DataMember]
    public object[] ConstructedParameters
    {
    get;
    set;
    }
    [DataMember]
    public string Method
    {
    get;
    set;
    }
    [DataMember]
    public object[] Parameters
    {
    get;
    set;
    }
    }

      为了证明客户端可以通过Ajax能够直接调用服务器WCF,我们先开发一个MyAssembly程序集:

    namespace MyAssembly
    {

    [DataContract]
    public class User
    {
    [DataMember]
    public int ID
    {
    get; set; }

    [DataMember]
    public string Name
    {
    get; set; }

    [DataMember]
    public int Age
    {
    get; set; }
    }

    public class UserManager
    {
    public List<User> GetList()
    {
    List
    <User> entities = new List<User>();
    User user
    = new User();
    user.ID
    = 0;
    user.Age
    = 26;
    user.Name
    = "Leslie";
    entities.Add(user);
    return entities;
    }
    }
    }

      好,现在已经做好准备,现在我们新建一个“启动了AJAX的WCF服务”:

    [ServiceContract(Namespace = "myNamespace")]
    [AspNetCompatibilityRequirements(RequirementsMode
    = AspNetCompatibilityRequirementsMode.Allowed)]

    //注意必须将RequirementsMode设置为AspNetCompatibilityRequirementsMode.Allowed

    public class Service
    {
    private static Hashtable assemblies = new上海网站建设n style="color: #000000;"> Hashtable();
    private static Hashtable types = new Hashtable();

    [OperationContract]
    [WebGet]

    // 要使用 HTTP GET,请添加 [WebGet] 特性。
    public string DoWork(Communication communication)
    {
    Type classType
    = GetType(communication); //通过自定义的GetType(Communicate o)方法加载类

    if (classType != null) //下面将利用反射原理创建类对象
    {
    object reflectedObject;
    if (communication.ConstructedParameters != null)
    reflectedObject
    = Activator.CreateInstance(classType, communication.ConstructedParameters);
    else
    reflectedObject
    = Activator.CreateInstance(classType);

    MethodInfo methodInfo
    = classType.GetMethod(communication.Method); //获取方法信息

    if (methodInfo != null)
    {
    object data = methodInfo.Invoke(reflectedObject, communication.Parameters); //调用方法
    if (data != null)
    return Formate(data, methodInfo.ReturnType); //将结果转化为JSON
    else
    return null;
    }
    else
    return null;
    }

    return null;
    }

    //因为结果供于Ajax页面使用,所以将结果转化为Json形式
    //其实当项目已经启动AJAX,在默认情况下结果会自动转化为JSON,但因为不能事先预知返回的类型,所以把返回类型定为String
    //此处手动将结果转换成JSON字符串
    public string Formate(object data,Type type)
    {
    using (Stream stream = new MemoryStream())
    {
    DataContractJsonSerializer jsonSerializer
    = new Data上海企业网站制作ContractJsonSerializer(type);
    jsonSerializer.WriteObject(stream, data);
    byte[] byteData = new byte[stream.Length];
    stream.Seek(
    0,0);
    stream.Read(byteData,
    0, (int)stream.Length);
    stream.Close();
    return Encoding.UTF8.GetString(byteData);
    }
    }

    //加载程序集 
    private Assembly GetAssembly(Communication communication)
    {
    if (!assemblies.ContainsKey(communication.Assembly))
    {
    Assembly myAssembly
    = Assembly.Load(communication.Assembly);
    assemblies.Add(communication.Assembly, myAssembly);
    }
    return (Assembly)assemblies[communication.Assembly];
    }
    //加载类
    private Type GetType(Communication communication)
    {
    if (!types.ContainsKey(communication.Class))
    {
    Assembly assembly
    =GetAssembly(communication);
    types.Add(communication.Class, assembly.GetType(communication.Class));
    }
    return (Type)types[communication.Class];
    }
    }

      服务器端会自动为你配置.config文件:

    <system.serviceModel>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
      <behaviors>
        <endpointBehaviors>
        <behavior name="ServiceAspNetAjaxBehavior">
        <enableWebScript /> //注意启动enableWebScript
      </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true" /> //注意此处启动了httpGetEnabled
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
      <services>
      <service name="Service" behaviorConfiguration="ServiceBehavior">
        <endpoint address="" behaviorConfiguration="ServiceAspNetAjaxBehavior"
    binding
    ="webHttpBinding " contract="Service" /> //注意绑定的是webHttpBinding
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
      </services>
      </system.serviceModel>
    </configuration>

      好吧,现在万事俱备的时候,让我们开发一个测试页面:

    <body>
    <form id="form1" runat="server">
    <script type="text/javascript">
    window.onload
    = function () {
    myNamespace.Service.set_path(
    "http://localhost:8080/Service.svc/");
    var communication = { "Assembly": "MyAssembly", "Class": "MyAssembly.UserManager",
            "
    ConstructedParameters": null, "Method": "GetList", "Parameters": null };

    //把Communication参数转化为Json形式
    myNamespace.Service.DoWork(communication, OnSucceed, OnFail, null);
    }
    function上海闵行企业网站制作yle="background-color: #f5f5f5; color: #000000;"> OnSucceed(result) {
    if (result != null)
    alert(result);
    }
    function OnFail(result) {
    alert(result);
    }
    上海徐汇企业网站设计与制作
    </script>
    </form>
    </body>

      测试成功:

      恭喜你终于学会如何使用Ajax+WCF进行页面数据显示了。

      你应该初步了解到如何使用管道Pipeline进行客户端与服务器端的通讯,自此之后,每逢你进行简单的页面开发时都可使用此方式。好处在于页面无 需了解数据是从何处获取的,因为数据存取和页面可以处于不同的线程池,所以这样做可以把服务器压力降到最低。同时你可以使用异步的服务,来进一步提高数据 站点的线程池效率。(异步服务可参考ASP.NET服务器端多线程设计

    声明:此博有部分内容为转载,版权归原作者所有~
  • 相关阅读:
    Spring基于注解的事务控制
    Spring基于配置的事务控制
    Spring基于注解配置AOP
    字符串构造,思维
    DP
    线段树二分
    计算机组成原理
    Graph Attention Networks (GAT) 代码解读
    Python 列表与字典
    2.运算方法和运算器
  • 原文地址:https://www.cnblogs.com/waw/p/2218080.html
Copyright © 2020-2023  润新知