Vraag HTTP Bad Request-fout bij het aanvragen van een WCF-servicecontract


Ik heb een WCF-service met de volgende configuratie:

<system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior name="MetadataEnabled">
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceMetadata httpGetEnabled="true" />
            </behavior>
        </serviceBehaviors>
     </behaviors>
      <services>
          <service behaviorConfiguration="MetadataEnabled" name="MyNamespace.MyService">
              <endpoint name="BasicHttp"
                        address=""
                        binding="basicHttpBinding"
                        contract="MyNamespace.IMyServiceContract" />
              <endpoint name="MetadataHttp"
                        address="contract"
                        binding="mexHttpBinding" 
                        contract="IMetadataExchange" />
              <host>
                  <baseAddresses>
                      <add baseAddress="http://localhost/myservice" />
                  </baseAddresses>
              </host>
          </service>
    </services>
</system.serviceModel>

Bij het hosten van de service in de WcfSvcHost.exe proces, als ik naar de URL blader:

http: // localhost / MyService / contract

waar de metadata van de service beschikbaar is krijg ik een HTTP 400 slecht verzoek fout.

Door de WCF-logboeken te inspecteren, ontdekte ik dat een System.Xml.XmlException uitzondering wordt gegooid met de boodschap: "De inhoud van het bericht kan niet worden gelezen omdat het leeg is."
Hier is een uittreksel van het logbestand:

<Exception>
<ExceptionType>
System.ServiceModel.ProtocolException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
</ExceptionType>
<Message>There is a problem with the XML that was received from the network. See inner exception for more details.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult result)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result)
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<InnerException>
<ExceptionType>System.Xml.XmlException, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The body of the message cannot be read because it is empty.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult result)
at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result)
at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
</InnerException>
</Exception>

Als ik in plaats daarvan naar de URL blader:

http: // localhost / MyService wsdl

alles werkt prima en ik krijg het WSDL-contract. Op dit punt kan ik ook de "MetadataHttp" metadata-eindpunt volledig, en het zou geen enkel verschil maken.

Ik gebruik .NET 3.5 SP1. Heeft iemand een idee van wat hier fout zou kunnen zijn?


12
2017-11-27 11:49


oorsprong


antwoorden:


Ik denk dat ik erachter ben gekomen wat het probleem is.

Als ik naar de URL blader:

http: // localhost / MyService / contract

met de WcfTestClient toepassing Ik kan metagegevens van de service met succes ophalen.
De fout komt dus echt alleen voor als ik de URL opzoek via een webbrowser.

De HTTP slecht verzoek fout komt van het feit dat de browser een HTTP GET-verzoek afgeeft waarbij de inhoud van het bericht in de HTTP-headers staat en de body leeg is.
Dit is precies wat de WCF mexHttpBinding klaagt over!

Om via een webbrowser bij het servicecontract te komen, moet u dit expliciet inschakelen in het servicegedrag:

<serviceBehaviors>
    <behavior name="MetadataEnabled">
        <serviceMetadata httpGetEnabled="true" />
    </behavior>
</serviceBehaviors>

De URL om te vragen wordt dan:

http: // localhost / MyService wsdl

Dus het bleek dat ik iets te snel was met het plaatsen van deze vraag. Ik bewaar het echter gewoon voor de goede orde.


12
2017-11-27 12:04



Over het algemeen is dit een probleem met de grootte van de SOAP-envelop. Controleer uw inbindconfiguratie om MaxBufferPoolSize, MaxReceivedMessageSize te wijzigen om grote inhoud toe te staan. Onthoud dat u zowel in client- als in serverkant moet veranderen.

Een ander probleem is de MessageEnconding (een andere bindende parameter), die ervoor zorgt dat client- en serverkant dezelfde codering gebruiken.

Controleer ten slotte de parameters van Reader Quotas Properties.


4
2017-11-10 19:42



Ik kon het probleem "400 Bad Request" oplossen door mijn WCF-service uit te schakelen van Visual Studio Development Server naar Local IIS-webserver (klik met de rechtermuisknop op het project -> eigenschappen -> tabblad web -> radio knop onder "Servers"). Ik hoop dat dit iemand daarbuiten helpt, want het kostte me twee dagen om dit uit te zoeken.


3
2018-03-18 13:24



Ik had problemen met HTTP 400 bij het gebruik van een HTTPS mex-URL van SvcUtil, hoewel httpsGetEnabled was ingesteld op true. De foutmelding was mijlen verwijderd van wat echt het probleem was, dus ik post hier voor het geval iemand anders hetzelfde probleem tegenkomt.

Ik had een zelfondertekend CA-certificaat (TestRootCA) dat de uitgever van het servercertificaat (localhost) was. Op de client heb ik het CER-bestand TestRootCA geïmporteerd maar ik heb de CRL (Certificate Revocation List) niet geïmporteerd. Het lijkt erop dat wanneer u een door uzelf ondertekende CA gebruikt moet importeer ook de CRL, anders mislukt serververificatie op een vreemde manier, en niets wijst u op het echte probleem. Wat is erger is dat het falen gebeurt tijdens SSL-handshake, voor het verzoek bereikt zelfs uw service, dus u ziet geen fouten in WCF-traceerlogboeken.


2
2018-03-26 17:36



Als u niet zeker weet waarom uw WCF-code een fout veroorzaakt, raad ik de MS Service Trace Viewer ten zeerste aan. Het is erg handig bij het identificeren van communicatie- en transportproblemen zoals deze. Kijk hier eens even naar C # hoek artikel voor meer details.


2
2018-03-23 02:43