WCF Service Error 400 Bad Request In VS2017 - wcf

I have a very simple WCF Service Project in VS2017. But I keep getting error 400 when I try to visit the endpoints. I have read the other questions posted here about the same issue and I have tried them with no luck so far.
My Service Contract:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/GetData/{value}")]
string GetData(string value);
}
My Service:
public class Service : IService
{
public string GetData(string value)
{
return string.Format("You entered: {0}", value);
}
}
My Web.Config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="myBehavior" name="WCGFService1.Service">
<endpoint address="" contract="WCGFService1.IService" binding="webHttpBinding">
</endpoint>
</service>
</services>
When I visit http://localhost:61648/Service.svc/GetData/12, I get HTTP 400 Bad Request. I've tried with browser and POSTman. What am I doing wrong?
I am using VS2017. My IService.cs and Service.cs are inside the App_Code folder whereas the
Service.svc is in the root folder. Also, when I try to add the name & contract in web.config, VS2013 suggests me the namespace and the interface/class name, whereas, VS2017 is not suggesting me anything so I have to manually type it.
Also, in VS2013, the Interface and Class were located in the root folder instead of the App_Code folder. The project is a WCF Application in VS2017. My .NET Version is 4.5.2.

Fixed it, had a few problems in the web.config file:
<system.serviceModel>
<behaviors>
<!-- Fix 1: Added a endpointBehavoir with webHttp -->
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!-- Fix 2: Instead of using the full name (WCGFService1.Service), used just the class name (Service) -->
<service behaviorConfiguration="myBehavior" name="Service">
<!-- Fix 3: Same thing here, used just the IService instead of full name, also, used the aforementioned endpointBehavoir -->
<endpoint address="" contract="IService" binding="webHttpBinding" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
That did it for me, for whatever reason, in VS2013, it would not work if you don't provide the full name (namespace and class/interface name) but in VS2017, it works only if you provide just the class/interface name.

Related

WCF JSON Format - while consuming in Client side getting an error message

Client side Code
I have created web application and added service reference to the Client Project
I tried creating a client Object like this:
Service1Client a = new Service1Client();
but getting an error message :
Could not find default endpoint element that references contract 'ServiceReference_test.IService1' in the ServiceModel client
configuration section. This might be because no configuration file was
found for your application, or because no endpoint element matching
this contract could be found in the client element.
Could you please let me know what mistake am I doing, I am new to WCF please help me
WCF service which returns JSON Format:
namespace WcfService1
{
public class Service1 : IService1
{
public string GetData(string Id)
{
return ("You entered: " + Id);
}
}
}
namespace WcfService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetData/{Id}",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped
)]
string GetData(string Id);
// TODO: Add your service operations here
}
}
Web.Config file
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="ServiceBehaviour">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="WcfService1.IService1"/>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="false" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
You should add following tags in your client App.config or Web.config:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="WebHttpBinding" />
</webHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/fine_service/FineService/soap"
binding="webHttpBinding" bindingConfiguration="WebHttpBinding"
contract="ServiceReference1.IService1" name="WebHttpBinding" />
</client>
</system.serviceModel>
if you have this tags in your cofig file then make sure that client endpoint contract name should be the same as it is in your service endpoint. In your case contract name is IService1
EDIT:
also see this

WCF Restfull service stopped working

I have this service that was working great until I changed the namespace of the service. Also changed the default namespace in the project. I was getting some errors something about not publishing metadata, so I undid my changes, and not nothing works. I even created a new service to test getting this going again, and not I am getting an http 400 when I try to test my rest service. It's been a long week, and I am fully pulling my hair out. Can anyone see what I am doing wrong here?
Update: The http 400 is gone, this is the error I am seeing:Error: Cannot obtain Metadata from http://localhost:1585/ProdSvc.svc If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455
[OperationContract]
void DoWork();
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "GetProductName/")]
string GetProductName();
public string GetProductName()
{
return "It worked!!!";
}
<system.serviceModel>
<services>
<service name="TSServices.ProdSvc" behaviorConfiguration="serviceBehavior">
<endpoint address=""
binding="webHttpBinding"
contract="TSServices.ProdSvc"
behaviorConfiguration="web"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Supertopi's answer was correct. Adding the config sections did the trick.

WCF Error 404 - Possibly the config file

I created a WCF project and i'm using the WCF Test Client, I got the returned message. However, when I used the browser to the endpoint address, I received Error 404. My code is shown below:
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "UpdateTbl/{tblName}")]
public string UpdateTbl(string tblName)
{ ... }
The related code in the config file is below:
<system.serviceModel>
<services>
<service name="WcfJsonRestService.Service1" >
<endpoint address="http://thehost:47423/Service1" binding="webHttpBinding" contract="WcfJsonRestService.IService1" >
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Please help if you can share your experience. Thanks.
You can't configure service activation by providing a URL for the endpoint. The syntax you're using for the endpoint element is appropriate for a client configuration file, not a service. You must either use the URL of an SVC file for activation, or use a more sophisticated activation scheme, as discussed here and here.

Invoking WCF service in browser similar to asmx

I have made a WCF service in NET 4.0 and it returns the XML, I have tested it using SoapUI and i can see the required response xml. But my WCF service would be called by 3rd party software and they want to use it through a URL like asmx. I have googled and found that i need to make using REST guidelines. However i have not found a proper link showing making web-service using REST and then accessing the method from the browwer similar to web services.
Below is the interface code which i have used to return the format in XML
public interface IService1
{
[WebGet(
UriTemplate = "/GetDocument/",
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Xml)]
[OperationContract, XmlSerializerFormat]
XmlElement GetDocument();
// TODO: Add your service operations here
}
Below is my config settings.
<system.serviceModel>
<services>
<service name="BritishLandXML.BritishLandXML1" behaviorConfiguration="metadataBehavior">
<endpoint address="" binding="basicHttpBinding" contract="BritishLandXML.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding>
<security mode="None"></security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp helpEnabled="true" faultExceptionEnabled="true" automaticFormatSelectionEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<!-- 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>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
Please let me know how can i achieve this and what exact settings will be required.

WCF Generate help for REST POST call

Using WCF, it is possible to generate help for a webHTTPBinding. With a WebGet operation, it works like charm. Using a WebInvoke (Method = "POST") however doesn't give me any help. In the pages I can see this:
Url:
http://localhost/edumatic3/trunk/services/service.svc/rest/saveUser
HTTP Method: POST
Message direction Format Body
Request Unknown Could not generate schema document.
Response Unknown Could not generate schema document.
Any ideas?
Web.Config system.serviceModel
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBindingConfiguration">
<security mode="TransportWithMessageCredential" />
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="HelpEndPointBehavior">
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="false" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType=
"Edu3.Service.OpenApi.Security.CustomUserNameValidator
, Edu3.Service.OpenApi" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="OpenApiService"
behaviorConfiguration="ServiceBehavior">
<endpoint name="soap"
address="soap"
binding="basicHttpBinding"
contract="Edu3.Service.OpenApi.Interface.IService"
bindingConfiguration="basicHttpBindingConfiguration"/>
<endpoint name="rest"
address="rest"
behaviorConfiguration="HelpEndPointBehavior"
binding="webHttpBinding"
contract="Edu3.Service.OpenApi.Interface.IService"/>
<endpoint name="mex"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="services/service.svc"
service="OpenApiService"
factory="Spring.ServiceModel.Activation.ServiceHostFactory"/>
</serviceActivations>
</serviceHostingEnvironment>
Service Contract:
The GetNodeByKey gives me clear help. The SaveUser not.
[ServiceContract]
public interface IService
{
[OperationContract]
[WebGet(UriTemplate = "login?userName={userName}&password={password}")]
void Login(string userName, string password);
[OperationContract]
[WebGet(UriTemplate = "getNodeByKey/{key}?getAllDescendants={getAllDescendants}"
, ResponseFormat = WebMessageFormat.Json)]
[ServiceKnownType(typeof(BranchNodeDTO))]
[ServiceKnownType(typeof(LeafNodeDTO))]
[ServiceKnownType(typeof(CasusNodeDTO))]
[ServiceKnownType(typeof(BucketNodeDTO))]
NodeDTO GetNodeByKey(string key, string getAllDescendants);
[OperationContract]
[WebInvoke(UriTemplate = "saveUser", Method = "POST"
, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
UserDto SaveUser(UserDto user, int channelId);
}
What about your DataContract? Are there any enums which have FlagsAttribute? It seems that when you use [Flags] WCF isn't able to correctly generate the help page.
Source: http://support.microsoft.com/kb/2020406/en-us