简体   繁体   中英

Can't access service Windows 7 self-hosted WCF app on a non-domain

Trying to run a self-hosted app on my Win 7 system, with little success. The app starts up but I can't access it from WCF Test Client or by adding a reference in VS. I've read what seems like 1000 posts about similar problems, but none of the solutions seem to fit.

I did this:

netsh http add urlacl url=http://+:9090/hello user=LocalPC\UserName

And then this:

netsh http add iplisten ipaddress=0.0.0.0:9090

Here's the code to do the

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
        Uri baseAddress = new Uri("http://localhost:9090/hello");

        // Create the ServiceHost.
        using (ServiceHost host = new ServiceHost(typeof(HelloWorldService), baseAddress))
        {
            // Enable metadata publishing.
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(smb);

            // Add MEX endpoint
            host.AddServiceEndpoint(
              ServiceMetadataBehavior.MexContractName,
              MetadataExchangeBindings.CreateMexHttpBinding(),
              "mex");

            // Add application endpoint
            host.AddServiceEndpoint(typeof(IHelloWorldService), new WSHttpBinding(), "");                

            // Open the ServiceHost to start listening for messages. Since
            // no endpoints are explicitly configured, the runtime will create
            // one endpoint per base address for each service contract implemented
            // by the service.
            try
            {
                host.Open();
            }
            catch (Exception excep)
            {
                string s = excep.Message;
            }
        }
    }

When I try to access from WCF Test Client I get:

Error: Cannot obtain Metadata from http://localhost:9090/hello 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:9090/hello
Metadata contains a reference that cannot be resolved: 'http://localhost:9090/hello'.
There was no endpoint listening at http://localhost:9090/hello 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 No connection could be made because the target machine actively refused it 127.0.0.1:9090
HTTP GET Error URI: http://localhost:9090/hello There was an error downloading 'http://localhost:9090/hello'. Unable to connect to the remote server No connection could be made because the target machine actively refused it 127.0.0.1:9090

When I try to add a service reference I get:

There was an error downloading 'http://localhost:9090/hello'.
Unable to connect to the remote server
No connection could be made because the target machine actively refused it
127.0.0.1:9090
Metadata contains a reference that cannot be resolved: 'http://localhost:9090/hello'.
There was no endpoint listening at http://localhost:9090/hello 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
No connection could be made because the target machine actively refused it 127.0.0.1:9090
If the service is defined in the current solution, try building the solution and adding the service reference again.

The problem is that you are letting the ServiceHost go out of scope immediately.

The using statement is there as a convenience to do cleanup when that block of code goes out of scope, but you have nothing in place to prevent that. So in essence you are opening the connection, but then it is being disposed almost instantly... which closes the connection.

So long as you don't run into any permissions issues, this approach should work for you. That being said, this is just demo-ware. In reality you probably don't want your WCF service tied directly to your form, but rather defined at the application level.

public partial class WcfHost : Form
{
    private ServiceHost _svcHost;
    private Uri _svcAddress = new Uri("http://localhost:9001/hello");

    public WcfHost()
    {
        _svcHost = new ServiceHost(typeof(HelloWorldService), _svcAddress);

        ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
        smb.HttpGetEnabled = true;
        smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
        _svcHost.Description.Behaviors.Add(smb);

        InitializeComponent();

        FormClosing += WcfHost_FormClosing;
    }

    private void WcfHost_Load(object sender, EventArgs e)
    {
        try
        {
            _svcHost.Open(TimeSpan.FromSeconds(10));
            lblStatus.Text = _svcHost.State.ToString();
        }
        catch(Exception ex)
        {
            lblStatus.Text = ex.Message;
        }            
    }

    void WcfHost_FormClosing(object sender, FormClosingEventArgs e)
    {
        _svcHost.Close();

        lblStatus.Text = _svcHost.State.ToString();
    }
}

[ServiceContract]
public interface IHelloWorldService
{
    [OperationContract]
    string SayHello(string name);
}

public class HelloWorldService : IHelloWorldService
{
    public string SayHello(string name)
    {
        return string.Format("Hello, {0}", name);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM