解决WCF跨域问题,及DataTable参数问题

上一篇章配置了如何可以使用http方式调用wcf,在C#代码中可以使用HttpClient,HttpWebRequest等web类进行请求

但是如果直接使用js发送ajax请求的时候却会出现跨域问题

首先是web.config中的system.serviceModel节点配置

如下:

 <system.serviceModel>
    <services>
      <service name="WcfService.ServiceAjax">
        <endpoint address="" behaviorConfiguration="WcfService.ServiceAjaxAspNetAjaxBehavior" 
          binding="webHttpBinding" contract="WCFlib.IClass" bindingConfiguration="webBinding"/>
          
      </service>
    </services>

    <bindings>
      <webHttpBinding>
        <binding name="webBinding" crossDomainScriptAccessEnabled="true" >
         
        </binding>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="WcfService.ServiceAjaxAspNetAjaxBehavior"  >
          <webHttp automaticFormatSelectionEnabled="true" defaultBodyStyle="Wrapped" helpEnabled="true" 
                   defaultOutgoingResponseFormat="Json" faultExceptionEnabled="true"/>
            <!--<enableWebScript/> 这一个不能要,否则就不能使用ref或out参数了-->
            <dataContractSerializer ignoreExtensionDataObject="true"/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
      <add binding="basicHttpsBinding" scheme="http" />
      <add binding="webHttpBinding" scheme="https"/>
      <add binding="webHttpBinding" scheme="http"/>
        
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

主要的配置在service的endpoint里面的behaviorConfiguration,关于配置文件的详解,请查看上一篇

然后在wcf项目中添加一个全局配置文件

 

 在里面的Application_BeginRequest方法中写入

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
            if (HttpContext.Current.Request.HttpMethod != "OPTIONS") return;
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
            HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
            HttpContext.Current.Response.End();
        }

之后就可以使用了,当然,契约接口和契约实现类,也请参照上一篇章 

让WCF支持Http调用

下面是调用的html文件

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <script crossorigin="anonymous" integrity="sha512-WNLxfP/8cVYL9sj8Jnp6et0BkubLP31jhTG9vhL/F5uEZmg5wEzKoXp1kJslzPQWwPT1eyMiSxlKCgzHLOTOTQ==" src="https://lib.baomitu.com/jquery/3.5.1/jquery.js"></script>
    <script>
        $(function () {
            $('#btn').click(function () {
                $.ajax({
                    url: 'http://localhost:15500/ServiceAjax.svc/TestModel',
                    type:'POST',
                    data: '{\"name\":\"aaa\"}',
                    async: false,
                    dataType: "json",
                    Accept:'*/*',
                    contentType: 'application/json',
                    success: function (data) {
                        console.log(data)
                    },
                    error: function (data) {
                        console.log(data)
                    }
                }

                )
            })
        })
    </script>
</head>
<body>
    <button id="btn">Get</button>
</body>
</html>

下面是成功的截图

 

 

==========================

关于DataTable的参数问题

如果有是out类的则无须管

但如果是入参,例如以下方法

 public string ParamterTable(DataTable table)
        {
            return "传递成功";
        }

传递table的时候,应该如下传递 首先封装成一个json,然后DataTable的数据,需要是一个xml文档

 

该文档如下所示

<!--命名空间为固定的,必须如此,表示此处是一个DataTable类型-->
<DataTable xmlns=\"http://schemas.datacontract.org/2004/07/System.Data\">
    <!--schema定义DataTable的架构-->
    <xs:schema id=\"NewDataSet\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">
        <xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"table\" msdata:UseCurrentLocale=\"true\">
            <xs:complexType>
                <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">
                    <xs:element name=\"table\">
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name=\"ID\" type=\"xs:string\" minOccurs=\"0\"/>
                                <xs:element name=\"Name\" type=\"xs:string\" minOccurs=\"0\"/>
                            </xs:sequence>
                        </xs:complexType>
                    </xs:element>
                </xs:choice>
            </xs:complexType>
        </xs:element>
    </xs:schema>
    <!--定义DataTable的内容-->
    <diffgr:diffgram xmlns:diffgr=\"urn:schemas-microsoft-com:xml-diffgram-v1\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">
        <DocumentElement xmlns=\"\">
            <!--table为此DataTable的名称,下面就是每一行的数据-->
            <!--注意diffgr:hasChanges特性,此处可取值 
            modified 表示该行已修改
            inserted 表示该行为新添加-->
            
            <table diffgr:id=\"table1\" msdata:rowOrder=\"0\" diffgr:hasChanges=\"modified\">
                <ID>0</ID>
                <Name>33</Name>
            </table>
            <table diffgr:id=\"table3\" msdata:rowOrder=\"2\">
                <ID>2</ID>
                <Name>3</Name>
            </table>
            <table diffgr:id=\"table4\" msdata:rowOrder=\"3\">
                <ID>3</ID>
                <Name>4</Name>
            </table>
            <table diffgr:id=\"table5\" msdata:rowOrder=\"4\">
                <ID>4</ID>
                <Name>5</Name>
            </table>
            <table diffgr:id=\"table6\" msdata:rowOrder=\"5\" diffgr:hasChanges=\"inserted\">
                <ID>1</ID>
                <Name>2</Name>
            </table>
        </DocumentElement>
        <!--此处为已经被删除的行标识 before表示该行之前的状态-->
        <diffgr:before>
            <!--表示将原有下标为1的行删除了,注意看上面没胡rowOrder=1的数据-->
            <table diffgr:id=\"table1\" msdata:rowOrder=\"0\" xmlns=\"\">
                <ID>0</ID>
                <Name>1</Name>
            </table>
            <!--然后将之前第第二行下标为2的数据放到下标1上,而上面其实还将下标进行了升级-->
            <table diffgr:id=\"table2\" msdata:rowOrder=\"1\" xmlns=\"\">
                <ID>1</ID>
                <Name>2</Name>
            </table>
        </diffgr:before>
    </diffgr:diffgram>
</DataTable>

 

这是方法调用截图示例

 

 

总的来说,DataTable的参数传递和解析都是很麻烦的,如果是C#代码还好,解析和封装都不算困难,但如果是JS解析的话,那就很麻烦了

 

posted @ 2021-02-01 10:41  人不自在  阅读(335)  评论(2编辑  收藏  举报