具有跨域 Ajax 的 WCF Web 服务不起作用

Posted

技术标签:

【中文标题】具有跨域 Ajax 的 WCF Web 服务不起作用【英文标题】:WCF web service with CROSS Domian Ajax not working 【发布时间】:2018-04-12 11:29:45 【问题描述】:

使用 jsonp 调用 WCF Ajax 请求时出现错误 下面是我的 web.config

<?xml version="1.0"?>
<configuration>


  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour">
        <endpoint address="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web"></endpoint>
        <endpoint address="basic" binding="basicHttpBinding" name="HttpEndPoint" contract="RestService.IRestServiceImpl" ></endpoint>

        <endpoint
            address="Service1.svc"
            binding="mexHttpBinding"
            contract="IMetadataExchange"/>
      </service>
    </services>

    <behaviors>

      <serviceBehaviors>
        <behavior name="ServiceBehaviour">
          <!-- To avoid disclosing metadata information, set the value below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>

        </behavior>

      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
    </bindings>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

还有我的界面

 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using System.Text;

    namespace RestService
    
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IRestServiceImpl" in both code and config file together.
        [ServiceContract]
        public interface IRestServiceImpl
        


            [WebInvoke(Method = "GET",
                ResponseFormat = WebMessageFormat.Json,
                BodyStyle = WebMessageBodyStyle.Wrapped,
                UriTemplate = "getallemp")]
            [return: MessageParameter(Name = "success")]
            string GetAllEmployee();




        
    

以下是我的服务类

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using WebService.DataLayer;

namespace RestService


    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "RestServiceImpl" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select RestServiceImpl.svc or RestServiceImpl.svc.cs at the Solution Explorer and start debugging.
    public class RestServiceImpl : IRestServiceImpl
    

        public string GetAllEmployee()
        
            cls_datalayer obj = new cls_datalayer();
            DataTable dt = obj.getDataTableFromQuery("select usercode from users where empstatus='A'");

            return ConvertDataTabletoString(dt);
        

        public string ConvertDataTabletoString(DataTable dt)
        
            System.Web.Script.Serialization.javascriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            serializer.MaxJsonLength = 50000000;
            List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
            Dictionary<string, object> row;
            foreach (DataRow dr in dt.Rows)
            
                row = new Dictionary<string, object>();
                foreach (DataColumn col in dt.Columns)
                
                    row.Add(col.ColumnName, dr[col]);
                
                rows.Add(row);
            

            return serializer.Serialize(rows);
        




    

当我从浏览器调用它时,它会给出From Browser

但是当我使用跨域从 Ajax 请求中尝试这个时,我得到了错误

$.ajax(
                type: "GET",
                url: 'http://localhost:59672/RestServiceImpl.svc/getallemp',
                contentType: "application/json",
                dataType: "jsonp",
                cache: false,
                jsonpCallback: 'callback',
                success: function (data) 
                    alert();

                ,
                error: function (xhr) 
                    //console.log(xhr);
                    var err = eval("(" + xhr.responseText + ")");

                
            );

然后我收到错误请检查附件Attachment 01

Attachment 02

【问题讨论】:

【参考方案1】:

对我来说比 Web.config 版本更好:

创建Global.asax

将此代码添加到Global.asax.cs

protected void Application_BeginRequest(object sender, EventArgs e)

    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin" , "*");
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    
        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();
    

【讨论】:

以上是关于具有跨域 Ajax 的 WCF Web 服务不起作用的主要内容,如果未能解决你的问题,请参考以下文章