I'm writing a WCF service in Visual Studio 2008 to be hosted on a Windows 2008 Standard server.
I've created a new Web Site in IIS7 with its own application targeted to ASP.NET 2.0. I added .NET 3.0 Framework features to the server role. I've already gone through all of the steps involving *.svc extensions and the aspnet_isapi module. I've run "ServiceModelReg -r" and restarted IIS as well as the server itself.
My project targets the .NET framework 3.5 for builds. My solution references the project as a Web site using a UNC path to the server's Web directory. The project builds without errors and I can successfully add a service reference to my WCF service in my client project (on my Win XP development virtual machine). My client project builds and runs, but throws an exception during the service method (CheckDatabaseConnection) call. My web.config and service classes are attached below, followed by the client app. I've completely run out of ideas!
web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
<services>
<service behaviorConfiguration="ConnectivityBehavior" name="EDCO.Web.Services.Connectivity">
<endpoint address="http://validurl.net" binding="wsHttpBinding" contract="EDCO.Web.Services.IConnectivity">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ConnectivityBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
IConnectivity.cs:
[ServiceContract(Namespace="http://validurl.net")]
public interface IConnectivity
{
#region Methods
[WebGet()]
[WebInvoke(Method="GET")]
[OperationContract()]
bool CheckDatabaseConnection(string server, string database, string user, string password);
#endregion Methods
} // interface IConnectivity
Connectivity.svc.cs:
public class Connectivity : IConnectivity
{
#region Members
const string CONN_STRING = "Server={0};Database={1};User ID={2};Password={3};";
#endregion Members
#region Methods
public bool CheckDatabaseConnection(string server, string database, string user, string password)
{
SqlConnection conn = null;
try
{
conn = new SqlConnection(string.Format(CONN_STRING, server, database, user, password));
conn.Open();
}
catch
{
return false;
}
finally
{
if (conn != null)
{
if (conn.State != ConnectionState.Closed)
{
conn.Close();
}
conn.Dispose();
}
}
return true;
} // CheckDatabaseConnection(server, database, user, password)
#endregion Methods
} // class Connectivity
client Program.cs:
class Program
{
#region Methods
static void Main(string[] args)
{
Connectivity.ConnectivityClient connect = new Connectivity.ConnectivityClient();
Console.WriteLine("Establishing connection...");
if (connect.CheckDatabaseConnection("dbServer", "dbName", "login", "password"))
{
Console.WriteLine("Successful connection!");
}
else
{
Console.WriteLine("Connection failed.");
}
Console.ReadLine();
} // Main()
#endregion Methods
} // class Program
OK, it looks like I solved the problem by adding an identity element to my web.config. Oddly enough, this hasn't been one of the answers floating around on the Internet but I stumbled across it while looking at a nearly-unrelated article. The fix goes like this:
<service behaviorConfiguration="ConnectivityBehavior" name="EDCO.Web.Services.Connectivity">
<endpoint address="http://validurl.net/Connectivity.svc" binding="wsHttpBinding" contract="EDCO.Web.Services.IConnectivity">
<identity>
<dns value="validurl.net" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
Related
I have deployed WCF web service in IIS (remote-host: godaddy) and trying to consume through windows service. But getting below error when I try to consume via Windows Service.
"Exception: There was no endpoint listening at http://mydomainname.com/vfolder1/vfolder2/HelloService.svc/HelloService" that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
But when i consume the same service via Windows Form, it works without any issue.
Below is my WCF web service configuration (web.config)
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="HelloService.HelloService" behaviorConfiguration="mexBehaviour">
<endpoint address="HelloService" binding="basicHttpBinding" contract="HelloService.IHelloService"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
<host>
<baseAddresses>
<add baseAddress="http://mydomainname.com/vfolder1/vfolder2/"/>
</baseAddresses>
</host>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
Below is my WCF client configuration (app.config)
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IHelloService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://mydomainname.com/vfolder1/vfolder2/HelloService.svc/HelloService"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IHelloService"
contract="HelloService.IHelloService" name="BasicHttpBinding_IHelloService" />
</client>
</system.serviceModel>
Below is the code in Windows forms
private void button1_Click(object sender, EventArgs e)
{
HelloService.HelloServiceClient client = new HelloService.HelloServiceClient();
label1.Text = client.GetMessage(textBox1.Text);
}
Below is the code in Windows Service
public static void write_data()
{
try
{
HelloService.HelloServiceClient clNt = new HelloService.HelloServiceClient();
for (int i = 0; i < 10; i++)
{
Write_Log(clNt.GetMessage(i.ToString()));
}
clNt.Close();
}
catch (Exception ex)
{
Write_Log("Exception: " + ex.Message.ToString());
}
}
When we initially developed & hosted in local network (IIS), we never had any issues. This is our first project in WCF and involving remote host. Tried to look all similar posts but all were talking on complete non-working. Nothing similar to our scenario exists.
Appreciate the great help.
The issue is resolved. Our company policy wasn't allowing the service to communicate to internet when running under "Local System" privilege. I temporarily changed to run with my user credentials and it went through.
I'm develping a Metro application, and a WCF Data service hosted in a Windows Service using TCP. The Metro App will use this WCF service to consume data. I get the Windows Service host running so the WCF Service is available.
The problem is that running Metro App to test this configuration in my develop box I get System.ServiceModel.Security.SecurityNegotiationException. Inner exception is System.Security.AuthenticationException: "A call to SSPI failed, see inner exception.") , which in turn have this other inner exception too: System.ComponentModel.Win32Exception: "No credentials are available in the security package".
My Test environment:
Service contract:
[ServiceContract]
public interface IWCFDataService
{
[OperationContract]
Device GetDevice(string ip);
}
[DataContract]
public class Device
{
[DataMember]
public string Name { get; set; }
}
Service code:
public class WCFDataService : IWCFDataService
{
public Device GetDevice(string ip)
{
return new Device { Name = "Sample device" };
}
}
WCF Service configuration:
<system.serviceModel>
<services>
<service name="Apollo.DataService.WCFDataService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="Apollo.DataService.IWCFDataService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8523/WCFDataService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Metro Application consuming WCF Data Service:
var client = new DataService.WCFDataServiceClient();
var peripheral = await client.GetDevice("127.0.0.1"); <-- Throw Exception
UPDATE:
If I consume the WCF service from a Windows Form application every thing work fine, so the problem is something with Metro Application.
I googled for 2 days and tried almost everything, but I still can't get this stuff working.
I have 2 WCF services. I use self-hosting, not IIS(for some reasons IIS isn't working for me). One is duplex, another is standart. Here are their contracts:
Duplex:
[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IServiceCallback))]
public interface IClientService
{
[OperationContract(IsOneWay = true)]
void SolveTask(string pipelineName, string data);
[OperationContract(IsOneWay = true)]
void GenerateTask(List<GeneratorMethod> parameters);
[OperationContract]
bool Ping();
}
public interface IServiceCallback
{
[OperationContract(IsOneWay = true)]
void SendResult(SampleAnswer[] answers);
[OperationContract(IsOneWay = true)]
void RequestGeneratorParameters();
[OperationContract(IsOneWay = true)]
void SendGenerationResult(string text);
}
Classic:
[ServiceContract]
public interface IServerManagementService
{
[OperationContract]
[FaultContract(typeof(XmlError))]
[FaultContract(typeof(UnknownError))]
[FaultContract(typeof(InitializationError))]
void InitializeServer();
[OperationContract]
void StartServer();
[OperationContract]
void StopServer();
[OperationContract]
void RestartServer();
}
I have following config:
<configuration>
<services>
<service behaviorConfiguration="Service" name="LinProgWebServer.ClientService">
<endpoint address="net.tcp://localhost:8078/LinProgWebServer/ClientService"
binding="netTcpBinding" bindingConfiguration="netTcpEventBinding"
contract="LinProgWebServer.IClientService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/Design_Time_Addresses/LinProgWebServer/ClientService" />
</baseAddresses>
</host>
</service>
<!--сервис управления сервером-->
<!--<service behaviorConfiguration="Service" name="LinProgWebServer.ServerManagementService">
<endpoint address="net.tcp://localhost:8079/LinProgWebServer/ManagementService"
binding="netTcpBinding" bindingConfiguration="netTcpEventBinding"
contract="LinProgWebServer.IServerManagementService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/LinProgWebServer/ManagementService" />
</baseAddresses>
</host>
</service>-->
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Service">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Now i have a big trouble: I CAN find classic service via add service reference and CANNOT find duplex service. I tried netstat and it says that both services are listening on their ports. What am i doing wrong?
Here is exception i get:
There was an error downloading 'http://localhost:8731/Design_Time_Addresses/LinProgWebServer/ClientService/_vti_bin/ListData.svc/$metadata'.
The request failed with HTTP status 405: Method Not Allowed.
Metadata contains a reference that cannot be resolved: 'http://localhost:8731/Design_Time_Addresses/LinProgWebServer/ClientService'.
There was no endpoint listening at http://localhost:8731/Design_Time_Addresses/LinProgWebServer/ClientService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
The remote server returned an error: (404) Not Found.
If the service is defined in the current solution, try building the solution and adding the service reference again.
I'll be grateful for any help.
Make sure you .svc file has the correct name of the class you added in your Service Reference
if you added a service called 'Foo' it should look like:
<%# ServiceHost Language="C#" Debug="true" Service="Foo" CodeBehind="Foo.svc.cs" %
Also, make sure you have
In your web.config
I'm not sure whether this is going to be usefull. All my configs and services were fine, but i had a mistace in types, which were involved in work of wcf services, i haven't marked one of the types as datacontract. U'm very surprised why service started without erros and showed me such not informative messages. Also, thanks Yuval for reminding about InstanceContextMode attribute.
Add this to the area where you setup you set up your endpoint and reference your service classes:
//config service metadata
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
ServiceMetadataBehavior mb = new ServiceMetadataBehavior();
ServiceHost.Description.Behaviors.Add(mb);
if (bUseSSL) {
mb.HttpsGetEnabled = true;
mb.HttpGetEnabled = false;
ServiceHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpsBinding(), "mex");
} else {
mb.HttpsGetEnabled = false;
mb.HttpGetEnabled = true;
ServiceHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
}
You should not be using the same URL that you were using to host it in the dev environment. Localhost means nothing outside of the machine, anyway. Use the IP address of the machine and also -- you might have to use netsh to open the port on that machine.
using this example...Hosting WCF service inside a Windows Forms application ... with a Winform Application in 4.5 VS2012 in the form_Load()
it loads okay but can not access in Browser ... error can not access 'localhost'
private ServiceHost Host;
private void frmAdmin_Load(object sender, EventArgs e)
{
Host = new ServiceHost(typeof(bklvmain_v4.BTestService));
if (Host == null)
Host.Open();
}
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Host != null)
Host.Close();
}
App config...
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="bklvmain_v4.BTestServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="bklvmain_v4.BTestServiceBehavior"
name="bklvmain_v4.BTestService">
<endpoint address="" binding="wsHttpBinding" contract="bklvmain_v4.IBTestService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/BTestService/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
interface...
[ServiceContract]
public interface IBTestService
{
[OperationContract]
Tickers[] BTestLong(string dte);
[OperationContract]
Tickers[] BTestShort(string dte);
}
You're never opening the Host:
private void frmAdmin_Load(object sender, EventArgs e)
{
Host = new ServiceHost(typeof(bklvmain_v4.BTestService));
// if (Host == null)
// Could be if (Host != null), but the check is not required here anyways
Host.Open();
}
Since you had if (Host==null) as your check, and you just constructed the Host, the check will always fail and you'll never call .Open().
Thanks #Reed -- again.. and it seems like I may have been actually working but its difficult to tell - b'cause as I stated there were no web accessible service methods.... upon further experimentiation... (new word for 2014)... !! .ps.. my 2014 resolution is to NOT use 'but' 'however', 'I tell you what..', 'guess what', 'you know what', 'look', 'so..(beginning statement), or other overlooked dumb terminology... like 'anyway'... so, here goes again...upon further experimentiationology...(!!).. testing a wcf service in winform may be easier than we think but it's very difficult to find the right documentation.. how I know MS says just fire up a vs cmd prompt and load WCFTestClient.exe but why would anyone even know where a VS cmnd prompt existed.?? In deference to this, the location is in the 'Start -> 'Programs' bar under VS Tools and in fact, by running C:\WcfTestClient.exe and then including a modified endpoint address for the 'mex' configuration above <'http://localhost/mexBTestService'> is actually able to verify the service was running successfully !!! Have a Great and Wonderful New Year to All!! And happy coding !!
I am having some trouble hosting a WCF service inside a Windows Service.
I can start my WCF service in VS2008 and by navigating to the base address in my app.config
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="WCF.IndexerBehavior"
name="WCF.Indexer">
<endpoint address="" binding="wsHttpBinding" contract="WCF.IIndexer">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/WCFService/Action/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCF.IndexerBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I can see it works fine, I get the page saying I created a service and code samples on how to use it are shown.
Now my next step was to create a Windows Service to host my WCF shown above.
I just used te windows service template, it gave me a Program.cs and Service1.cs which I renamed to WindowsServiceHost.cs. In it I have:
private ServiceHost host;
public WindowsServiceHost()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
var serviceType = typeof(Indexer.WCF.Indexer);
host = new ServiceHost(serviceType);
host.Open();
}
catch (Exception ex)
{
}
}
protected override void OnStop()
{
if (host != null)
{
host.Close();
}
}
Everything compiles fine, I can run InstallUtil (I defined an installer).
The service used to start and stop immediately but disabling Windows Defender got rid of this.
Now the service starts (As a network service) and stays up (I think), but when I navigate to the base address, I get the not found page.
Another weird thing is when I try to stop the service (which is still displayed as running) I get:
Error 1061: The service cannot accept control messages at this time
I've tried everything but am at a loss.
Not 100% sure what the reason really is - just to confirm, we self-host WCF services in Windows services all the time and it generally works perfectly fine.
Two points you could try - just to get a feeling for the behavior and a potential clue for the problem:
1) I notice you open the ServiceHost with just the type of the service - that works, but you might still want to add a base address even to the call of the new ServiceHost() - like this:
host = new ServiceHost(serviceType,
new Uri("http://localhost:8181/WCFService/Action/");
Can you navigate to that address and get the service page??
2) The other thing I noticed is that your service seems to be called Indexer.WCF.Indexer as specified in the typeof() before opening the host, but in the config file, the name= on the <service> tag is only "WCF.Indexer".
Could you possibly try to change that tag to read:
<service behaviorConfiguration="WCF.IndexerBehavior"
name="Indexer.WCF.Indexer">
Does that help? Are you now able to see the service page when navigating to it in the browser?
Marc
Self-hosting HTTP in a Windows service may require registering the endpoint with HttpCfg.exe. Take a look here.
Try removing the catch statement, there may be an error that you are not seeing