Can't define the endpoint after creating my WCF - wcf

I wanna learn WCF so I decided to try out creating some application that uses it. Well what I have in mind is I have 2 databases and I wanna create also an SSIS custom data source extension that calls the web service and passes the data (from one database) to an SSIS ADO.Net Data source (into the second database).
Now I created the 2 databases using SQL Server with one table in each. Then I Added a Connection in Visual Studio and then specified the server instance. (didn't create any .mdf files). I added this connectionString in the Web.Config file
<connectionStrings>
<add name="dbconnection" connectionString="
Data Source = SARE-VAIO;
Integrated Security = true;
Initial Catalog = Database1"/>
</connectionStrings>
When I wrote my service which basically populates Database1 with data, I wanted to define the endpoints but when I clicked on the "Edit WCF Configuration" it says 'No Service' is defined? What possibly am I doing wrong here? I want to create an error free service to be able to use it as a source in the SSIS package.
PS. My service has a basicHttpsBinding
UPDATE: I'm using VS 2012 with .Net Framework 4.5
UPDATE 2:
I skipped the endpoint definition for now and went ahead with testing and deploying my WCF. When I invoke the service it says the following error
Failed to invoke the service. Possible causes: The service is offline or inaccessible;
the client-side configuration does not match the proxy; the existing proxy is invalid.
Refer to the stack trace for more detail. You can try to recover by starting a new proxy,
restoring to default configuration, or refreshing the service.
Here is my web.config file
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="dbconnection" connectionString="Data Source = SARE-VAIO; Integrated Security = true; Initial Catalog = Database1"/>
</connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="false" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>

To answer your questions
(1) Why WCF configuration editor shows 'No service is defined' error : Your web.config does not have any services and endpoints defined explicitly (Note: When you host this in IIS you will still get some endpoints added due to the defaults endpoint feature. But config editor tool shows only explicitly defined endpoints). That's the reason the config editor tool shows this message. But you can use the tool to add services and endpoints.
(2) After deploying the service see if the service successfully activated. You can do this by browsing to the metadata URL (your config has metadata enabled). Make sure your service WSDL help page and WSDL shows up fine. If not fix that issue first.
(3) If you are looking a default https endpoint after hosting it in IIS, make sure your IIS has https binding configured with an SSL certificate.
Hope this helps!
Thanks!

Related

WCF - Access Denied when creating folder

I've built a WCF service and want to host it on IIS. One of the features I want is to programmatically create a subfolder in the WCF webhost root, to persist some json files.I've tested it on my local dev IIS Express and it works fine, which is no surprise 'cause I have all the necessary permissions.Now, I want to publish it on my public domain. For this, I've created a subdomain on Plesk and a subfolder within httpdocs. I've copied the web.config file and the Bin folder from my dev machine to this folder on my domain. But, when I enter the svc url on my browser I get a access denied exception (the folder is created in a dependency injected in my service, that's why I get the exception at this point).
Server Error in '/' Application.
Access to the path
'C:\Inetpub\vhosts\««my domain»»\httpdocs\VersioningService\Repository' is
denied.
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details: System.UnauthorizedAccessException: Access to the
path
'C:\Inetpub\vhosts\««my domain»»\httpdocs\VersioningService\Repository' is
denied.
Below is my web.config:
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="false" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<customErrors mode="Off"/>
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true">
<serviceActivations>
<add factory="VersioningService.Services.ManualMajorMinorVersioningHostFactory"
relativeAddress="~/ManualMajorMinorVersioning.svc"
service="VersioningService.Services.ManualMajorMinorVersioning" />
</serviceActivations>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
This is what I use to get the current assembly path:
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
Note: If I use the ProgramData folder I get NO exception, but I would prefer to have a subfolder within the WCF folder.
This is clearly a permissions issue. Do I need to add something else to my web.config?Do I need to ask my host provider to give some extra permissions to some user?

WCF only accepts localhost

I'm writing my first WCF in Visual Studio Express, and configured it to run under IIS Express. My Web.config is as bellow. From my browser I can access the service if I do a Get request on http://localhost:50000/Service1.svc, but not http://10.0.0.26:50000/Service1.svc where 10.0.0.26 is my ip. How to configure WCF of IIS Express to accept IP addresses. Ultimatly my service is tio be reached accross the network.
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="medSaveWCF.Service1">
<endpoint address="../Service1.svc"
binding="webHttpBinding"
contract="medSaveWCF.IService1"
behaviorConfiguration="webBehaviour" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept" />
</customHeaders>
</httpProtocol>
<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>
</configuration>
(Side note: I have blogged about this, including additional setup steps you need to use SSL: http://blog.kutulu.org/2015/01/using-iis-express-with-remote-systems.html)
The problem is that IIS Express only listens on the localhost address, by default. The reason is, IIS runs as a user process, but uses the same HTTPD.SYS system library that the full IIS does. By default the HTTPD.SYS configuration does not allow user processes to bind to an external address. To fix this you'll need to do three things:
Edit the IIS configuration to bind to a new port
Update HTTPD.SYS to permit your user to use that new binding.
Tell WCF you have multiple bindings.
Step One: IIS Express Setup
The IIS Express configuration is done directly through the XML configuration file, which is found at:
C:\Users\[username]\Documents\IISExpress\config\applicationhost.config
If your project is already set up to work with IIS Express, you'll find a configuration block starting around 150 lines into the file -- look for the XML <sites> tag, and you'll find a <site> element:
<site name="MySolution.MyProject" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/"
physicalPath="C:\Projects\MySolution\MyProject" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:50000:localhost" />
</bindings>
</site>
Inside that <bindings> element is the list of ports and hostnames that IIS Express binds to when running that particular site, you just need to add a new binding element:
<binding protocol="http" bindingInformation="*:50000:10.0.0.26" />
Step Two: HTTPD.SYS Permissions
Full disclosure: this step is optional if you are willing to run Visual Studio and IIS Express as an admin user. But that defeats the entire purpose of IIS Express, which is a user-mode web server, so don't do that.
Instead, you just need to use the netsh command to reconfigure HTTPD.SYS to allow you to bind to the ports you want. Specifically, you need to use the http add urlacl command.
Launch an administrative command prompt and/or PowerShell prompt and do this:
netsh http add urlacl url=http://10.0.0.26:5000 user=Everyone
Once both are done, shut down IIS Express so VS will restart it, and you should be all set.
I wrote myself a small Powershell script to go through and do this for a whole range of ports:
$LowPort = 50000
$RangeSize = 99
for ( $i = 0; $i -le $RangeSize; $i++ )
{
netsh http delete urlacl url="http://${IISHost}:$($LowPort + $i)/"
netsh http add urlacl url="http://${IISHost}:$($LowPort + $i)/" user=Everyone
}
That way I don't have to remember to do this every time, I just need to use a port in the 50000 - 50100 range.
Step Three: Inform WCF
By default, WCF only binds to one site per project. For real IIS this is fine, because that's the *:80 binding you probably want. For IIS Express, you need separate bindings per IP address so you need to tell WCF to use them all. This is easy, just add this to your WCF configuration:
<configuration>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
Once all that's done, shut down IIS Express and let VS restart it and you should be all set.

Confusion about default WCF project web.config layout

Below is the default layout for the web.config of a new WCF Service Application in VS2012.
What confuses me is that it doesn't seem to match any examples or tutorials online. There are no endpoints or bindings defined, yet it's possible to call the service.
I hit a problem when trying to increase the MaxReceivedMessageSize property - I googled it and didn't have a clue where to look in my web.config.
Can someone point me in the right direction of why it's so strangely laid out?
I expected it to look more like This SO question about setting MaxReceivedMessageSize or even any WCF tutorials like Michelle Bustamante's which is how I originally learned WCF.
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<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>
</configuration>
Starting with .NET 4.0, WCF introduced the concepts of default endpoints and bindings, allowing developers to create a service without having to define a bunch of stuff in the configuration file.
The posted config file is targeting 4.5, which is why you're seeing such a naked WCF config. If you need to increase your maxMessageSize, you'll need to explicitly define it in the config.
You can do this by either setting that binding definition as the default (by omitting the name attribute on the binding element), or creating an endpoint and explicitly assigning the binding configuration you defined via the bindingConfig attribute.
See A Developer's Introduction to Windows Communication Foundation 4.
You can also check a previous answer by me that has examples: https://stackoverflow.com/a/16099054/745969

WCF Deploy Strange Contract behavior

WCF service deployed to IIS7 server sitting on WinServer2008 Standard SP2.
DataContract int Members are being 'lost'
i.e. All ints sent by the client emerge as 0 into the Contract processing logic on the Server
I made a 'Reflection' contract (Take incoming int turn it to string and return it). When the test harness is pointed at the WCF Contract running in the IDE the ints are reflected OK. When it is pointed at the Deployed contract zeros are reflected.
Deployment:
Made an IIS Application on the Server and did a file deployment to the physical directory.
The Deployed Service appears OK. i.e. The 'real' client app (VS2008 WinMobile 6.5 app under development separate solution) has a WebService reference that sees the Deployed WCF OK . It is just that the variable values generated by the client get lost on the wire. Only happens to Client generated variables. The client is able to consume Server generated DataContract Variables with the expected values. It is something to do with base types. The first victim was client generated dates so I moved these into strings for the journey.
Web.config is below.
thanks
Bob
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Removed the web Application from Production server and remade it. Problem partially solved. Test windows app now sees the ints reflected. However the WinMobile client still doesn't. Tested using string values for the contract and it works. Life is too short for this. I shall alter the Contracts to strings strings strings. So much for strongly typed Data Contracts.

Setting BasicHTTPBinding for WCF service in Visual Web Express 2010

I'm creating a WCF service using Visual Web Developer Express 2010. I'd like to try out various bindings for educational purposes.
My memory from 2008 is that the web.config automatically included a section in for <services>, which I then would edit to change the endpoint binding, for example to basicHttpBinding
However my autogenerated 2010 service does not include <services> and any child endpoint or binding details under <system.serviceModel> (see web.config below). Do I need to add this element to the Web.config manually, or is there an alternative way that this should be configured? Or is this a limitation of the Express edition?
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
UPDATE 1 - I've found the following link which seems to describe the same behaviour - investigating now: http://forums.silverlight.net/t/166429.aspx/1
The version of Visual Studio doesn't matter here - it's the version of the .NET framework that is causing your confusion. In .NET 4.0 there are default WCF settings which means that a service can be hosted without any configuration.
MSDN Introduction to WCF 4 will explain more.
If you create the project as a .NET 3.5 project the configuration will be required (and will be added when you 'add new WCF service').
You can add the configuration in .NET 4.0, but if you are new to WCF it's easier if it were automatically generated so you had a starting point to work from.
It seems that WCF 4 creates a default end point if one isn't defined. From http://msdn.microsoft.com/en-us/library/ee354381.aspx
In an effort to make the overall WCF experience just as easy as ASMX,
WCF 4 comes with a new “default configuration” model that completely
removes the need for any WCF configuration. If you don’t provide any
WCF configuration for a particular service, the WCF 4 runtime
automatically configures your service with some standard endpoints and
default binding/behavior configurations. This makes it much easier to
get a WCF service up and running, especially for those who aren’t
familiar with the various WCF configuration options and are happy to
accept the defaults, at least to get started.