WCF的角度XMLHttpRequest发布请求失败

时间:2019-06-02 21:20:30

标签: angular wcf xmlhttprequest

我的朋友(真实的故事,不是假的)正在尝试使用角度服务中使用的XMLHttpRequest发出发布请求。 他正在尝试到达一个有效的WCF端点,并从ASP.NET应用程序(或邮递员)接近该端点时可以正常工作。 问题是,有时他会收到请求readyState = 4但请求状态=0。第二次尝试再次执行此操作(请参见下面的代码“ if-else”情况)-结尾为成功(?????)

我假设这与WCF配置(服务器的web.config文件中的CORS选项应已注意-参见下文)或帖子标头选项有关。 这是有角度的服务代码:

import {Injectable, OnInit} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
 @Injectable({
  providedIn: 'root'
 })
export class BaseServiceService implements OnInit {

   constructor( private _http: HttpClient) { }


   public authenticate(user, callback)
   {
      const xmlreq = new XMLHttpRequest();
      xmlreq.open('POST', '<WCF service>.svc', true);
      xmlreq.setRequestHeader('Content-Type', 'text/xml;charset=utf-8');
      xmlreq.responseType = 'document';
      const message = '<s:Envelope 
      xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">\n' +
     '<s:Body>' +
     '<Authenticate xmlns="http://tempuri.org/">' +
         <some xml data used in the post request as body> +
     '</Authenticate>' +
     '</s:Body>' +
    '</s:Envelope>';
    xmlreq.setRequestHeader('SOAPAction', 
   'http://tempuri.org/IAdministrationService/Authenticate');
   xmlreq.onreadystatechange = function () {
   if (xmlreq.readyState === 4 && xmlreq.status === 200 ) 
   {
      callback.apply(this, [xmlreq.responseXML]);
   }
   else //try it again and it will work
   {
       xmlreq.open('POST', '<WCF service>.svc', true);  
       xmlreq.setRequestHeader('Content-Type', 'text/xml;charset=utf-8');
       xmlreq.responseType = 'document';
       const message = '<s:Envelope 
       xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">\n' +
       '<s:Body>' +
       '<Authenticate xmlns="http://tempuri.org/">' +
        <some xml data used in the post request as body> +
       '</Authenticate>' +
       '</s:Body>' +
       '</s:Envelope>';
       xmlreq.setRequestHeader('SOAPAction', 
       'http://tempuri.org/IAdministrationService/Authenticate');
       xmlreq.onreadystatechange = function () 
       {
         if (xmlreq.readyState === 4 && xmlreq.status === 200 ) 
         {
             callback.apply(this, [xmlreq.responseXML]);
         }
       }
       xmlreq.send(message);
    }
  };
  xmlreq.send(message);
  }
 }

这是服务器的web.config文件:

        <?xml version="1.0"?>
    <configuration>
    <system.web>
        <compilation targetFramework="4.0"/>
        <pages controlRenderingCompatibilityVersion="4.0"/>
    </system.web>
    <system.serviceModel>
        <behaviors>
        <endpointBehaviors>
            <behavior name="MyCostumBehavior">
            <webHttp helpEnabled="true"/>
            </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior>
            <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above 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>
        </behaviors>


        <!-- this part was added to allow large messages -->
        <bindings>
        <basicHttpBinding>
            <binding name="MyServiceBinding"
                hostNameComparisonMode="StrongWildcard"
                receiveTimeout="01:30:00"
                sendTimeout="00:30:00"
                openTimeout="00:30:00"
                closeTimeout="00:30:00"
                maxReceivedMessageSize="996553600"
                maxBufferSize="96553600"
                maxBufferPoolSize="9524288"
                transferMode="Buffered"
                messageEncoding="Text"
                textEncoding="utf-8"
                bypassProxyOnLocal="false"
                useDefaultWebProxy="true" >
            <security mode="None" />
            </binding>
        </basicHttpBinding>
        </bindings>


        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="false"/>
    </system.serviceModel>
    <system.diagnostics>
        <sources>
        <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
            <listeners>
            <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Logs\Prod\Mediator.svclog"/>
            </listeners>
        </source>
        </sources>
    </system.diagnostics>
    <system.webServer>
        <httpProtocol>
        <customHeaders>
            <add name="Content-Security-Policy" value="connect-src  http://*"/>
            <add name="Access-Control-Allow-Origin" value="http://localhost:4200"/>
            <add name="Access-Control-Allow-Headers" value="Origin, SOAPACTION, x-requested-with, content-type,X-Auth-Token,Accept" />
            <add name="Access-Control-Allow-Methods" value="GET, POST, PATCH, PUT, DELETE, OPTIONS" />
            <add name="Access-Control-Max-Age" value="3600" />  
        </customHeaders>
    </httpProtocol>
        <modules runAllManagedModulesForAllRequests="true"/>  
        <directoryBrowse enabled="true"/>
    </system.webServer> 

    <connectionStrings>
        <clear/>
        <add name="Configuration" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source = |DataDirectory|\Configuration.accdb"/>
        <add name="Configuration_SQL" connectionString=""/>
        <add name="Subscription_SQL" connectionString=""/>
    </connectionStrings>

    </configuration>

这是服务跟踪查看器: enter image description here

1 个答案:

答案 0 :(得分:0)

处理CORS请求可能有问题。我建议您可以将带有以下代码段的Global.asax文件添加到项目中。

protected void Application_BeginRequest(object sender, EventArgs e)
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.End();
    }
}

此外,当我们在Angular项目中使用SOAP Web服务时,请求主体是如此复杂,建议您将Restful Web服务与ASP.net WebAPI结合使用。
随时让我知道问题是否仍然存在。