WCF JSON returns XML data! - wcf

I'm building a WCF REST Web service which should output JSON, but I'm getting XML.
I'm using ResponseFormat = WebMessageFormat.Json
Please help I search everywhere and I couldn't find the solution.
Note: I even tried the suggestion from here
config file
<services>
<service name="TestService">
<endpoint address=""
behaviorConfiguration="TestServiceAspNetAjaxBehavior"
binding="webHttpBinding"
bindingConfiguration="webBinding"
contract="TestService" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
</security>
</binding>
</webHttpBinding>
</bindings>

Some things you need to check:
The "name" attribute of your <service> element in web.config needs to match the fully-qualified name of the service class - if TestService is on namespace MyNamespace, then the service must be declared as <service name="MyNamespace.TestService"> - in other words, it must match the name you have in the '.svc' file for your service
Your endpoint declaration doesn't specify a behaviorConfiguration attribute; for WCF web endpoints, you need both to have the webHttpBinding and the a reference to a behavior which declares (in your case) <webHttp />
Another option is to use the WebServiceHostFactory in the .svc file: <% #ServiceHost Service="MyNamespace.TestService" Factory="System.ServiceModel.Activation.WebServiceHostFactory" Language="C#" debug="true" %>. With this you don't need to have the service defined in config.

I had a similar issue because I had a tag like this;
<behavior name="jsonBehavior">
<enableWebScript/>
<webHttp helpEnabled="true"/>
</behavior>
after I remove
<webHttp helpEnabled="true"/>
it is fixed. Maybe it is a bug. I am not sure.

Related

WCF web.config file settings for IIS hosting and SSL

After hours of searching for examples, most of which contain only snippets of methods but not the 'whole picture' I am asking for guidance. Starting with the out-of-the-box web.config Visual Studio creates with a new WCF Service, I wrote my basic web service. When you run in debug, WCF Test Client shows the functions that you can test. This is great. Now, wanting to move the code to IIS (first on my local machine, then next to the web server using SSL), I added some code I found on the web. I did have my configuration working at one point but managed to change it so much that I lost the original configurations. So, which that, I have this:
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<services>
<service name="TaskTrackerAppService.Service1" behaviorConfiguration="">
<endpoint address=""
binding="webHttpBinding"
contract="TaskTrackerAppService.IAppWebService"
behaviorConfiguration="WebBehavior"></endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" bindingConfiguration=""></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="TaskTrackerAppService.IAppWebService"></binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="" binding="webHttpBinding"
bindingConfiguration="TaskTrackerAppService.IAppWebService"
contract="TaskTrackerAppService.IAppWebService"></endpoint>
</client>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
I configure my client desktop application service reference to point to the local IP http:192.168.0.100:90/AppWebService.svc. Then when I run my client application I get an error:
Could not find default endpoint element that references contract 'ServiceReference.IAppWebService' 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.
So I'd like to get the web.config settings corrected. Then deploy to a hosted IIS service where SSL is ready. As a bonus, is there is way to configure the endpoints such that I can still run debugger and get WCF Test Client. In the once working config WCF test stopped working. Can it support both simple and hosted configurations?
Thanks.
The <client> section in the <system.serviceModel> is used by client application to specify the "ABC" properties (Address, Binding, and Contract) of the service endpoint. You should have that section in your desktop application so you can simply remove it from your server configurations.
The <client> section in the app.config of your desktop application should, however, have the same "ABC" properties as the service endpoint. Since your service binding is webHttpBinding the client should also have webHttpBinding as binding but I can see that the bindingConfiguration it is referring to, TaskTrackerAppService.IAppWebService is actually a basicHttpBinding so that is a misconfiguration.
Further, since your production environment is using SSL so your production web.config should have binding configuration for SSL something similar to this:
<bindings>
<webHttpBinding>
<binding name="webBindingHTTPS">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
with the following endpoint configuration:
<endpoint address=""
binding="webHttpBinding"
contract="TaskTrackerAppService.IAppWebService"
behaviorConfiguration="webBindingHTTPS"></endpoint>
The best way to achieve this is to use web.config transformation syntax. In that case, your Release web.config could have the following elements:
<bindings>
<webHttpBinding>
<binding name="webBindingHTTPS" xdt:Transform="Insert">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<endpoint address="" xdt:Transform="Replace" xdt:Locator="Match(name)"
binding="webHttpBinding"
contract="TaskTrackerAppService.IAppWebService"
behaviorConfiguration="webBindingHTTPS">
</endpoint>
In this way, whenever you project is built in Debug mode it will be configured withoud SSL and whenever is built in Release mode, it will use SSL.

WCF/SSL error: Failed to lookup a channel to receive an incoming message

I've been having a difficult time getting a WCF call in Silverlight to work when using SSL. I've gotten it to a point where WCF tracing says the endpoint is listening but when my code tries to call a function on it WCF Tracing shows the error:
Failed to lookup a channel to receive an incoming message. Either the endpoint or the SOAP action was not found.
If I browse to the services URL I properly get the service page, but calling it in code it always fails. Again, this only happens on HTTPS, not before when I was using HTTP. Of course there were a number of config changes to add to use SSL. I should note that the WCF Domain Services functions work fine over SSL, just not the WCF Service. Below are my various config file sections
Web.config
<system.serviceModel>
<domainServices>
<endpoints>
<add name="OData" type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</endpoints>
</domainServices>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<behaviors>
<endpointBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding" maxReceivedMessageSize="20000" maxBufferSize="20000">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
<readerQuotas maxArrayLength="20000" maxStringContentLength="20000" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="PictureService">
<endpoint address="https://MyServer/AdvisorDev/PictureService.svc"
binding="basicHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="PictureService.IPictureService"/>
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
ServiceReferences.ClientConfig:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IPictureService" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://MyServer/AdvisorDev/PictureService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPictureService"
contract="PictureService.IPictureService" name="BasicHttpBinding_IPictureService" />
</client>
</system.serviceModel>
</configuration>
Create client:
PictureService.PictureServiceClient client = new PictureService.PictureServiceClient();
I am running this on my Dev machine using VS 2012 and using IIS as my web server. IIS is using a self-signed certificate. When my site first loads I do get the "There is a problem with this website's security certificate" error, click continue, and the rest of the application runs fine again including the Domain Service calls which use a dynamically created proxy. I create my proxy for this failing WCF service using "Add Service Reference"
One of my sources for SSL is this:
http://msdn.microsoft.com/en-us/library/hh556232(v=vs.110).aspx
This is the service I implemented:
http://www.silverlightshow.net/items/Uploading-and-downloading-images-from-WCF-in-Silverlight.aspx
I appreciate all advice on this, thank you.
It turns out this error was caused by an incorrect namespace in the Service name and contract attributes in the web.config for this service.
Just in case anyone else is having this issue as well, I was receiving the same error. The fix turned out to be removing inheritance from three of my classes.
My WCF service was returning a List<MyObject> and three classes inherited from the "MyObject" class. This error was thrown when one of the inheriting classes was included in the list.
Ex:
public class MyObject
public class MyObjectTwo : MyObject
...
List<MyObject> returnList;
MyObjectTwo addingThisBreaksTheService = new MyObjectTwo();
returnList.Add(addingThisBreaksTheService);
return returnList; // Exception thrown after this statement

Wcf custom userNamePasswordValidationMode doesn't work at IIS express

I tried to make a secure wcf with custom userNamePasswordValidationMode service but I confronted some problems(for three days). My setup environment is visual studio 2012, .net 4.0, IIS Express. My service model in host is:
<system.serviceModel>
<bindings >
<wsHttpBinding>
<binding maxReceivedMessageSize="65536" name="WsHttpBinding_ISurveyService">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
<readerQuotas maxArrayLength="65536"
maxBytesPerRead="65536"
maxStringContentLength="65536"/>
</binding>
</wsHttpBinding>
</bindings>
<services>
<!--name= "namespace.serviceClass"-->
<service name="Rids.Services.SurveyService" behaviorConfiguration="Rids.WcfHost.ServiceBehavior" >
<!--contract= "namespace.serviceClass"-->
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="WsHttpBinding_ISurveyService"
contract= "Rids.Services.ISurveyService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="https://localhost" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Rids.WcfHost.ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="None" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Rids.WcfHost.ServiceUserValidator,Rids.WcfHost"/>
<!--Specify the Certificate-->
<serviceCertificate findValue="rids_2014.04.15"
storeLocation="LocalMachine"
x509FindType="FindBySubjectName"
storeName="My"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
When I want to add this service to client, it can not read the metadata and gave the error below:
There was an error downloading 'https://localhost:44300/SurveyService.svc/_vti_bin/ListData.svc/$metadata'.
Unable to connect to the remote server
Hedef makine etkin olarak reddettiğinden bağlantı kurulamadı 127.0.0.1:44300
Metadata contains a reference that cannot be resolved: 'https://localhost:44300/SurveyService.svc'.
There was no endpoint listening at https://localhost:44300/SurveyService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
Unable to connect to the remote server
Hedef makine etkin olarak reddettiğinden bağlantı kurulamadı 127.0.0.1:44300
If the service is defined in the current solution, try building the solution and adding the service reference again.
--
But if I delete name tag from behavior(name="Rids.WcfHost.ServiceBehavior" part) and behaviorConfiguration tag from service (behaviorConfiguration="Rids.WcfHost.ServiceBehavior" part); then I can add the service(https://localhost:44300/SurveyService.svc) to client without error. Also this doesn't solve my problem.
After adding service to client, client service model was like below:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ISurveyService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:11067/SurveyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISurveyService"
contract="Survey.ISurveyService" name="BasicHttpBinding_ISurveyService" />
</client>
</system.serviceModel>
The problems I saw is:
Client service model sees basicHttpBinding although my service binding configuration is wsHttpBinding.
Client service model doesn't see ssl address although I added the service in the path: https://localhost:44300/SurveyService.svc.
I can not add the service to client if service has the behaviorConfiguration tag and behavior has name tag in host configuration.
Custom userNamePasswordValidationMode doesn't work and even if I add service to client without error, service doesn't see validation class or validation method. It works without validation.
Note: Service host project property of 'SSL Enabled' is True; and in project configuration project url is set to https://localhost:44300/.
I've encountered problems in problems. Any advice or solution? Thanks in advance.
I learned how to solve this problem. I made it using EditWcfConfiguration tool in visual studio 2012 as explained below.
Firstly, set property of 'SSL Enabled' as true in host project properties. Under this property automatically ssl url will be generated(such as 'https://localhost:44300/') Then, right click host project and select properties. In project properties Web tab, check 'Use Local IIS Web server' then check 'Use IIS Express'
--
In host project WebConfig, right click then select EditWcfConfiguration:
In EditWcfConfiguration firstly add service, then add a binding for endpoint of service, then add a behavior for service.
1- Add Service
Browse service type at host's bin folder
Select communication mode as HTTP
Select Advanced Web Service interoperability as Simplex communication
Leave the address blank
After adding behavior configuration; select BehaviorConfiguration
After adding binding configuration; open end point of service then, select binding(customBinding) and bindingConfiguration
2- Add a custom binding
Rename binding to use in service's BehaviorConfiguration property (such as 'custom_binding').
Add security, httpsTransport tags.
Select 'AuthenticationMode' as 'UserNameOverTransport' under security tag.
3- In Advanced/Service Behaviors folder, add new service behavior configuration
Rename behavior to use in service end point's BindingConfiguration property (such as safe_behavior).
Add serviceCredentials, serviceMetadata, serviceDebug tags.
For serviceCredentials tag properties:
a-) Select customUserNamePasswordValidatorType as your validator class and its namespace (such as: 'Rids.WcfHost.ServiceUserValidator, Rids.WcfHost')
b-) Select userNamePasswordValidationMode as custom
For clientCertificate tag(under serviceCredentials tag) properties, select certificateValidationMode as None and revocationMode as NoCheck
For serviceMetadata tag properties set HttpsGetEnabled as True
For serviceDebug tag properties set includeExceptionDetailInFaults as True
After these steps, resulting service model is:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="safe_behavior">
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="None" revocationMode="NoCheck" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Rids.WcfHost.ServiceUserValidator, Rids.WcfHost" />
</serviceCredentials>
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="custom_binding">
<security authenticationMode="UserNameOverTransport" />
<httpsTransport />
</binding>
</customBinding>
</bindings>
<services>
<service behaviorConfiguration="safe_behavior" name="Rids.Services.Services.SurveyService">
<endpoint address="" binding="customBinding"
bindingConfiguration="custom_binding" contract="Rids.Services.Services.ISurveyService" />
</service>
</services>
</system.serviceModel>

adding security binding to a wcf end point

I have added a binding to the config below:
<services>
<service name="MyNamespace.Service.ServiceName.ServiceEndPoint">
<endpoint address="http://localhost:8012/ServiceEndPoint" binding="webHttpBinding" contract="MyNamespace.Service.ServiceName.IServiceEndPoint" behaviorConfiguration="webHttp" name="ServiceName"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
So I've added the binding="webHttpBinding" as I'd like to secure the end point. Here's the corresponding config I have:
<bindings>
<wsHttpBinding>
<binding name="ServiceName">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
but this appears to not be securing the end point. I've tried this with Firefox to confirm IE isn't automatically authenticating and checked the headers in firebug.
Can anyone point me in the direction of the right config for doing this?
Thanks,
Matt
you forget to set bindingConfiguration
<endpoint address="http://localhost:8012/ServiceEndPoint" binding="webHttpBinding" contract="MyNamespace.Service.ServiceName.IServiceEndPoint" behaviorConfiguration="webHttp" name="ServiceNameEndpoint" bindingConfiguration="ServiceName"/>
In your binding you have configured a wsHttpBinding and in your service endpoint you have specified a webHttpBinding. I think you want your endpoint binding to be set to wsHttpBinding.
Check this link on WCF Bindings.

Equivalent web.config settings for WebServiceHostFactory

I'm having problems finding how to setup my web.config to use the same settings as using the WebServiceHostFactory on my RESTful WCF service. Does anyone know what the equivalent web.config would look like instead of using that factory, or how I can find it (assume I should be able to attach and find the endpoint objects etc?).
I need to change a couple of small things that the factory is using, and set the authentication to none, so it will play nicely with IIS (currently getting IIS specified authentication schemes 'IntegratedWindowsAuthentication, Anonymous' - and I cant change the IIS settings).
You should be able to add a reference to your service in the Web.config under the system.serviceModel section.
By specifying the full name of the service implementation as the name, of the service element you can then configure it to use specific end points and behaviours.
Hope this helps.
I have used a similar config to below for controlling my WCF Rest Services.
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<protocolMapping>
<add scheme="http" binding="httpBehavior"/>
</protocolMapping>
<bindings>
<webHttpBinding>
<binding name="serviceBinding">
<security mode="Transport" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="httpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="{fullname of your service}">
<endpoint address="" behaviorConfiguration="httpCommerceBehavior" binding="webHttpBinding" bindingConfiguration="serviceBinding" contract="{Service Contract full name}>
</endpoint>
</service>
</services>
</system.serviceModel>