угловой запрос XMLHttpRequest для WCF завершается неудачно - PullRequest
0 голосов
/ 03 июня 2019

Мой друг (правдивая история, а не подделка) пытается сделать запрос на публикацию с использованием XMLHttpRequest, используемого в сервисе angular.Он пытается добраться до конечной точки WCF, которая является действительной и работает при приближении к ней из приложения ASP.NET (или почтальона).Проблема в том, что бывают случаи, когда он получает запрос readyState = 4, но запрашивает статус = 0. Попытка сделать это снова, во второй раз (см. Случай «if-else» в приведенном ниже коде) - заканчивается наsuccess (?????)

Я получил предположение, что это как-то связано с конфигурацией WCF (параметры CORS должны были позаботиться в файле web.config сервера - см. также ниже) или с параметрами заголовка сообщения.Это угловой код службы:

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 голосов
/ 03 июня 2019

Возможно, что-то не так с обработкой запроса CORS.Я предлагаю вам добавить в проект файл Global.asax с приведенными ниже фрагментами кода.

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

Кроме того, когда мы используем веб-сервис SOAP в проекте Angular, тело запроса оказывается настолько сложным, что я предлагаюВы используете веб-службу Restful с ASP.net WebAPI.
Не стесняйтесь, дайте мне знать, если проблема все еще существует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...