warensoft 我是科学家

Warensoft 我是科学家

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

Javascript 调用自宿主WCFinvoke self hosted wcf from js/ajax)

ASP.NetMS已经集成了WCF方式的WebService,这样利用Ajax Enabled WCf就可以轻松的实现JS调用WCf功能。

但是在某些特定环境下(例如WebGame后台服务器程序)我们需要利用JS直接调用非IIS宿主的WCF服务,如果你Google过,就会发现在网上找到的大多数方案都是利用ASP.NET充当一个代理(先利用ASP.NET调用一次,再在ASP.NET网站中封装一下,以便JS调用)。这样做的好处是可以解决跨域访问的问题,并且调用起来也挺简单的。

下面,我们通过实例来说明如何利用JS直接调用非IIS宿主的WCFJS调用WCF无非要解决两个问题,1.如何获取JS代理类,2.如何解决跨域问题。今天主要解决第1个问题,关于跨域问题会在后面的文章中加以解决(利用JSONP)。

1.        建立一个自宿主WCFself hosted wcf

建立一个WCf服务器,其中包括一个函数,如下所示:

namespace WCFTest

{

    [ServiceContract]

    public interface IService1

    {

        [OperationContract]

        string GetHello(string uid);

    }

    public class Service1 : IService1

    {

 

        #region IService1 Members

 

        public string GetHello(string uid)

        {

            return "hello " + uid;

        }

 

        #endregion

    }

}

2.        在一个Windows窗口程序中启动该服务器,代码如下:

private void Form1_Load(object sender, EventArgs e)

        {

            ServiceHost host = new ServiceHost(typeof (Service1));

            host.Open();

        }

 

3.        App.config中查看该WCF的网址,并运行主程序

4.        在浏览器打开WCF的网站,如下图所示:

 

height=345

 

大家知道,如果在ASP.NET中添加WCF模板,IDE会自动为我们生成一个svc文件,而JS的代理类正是通过这个SVC文件得到的,但是在刚才生成的WCF中是无法得到SVC文件以及JS的代理类的,这样就无法被JS所调用,如何解决呢?让我们先来看一下在ASP.NET中添加了一个WCF后,Web.Config是如何配置的,如下所示:

<system.serviceModel>

        <behaviors>

            <endpointBehaviors>

                <behavior name="ServiceAspNetAjaxBehavior">

                    <enableWebScript />

                behavior>

            endpointBehaviors>

        behaviors>

        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"

            multipleSiteBindingsEnabled="true" />

        <services>

            <service name="Service">

                <endpoint address="" behaviorConfiguration="ServiceAspNetAjaxBehavior"

                    binding="webHttpBinding" contract="Service" />

            service>

        services>

    system.serviceModel>

关键就在于该服务绑定了webHttpBinding,并且在其行为中(ServiceAspNetAjaxBehavior启用了EnableWebScript

再看一下刚才那个WCF程序的App.Config文件,如下所示:

<system.serviceModel>

        <behaviors>

            <serviceBehaviors>

                <behavior name="">

                    <serviceMetadata httpGetEnabled="true" />

                    <serviceDebug includeExceptionDetailInFaults="false" />

                behavior>

            serviceBehaviors>

        behaviors>

        <services>

            <service name="WCFTest.Service1">

                <endpoint address="" binding="wsHttpBinding" contract="WCFTest.IService1">

                    <identity>

                        <dns value="localhost" />

                    identity>

                endpoint>

                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

                <host>

                    <baseAddresses>

                        <add baseAddress="http://localhost:8732/Design_Time_Addresses/WCFTest/Service1/" />

                    baseAddresses>

                host>

            service>

        services>

    system.serviceModel>

并不难发现该WCF服务使用的是wsHttpBinding, 参照ASP.NET中的WCf将该WCF的配置文件进行修改,修改后如下所示:

<system.serviceModel>

        <behaviors>

          <endpointBehaviors  >

            <behavior name ="MyBehavior">

              <enableWebScript/>

            behavior>

          endpointBehaviors>

            <serviceBehaviors>

                <behavior name="">

                    <serviceMetadata httpGetEnabled="true" />

                    <serviceDebug includeExceptionDetailInFaults="false" />

                behavior>

            serviceBehaviors>

        behaviors>

        <services>

            <service name="WCFTest.Service1">

                <endpoint address="" binding="wsHttpBinding" contract="WCFTest.IService1">

                    <identity>

                        <dns value="localhost" />

                    identity>

                endpoint>

            < contract="WCFTest.IService1" binding="webHttpBinding">

                        address ="http://localhost/WCFTest"

                         behaviorConfiguration ="MyBehavior"

                        >

                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

                <host>

                    <baseAddresses>

                        <add baseAddress="http://localhost:8732/Design_Time_Addresses/WCFTest/Service1/" />

                    baseAddresses>

                host>

            service>

        services>

注意,这里是添加了一个EndPoint,并将其使用的协议设置为WebHttpBinding(如加粗位置所示),当然这里也体现出WCF可以多协议绑定的方便之处。

现在可以尝试启动该WCF服务了,启动之后,输入如下网址:http://localhost/WCFTest/js,浏览器便会提示下载一个JS文件(没有扩展名的),如下图所示:

 

height=224

 

有了前面的准备,我们就可以在相同的域内(IP相同,端口也要相同)访问非IISWCF了。过程如下:

1.        寻立一个ASP.NET网站

2.        在页面中添加一个ScriptManager,基代码如下:

<asp:ScriptManager ID="ScriptManager1" runat="server">

            <Scripts>

                <asp:ScriptReference Path="http://localhost/WCFTest/js" />

            Scripts>

        asp:ScriptManager>

3.        添加JS代码以及HTML代码来完善功能

页面代码如下所示:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

 

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>title>

    <script language="javascript" type="text/javascript">

//

 

        function Button1_onclick() {

            var userName = $get("Text1").value;

            tempuri.org.IService1.GetHello(userName, function (result) {

                alert(result );

            });

        }

 

// ]]>

    script>

head>

<body>

    <form id="form1" runat="server">

    <div>

        <asp:ScriptManager ID="ScriptManager1" runat="server">

            <Scripts>

                <asp:ScriptReference Path="http://localhost/WCFTest/js" />

            Scripts>

        asp:ScriptManager>

        <input id="Text1" type="text" /><input id="Button1" type="button"

            value="button" onclick="return Button1_onclick()" />div>

    form>

body>

html>

 

4.        运行结果,如下所示:

 

height=302

posted on 2010-03-07 19:45  王宇 warensoft  阅读(1612)  评论(0编辑  收藏  举报