VS2012 WCF REST Service - Error: Cannot obtain metadata - json

I have built a WCF REST web service (WCF Service Application) and when I debug with Visual Studio 2012, it will spin up the WCF Test Client app and try to add my web service. I am getting the following error:
Error: Cannot obtain Metadata from http://localhost:50925/Service1.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.WS-Metadata Exchange Error URI: http://localhost:50925/Service1.svc Metadata contains a reference that cannot be resolved: 'http://localhost:50925/Service1.svc'. Content Type application/soap+xml; charset=utf-8 was not supported by service
I have visited the MSDN document linked above and I believe I have set up my web.config correctly.
Web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="Service1" behaviorConfiguration="Service1Behavior">
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"> </endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I still continue to receive the same error message. I am new to WCF / VS 2012 and .Net 4.0, but I am fluent in VS2008 .Net 2.0.

WCF REST services do not expose metadata, which is why you were getting that message (see more details in this blog post). If you're using the WCF Test Client, it's talking to a SOAP service (endpoint), not a REST one.
If you want to enable a RESTful endpoint, you can define the service element in configuration and define an endpoint inside of it which uses the webHttpBinding, and the endpoint also needs a behaviorConfiguration pointing to an endpoint behavior with the <webHttp/> behavior.

As it turns out I created a new WCF project and looked at what was going on here. VS2012/.Net 4.0 does not like the service configurations with endpoints defined. Here is my new web.config that works fine. I will need to look into why this is but at least it answers my question.
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>

Related

WCF Service 413 no matter which config item I change

I have been trying to figure this out for days, to no avail. This happens both when I try to debug in Visual Studio using IIS Express and with my production web site deployed to a machine running IIS 7.5.
I have called the service from a Visual Studio Unit Test using HttpWebRequest and in Fiddler 4, same errors. So I don't think this is a WCF client configuration, as I am not using one.
No matter what I change in my configuration file, I am always getting this exception:
"Exception thrown: 'System.ServiceModel.ProtocolException' in
System.ServiceModel.dll
Additional information: The maximum message size quota for incoming messages
(65536) has been exceeded. To increase the quota, use the
MaxReceivedMessageSize property on the appropriate binding element."
The below Web.config that I am attaching is for an application that is not at the root of my server.
I am calling using the json endpoint using Ajax.
I cannot for the life of me figure out why I am getting the 64K limit, especially given that I have added all of the items to the webHttpBinding as below.
I have also changed the httpRuntime element by adding the maxRequestLength item, changed the request filtering, the security settings, and a whole slew of other things that didn't make a difference.
Notice also that I have turned on tracing. The .svclog file didn't tell me anything more.
Thanks in advance for any help.
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
<add key="FactoryType" value="Production"/>
<add key="TravelRequestConnectionString" value="Data Source=ITLCS.benderson.com;Initial Catalog=TestTravelRequestSite;User Id=XXXX;Password=XXXXX"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1"/>
<membership defaultProvider="ADMembershipProvider">
<providers>
<clear />
<add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider" connectionStringName="ADConnectionString" attributeMapUsername="sAMAccountName" />
</providers>
</membership>
</system.web>
<system.serviceModel>
<services>
<service name="TravelRequestWebService.TravelRequestService">
<endpoint
address="web"
binding="basicHttpBinding"
contract="TravelRequestWebService.ITravelRequestService" />
<endpoint
address="json"
binding="webHttpBinding"
behaviorConfiguration="jsonBehavior"
contract="TravelRequestWebService.ITravelRequestService" />
<endpoint
address=""
binding="basicHttpBinding"
contract="TravelRequestWebService.ITravelRequestService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="defaultBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="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>
<behavior name="bigBehavior">
<dataContractSerializer maxItemsInObjectGraph="200"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp/>
</behavior>
<behavior name="jsonBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webHttpBinding" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000">
</binding>
</webHttpBinding>
<basicHttpBinding>
<binding name="basicHttpBinding" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000">
</binding>
</basicHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<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>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="CardSpace">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.IO.Log">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.Runtime.Serialization">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.IdentityModel">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\log\Traces.svclog" />
</sharedListeners>
</system.diagnostics>
</configuration>
Try changing your config to this:
<service name="TravelRequestWebService.TravelRequestService">
<endpoint
address="web"
binding="basicHttpBinding"
bindingConfiguration="basicHttpBinding"
contract="TravelRequestWebService.ITravelRequestService" />
<endpoint
address="json"
binding="webHttpBinding"
behaviorConfiguration="jsonBehavior"
bindingConfiguration="webHttpBinding"
contract="TravelRequestWebService.ITravelRequestService" />
<endpoint
address=""
binding="basicHttpBinding"
contract="TravelRequestWebService.ITravelRequestService" />
</service>
The clue was the 64K default limit for the message size in the error message. This implied your binding configuration was not being used by WCF. The fact the configurations are named the same as the endpoint bindings added confusion.

Configure Glimpse in Code

Glimpse is currently configured in the web config for MVC5 as shown below:
<configuration>
<configSections>
<section name="glimpse" type="Glimpse.Core.Configuration.Section, Glimpse.Core" />
</configSections>
</configuration>
<system.web>
<httpModules>
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet"/>
</httpModules>
<httpHandlers>
<add path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet"/>
</httpHandlers>
</system.web>
<glimpse defaultRuntimePolicy="On" endpointBaseUri="~/Glimpse.axd">
<tabs>
<ignoredTypes>
<add type="{Namespace.Type, AssemblyName}"/>
</ignoredTypes>
</tabs>
</glimpse>
is there anyway to configure glimpse in code perhaps using web activator or a class called from global App Start?

ASP.NET Razor Site: "This type of page is not served"

I've created an empty ASP.NET website (i.e. razor web pages) but I'm unable to reach the index.cshtml page.
This is true whether I have 'index.cshtml' in the URL or not.
The error pages says:
Server Error in '/' Application.
This type of page is not served.
Description: The type of page you have requested is not served because
it has been explicitly forbidden. The extension '.cshtml' may be
incorrect. Please review the URL below and make sure that it is
spelled correctly.
Requested URL: /index.cshtml
Here is the entire contents of the web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="true"/>
<add key="webpages:Version" value="3.0.0.0"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5"/>
<httpRuntime targetFramework="4.5" enableVersionHeader="false" requestValidationMode="2.0"/>
<pages validateRequest="false"/>
</system.web>
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true">
<fileExtensions>
<remove fileExtension=".cshtml"/>
<add fileExtension=".cshtml" allowed="true"/>
</fileExtensions>
</requestFiltering>
</security>
<defaultDocument>
<files>
<remove value="index.cshtml"/>
<add value="index.cshtml"/>
</files>
</defaultDocument>
</system.webServer>
</configuration>
Can anyone tell me what I'm missing (or what I've added and which shouldn't be there)?

How to secure webHttpBinding?

In my WCF service I am trying to to send data to the client using JSON over an SSL connection. I was able to secure the OData database source to my client using wsHttpBinding with a security mode of Transport. Why is webHttpBinding not able to do the same in order to use SSL? How would I configure an endpoint that needs to use JSON to use an SSL connection as well?
Essentially what is the difference between webHttpBinding and wsHttpBinding?
<bindings>
<wsHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceBehavior" name="DataService4.DataService">
<endpoint address="" binding="webHttpBinding" contract="DataService4.IService" bindingConfiguration="TransportSecurity" behaviorConfiguration="EndpBehavior" />
<endpoint contract="IMetadataExchange" binding="mexHttpsBinding" address="mex" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
I think this article will solve your problem.
Creating a WCF RESTful Service And Secure It Using HTTPS Over SSL
The relevant part from http://www.allenconway.net/2012/05/creating-wcf-restful-service-and-secure.html is this:
<bindings>
<webHttpBinding>
<binding>
<security mode="Transport" />
</binding>
</webHttpBinding>
</bindings>
but also remove exposing metadata if desired.
the details are documented in msdn here: https://msdn.microsoft.com/en-us/library/bb924478(v=vs.110).aspx
the relevant parts are:
Transport Security is provided using HTTPS. The service needs to be
configured with SSL certificates. The message is entirely secured
using HTTPS and the service is authenticated by the client using the
service’s SSL certificate. The client authentication is controlled
through the ClientCredentialType attribute of the transport of
webHttpBinding.

Connection interrupted when using WebHttpBinding in Transport SecurityMode

I want to expose an implementation of a contract over a WebHttpBinding with SecurityMode: transport (SSL).
However, when I try to access the site via Firefox, I only get
The connection to localhost was interrupted while the page was loading.
The config file is as follows:
<configuration>
<system.serviceModel>
<services>
<service name="MyService">
<endpoint address="https://localhost"
binding="webHttpBinding"
contract="MyService"
bindingConfiguration="secureWebHttp">
</endpoint>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="secureWebHttp">
<security mode="Transport"/>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
If host within IIS, you need to configure the hosting website security to use an ssl certificate on port 443 in this case.
You also need to configure the service behavior to set the certificate name and store. Particularly when hosting the wcf service as windows services, the certificate needs to be set for the port that you want to use. for example httpcfg.exe or netsh in vista.
Check out MSDN Configuring HTTP and HTTPS