WCF / Silverlight Call Back to Server Fails in IIS - wcf

Using Silverlight 3, Windows XP, IIS 5.1, I've written a small app which uses the channel method of calling the server rather than the 'add service reference' as per this MSFT article.
The application opens and the call to the server work when running it on the development computer in VS 2008 using the address localhost plus the port number. When I change the address to the computer name, dellnov2006, and publish the application to IIS, the application opens, but the call to the web service does not work.
Watching the call in Web Dev Helper, I see that the app was trying to call the service file, http://dellnov2006/Service1.svc, and is getting a 404 error.
So far, I've:
-In IIS mapped the .svc type to aspnet-isapi.dll
-Run the utility CleanIISScriptMaps
-Run aspnet_regiis.exe -i –enable
Any help would be appreciated - I am running out of ideas on this.
--
Here is the call back to the server, and the contents of the Service1.svc file:
private void Button_Click(object sender, RoutedEventArgs e)
{
// create a custom binding that uses HTTP and binary encoding
var elements = new List<BindingElement>();
elements.Add(new BinaryMessageEncodingBindingElement());
elements.Add(new HttpTransportBindingElement());
var binding = new CustomBinding(elements);
// create a channel factory for the service endpoint configured
// with custom binding
//var cf = new ChannelFactory<IService1>(binding,
// new EndpointAddress("http://localhost:1042/Service1.svc"));
var cf = new ChannelFactory<IService1>(binding,
new EndpointAddress("http://dellnov2006/Service1.svc"));
// save the syncronized context for the ui thread
uiThead = SynchronizationContext.Current;
// open the channel
IService1 channel = cf.CreateChannel();
// invoke the method asychrnoously
channel.BeginGetPerson(4, GetPersonCallback, channel);
}
Here are the contents of the svc file for what they are worth:
<%# ServiceHost Language="C#" Debug="true" Service="SilverlightChannelApp1.Web.Service1" CodeBehind="Service1.svc.cs" %>
Many thanks
Mike Thomas

Could be one of the following:
A problem with the web.config of the service. For example that localhost was part of the address.
That the service cannot find the dll which should be in the bin directory
Try browsing to the service with a web browser

Try adding the port number to the computer name. Whenever I'm testing local sites through a virtual machine that is always a necessity for me.
Change this:
new EndpointAddress("http://dellnov2006/Service1.svc"));
To this:
new EndpointAddress("http://dellnov2006:1042/Service1.svc"));

The solution to this was very simple, but it took both of your answers for me to think of
it.
Browsing to the service as suggested by Shiraz worked, so problem with calling service.
Suggestion to change endpoint address to include port # sounded good, but did not work.
Solution was to change:
new EndpointAddress("http://dellnov2006/Service1.svc"));
to this:
new EndpointAddress("http://dellnov2006/Silverlight/Service1.svc"));
where 'Silverlight' is the alias of the virtual directory. In other words, I open the app on IIS as 'http://dellnov2006/Silverlight/
Many thanks, I cannot believe how simple that was after so much time spent looking. I work alone and if it were not for this forum I'd be in serious trouble.
Mike Thomas

Related

How to run a WCF project locally?

I am trying to debug a WCF project. So can someone tell me a simple way to run this WCF project locally?
I loaded it in Visual Studio and when I tell it to run it says "A project of Output Type Class Library cannot be started." or something like that.
From there I come here, because I've exhausted my knowledge of WCF. Any answers may need to be severely "dumbed down".
This error simply means you have not set any start up project for WCF project. Try to set service host project as start up project if there is any. If you dont have any of them try to make service host project locally and add a reference to that project in your service host project.
A simple console hosting project will look like this
using System.ServiceModel;
namespace WcfDemoHost
{
class Program
{
static void Main(string[] args)
{
try
{
ServiceHost svchost = new ServiceHost(typeof(yourServiceClassNameHere));
svchost.Open();
Console.WriteLine("Service Started");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
there are also several method for hosting WCF services locally like hosting in Windows service, IIS, Console, in windows form etc.You also need to add App.config file for configuring your service like service endpoint and many things. I am providing you some youtube tutorial link that will help you a lot in understanding WCF. I hope this tutorial will help you a lot.
https://www.youtube.com/watch?v=QmfPmqMk9Xs&list=PL6n9fhu94yhVxEyaRMaMN_-qnDdNVGsL1
Go from part 3 and for hosting follow tutorial 24-30.
Rajput's answer may work, but another developer here showed me an easier way (for me). Our WCF project already has a hosting class (I did not know this). He showed me to set that as the startup project and then start the project. Then a browser window opens. I copy the URL that appears in that browser and paste that URL into the web.config endpoint settings like this:
<endpoint address="http://localhost:44798/ControlService.svc ...
Now I can step into the running code in the WCF project.
Set your WCF Service as Set As Startup Project and RUN project.
For testing, best way to check your methods through Postman tool instead of creating client for your WCF Service. You just need to take service URL like "http://localhost:35710/yourservicename.svc" after running your project and use in Postman.

Programmatically configure and host WCF Service in IIS

How can i programmatically configure and host WCF Service in IIS. I have created my WCF service example /WCFServices/Service1.svc". I want to programmatically configure and host this service in IIS. Can anyone help me on this?
The class you want is Microsoft.Web.Administration.ServerManager
http://msdn.microsoft.com/en-us/library/microsoft.web.administration.servermanager(v=VS.90).aspx
It has methods for manipulating most aspects of IIS, for example, adding application pools and applications. for example, this code configures a new IIS application
//the name of the IIS AppPool you want to use for the application - could be DefaultAppPool
string appPoolName = "MyAppPool";
//the name of the application (as it will appear in IIS manager)
string name = "MyWCFService";
//the physcial path of your application
string physicalPath = "C:\\wwwroot\mywcfservice";
using (ServerManager serverManager = new ServerManager())
{
Configuration config = serverManager.GetApplicationHostConfiguration();
ConfigurationSection sitesSection = config.GetSection("system.applicationHost/sites");
ConfigurationElementCollection sitesCollection = sitesSection.GetCollection();
ConfigurationElement siteElement = sitesCollection[0];
ConfigurationElementCollection siteCollection = siteElement.GetCollection();
ConfigurationElement applicationElement = siteCollection.CreateElement("application");
applicationElement["path"] = name;
applicationElement["applicationPool"] = appPoolName;
ConfigurationElementCollection applicationCollection = applicationElement.GetCollection();
ConfigurationElement virtualDirectoryElement = applicationCollection.CreateElement("virtualDirectory");
virtualDirectoryElement["path"] = #"/";
virtualDirectoryElement["physicalPath"] = physicalPath;
applicationCollection.Add(virtualDirectoryElement);
siteCollection.Add(applicationElement);
serverManager.CommitChanges();
}
In general, the calss is just a thin wrapper around the IIS config file. You can understand it by looking at your exisiting file, or even by looking at what you have to do in IIS Manager to configure the service manually, then translating that into the resulting configuration changes.
You can do all (at least lots of) the the IIS configuration in this way (e.g. configure application throttling, enable authentication schemes etc.).
The WCF part of the configuration is just normal WCF. you can do it either in code or in configuration.
What you are looking for is called Publish. You can find it from the right-click context menu on the WCF Service project. You can publish from there or create a package for publishing later or distributing it to a remote site. There are a lot of tutorials on the net.
If you have a specific question about this feature, feel free to ask.
Have a look at msdeploy, a command line packaging and deployment tool:
http://blogs.iis.net/msdeploy/
http://vishaljoshi.blogspot.de/2009/02/web-deployment-with-vs-2010-and-iis.html
http://msdn.microsoft.com/en-us/vs2010trainingcourse_webdevelopment_topic8#_Toc282089433

WCF NetNamedPipeBinding TimeoutException on Windows Server 2008

I have a problem with WCF NetNamedPipeBinding. When I run my server and client code through Visual Studio 2008 on a Windows XP machine everything works fine. But as soon as I deploy my server as a Windows Service and install my client app in Windows Server 2008 I get a TimeoutException on the client end whenever I try to use any of the contract methods. It seems that I can successfully create the client and open it, but can't call any of the methods.
Service initialisation code:
Uri baseAddress = new Uri("http://localhost:8500/xNet/xNetService");
string address = "net.pipe://localhost/xNet/xNetService";
_xNetAPIServiceHost = new ServiceHost(typeof(xNetService), baseAddress);
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
_xNetAPIServiceHost.AddServiceEndpoint(typeof(IServiceAPI), binding, address);
// Add a mex endpoint
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.HttpGetUrl = new Uri("http://localhost:8501/xNet/xNetService/mex");
_xNetAPIServiceHost.Description.Behaviors.Add(smb);
_xNetAPIServiceHost.Open();
Client initialisation code:
string address = "net.pipe://localhost/xNet/xNetService";
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
_serviceClient = new ServiceAPIClient(binding, new EndpointAddress(address));
_serviceClient.Open();
The Windows service runs as "Local System Account". I'm at a loss as to what the problem is. I don't know if it's a security account problem, or if the named pipe is even open? I would assume since I can successfully create and open the client side it would appear it at least found the named pipe. I just can't call any of the service methods without a TimeoutException.
After trying out various bindings and going back to basics I noticed that the sample programs worked, but mine didn't work unless I was using Visual Studio to debug. I decided at that point that it must be something going on with my own code. To simplify debugging I turned off all security in the binding.
I started commenting out most of the statements in my service's OnStart method in order to determine what could be going on. I commented out everything except for the code that initialises the ServiceHost. Magically, my client could now successfully communicate with the service. I then started uncommenting each line of code in the OnStart method until my client suddenly started giving me a TimeoutException again.
My service class, say "MyAPI", implements the contract "IMyAPI". As well as using "MyAPI" class as the WCF service, I was also using an instance of the "MyAPI" class internally in my service to do various things ("internal" methods). In my OnStart method I first created an instance of the "MyAPI" class and then created the ServiceHost:
MyAPI API = new MyAPI();
ServiceHost service = new ServiceHost(typeof(MyAPI));
I was not getting any errors or exceptions, so it appeared everything is fine, but really I couldn't connect to the service using a client. As soon as I changed the order of the above statements, the client started working again:
ServiceHost service = new ServiceHost(typeof(MyAPI));
MyAPI API = new MyAPI();
I'm not sure WHY this is occuring, all I know is that I can use my API internally and as a service without any client connection issues. Maybe someone out there will provide some light on the reasons behind this, or maybe my code is not properly designed.

can't enable net.tcp port sharing

I'm doing my dev work on a Window 7 x64 machine, deploying to a Windows 2008 x32 server. At the moment I'm adding WCF services to some internal apps so that we can build smaller clients using net.tcp bindings that report to the user what the server is doing without running multiple instances of the server. To cut back on how much administration the apps will require, I tried enabling port sharing on my first server app. I'm using the app to self-host the WCF service so they can be easily moved from one server to another if necessary. Here's the code starting the server:
Dim _service_host As ServiceHost
Dim active_server_address As Uri = New UriBuilder("net.tcp", "localhost", CInt(My.Settings.ServerPort)).Uri
_service_host = New ServiceHost(GetType(UpdateServiceOps), active_server_address)
_service_host.AddServiceEndpoint(GetType(IUpdateService), New NetTcpBinding With {.Name = "endpoint_tcp"}, "MiddlewareEndpoint")
_service_host.Description.Behaviors.Add(New ServiceMetadataBehavior)
_service_host.AddServiceEndpoint(GetType(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding, "mex")
_service_host.Open()
That works great. When I change it to what's below, however, I get an error. Here's the code:
Dim _service_host As ServiceHost
Dim active_server_address As Uri = New UriBuilder("net.tcp", "localhost", CInt(My.Settings.ServerPort)).Uri
_service_host = New ServiceHost(GetType(UpdateServiceOps), active_server_address)
_service_host.AddServiceEndpoint(GetType(IUpdateService), New NetTcpBinding With {.Name = "endpoint_tcp", .PortSharingEnabled = True}, "MiddlewareEndpoint")
_service_host.Description.Behaviors.Add(New ServiceMetadataBehavior)
_service_host.AddServiceEndpoint(GetType(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding, "mex")
_service_host.Open()
I get the following error when I put a breakpoint at the last line: Unable to automatically step into the server. Connecting to the server machine 'nettcpportsharing' failed. The requested name is valid, but no data of the requested type was found. The Try...Catch block housing that code says the exception type is AddressAlreadyInUseException...but when I run netstat I don't see anything else listening on that address. There's no occurrence of 'nettcpportsharing' anywhere in my solution. I've checked to make sure that the Net.Tcp Port Sharing service is started. Any ideas?
I think this may be a permissions issue. Please see the associated article which explains how to configure the port sharing service to support self-hosted services.
(For production purposes I would strongly recommend using IIS Hosting with WAS anyway - it makes management of the services much cleaner and you get dynamic startup/shutdown for free.)

Using a ReceiveActivity in a Sharepoint Workflow

I've made my first little workflow in sharepoint and I am trying to access it from the outside using a ReceiveActivity. I have created a WCF svc file with
and created a website in IIS with the same application pool as the sharepoint site.
Now I can start the workflow from my doclib, but when I try to reach the ReceiveActivity like below, I get the following error: "the workflow hosting environment does not have a persistence service as required by an operation on the workflow instance".
I think it has something to do with not using the Sharepoint persistence service in my own WCF website, but I'm not sure. Any idea's on this one???
DoMyThingContractClient proxy = new DoMyThingContractClient ();
IContextManager contextManager = proxy.InnerChannel.GetProperty<IContextManager>();
IDictionary<string, string> context = contextManager.GetContext();
context.Add("instanceId", myInstanceId);
contextManager.SetContext(context);
result = proxy.GetMyMethod(tb1.Text, tb2.Text);
Have you created the SQL tables that host the workflows? The ones at C:\Windows\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\en? If you did, you now need to add the required tags to your config (your WCF's folder with the svc file in this case) as explained at msdn.
Edit after comments: try to run a Persistance Service in your code:
SqlWorkflowPersistenceService ps = new SqlWorkflowPersistenceService("Initial Catalog=SqlPersistenceService;Data Source=localhost;Integrated Security=SSPI");
currentWorkflowRuntime.AddService(ps);