• 解决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解析的话,那就很麻烦了

  • 相关阅读:
    P3350 [ZJOI2016]旅行者
    P4178 Tree
    P2375 [NOI2014]动物园
    P2827 蚯蚓
    1002: [FJOI2007]轮状病毒
    1070: [SCOI2007]修车
    AtCoder Grand Contest 021完整题解
    Running to the End(Codeforces & AtCoder 百套计划)
    SDWC2017游记
    非传统题初探——AtCoder Practice Contest #B
  • 原文地址:https://www.cnblogs.com/rbzz/p/14355431.html
Copyright © 2020-2023  润新知