HTTP 400 Bad Request when calling a WCF service?

When I call http: //localhost/TestService.svc/GetColors , I get an invalid Http (400) request. When I run this in the violinist, I also get a Bad Request. When I call the service through the wcf test client, it works fine. What can cause this?

Service Agreement:

[ServiceContract] public interface ITestService { [OperationContract] string GetColors(); } 

Implementation of ITestService:

 [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] public class TestService : ITestService { public List<Color> GetColors() { List<Color> colors= new List<Color>(); colors.Add(new Color { Name = "Red", Code = "123" }); colors.Add(new Color { Name = "Blue", Code = "323" }); colors.Add(new Color { Name = "Green", Code = "3394" }); return colors; } } 

Here is my web.config:

 <?xml version="1.0"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0"/> </system.web> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="CustomAuthentication"> <security mode="Message"> <message clientCredentialType="UserName"/> </security> </binding> </wsHttpBinding> </bindings> <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/> <services> <service name="TestService.TestService" behaviorConfiguration="CustomValidator" > <endpoint address="" binding="wsHttpBinding" bindingConfiguration="CustomAuthentication" contract="TestService.ITestService"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost/TestService/" /> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior name="CustomValidator"> <serviceCredentials> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="TestService.CustomUserNameValidator, TestService"/> <serviceCertificate findValue="Test" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/> </serviceCredentials> <serviceMetadata httpGetEnabled="True"/> </behavior> <behavior> <serviceMetadata httpGetEnabled="True"/> <serviceDebug includeExceptionDetailInFaults="False"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> </configuration> 

When I call it, I simply open any browser and click on the url http://localhost/TestService.svc/GetColors . If I do this through the dev environment, I see a bad Http 400 request. If I do this through IIS, I just see a blank page.

Here is the internal exception:

 <ExceptionString>System.Xml.XmlException: The body of the message cannot be read because it is empty.</ExceptionString> 

One more question regarding my CustomUserNameValidation:

I do Custom Validation using the Validate UserNamePasswordValidator method, but when I call something like GetColors through the wcf client, it does not call the Validate method. The only way to get it for Invoke validate is if I call Validate (user, pass) directly in GetColors. I thought it would be called automatically for every service call if you configured it correctly in web.config.

+6
source share
2 answers

Your contract for service and service does not seem to match ....

The service contract defines a single string that must be returned from GetColors() :

 [ServiceContract] public interface ITestService { [OperationContract] string GetColors(); } 

But the implementation returns instead of List<Color> :

 [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] public class TestService : ITestService { public List<Color> GetColors() { 

Is it likely that you have changed your service implementation and forgot to renew your service contract?

Also: since this is a SOAP service with wsHttpBinding , you cannot just call the method from the browser by looking at its address - you need to use the WCF test client (which works as you say). You also cannot just call it from Fiddler: you have to manually create the entire SOAP envelope with the header and body, and that’s not an easy task at all.

What you can try is go to http://localhost/TestService.svc?wsdl to check if you will return the correct WSDL for this service.

+5
source

Many things can cause this. I suggest you turn on WCF tracing first, it is usually very useful, as it gives you a conclusion about what is happening on the server. Here is a link that should help: How to enable WCF tracing

EDIT : one small thing to note with WCF: unlike the ASMX ole auto-generated web service, it does not allow you to view the base address with a standard browser. You can go to the metadata address (mex one), but not to the root. It is just by design (HTTP method is not supported, I believe).

0
source

Source: https://habr.com/ru/post/888051/


All Articles