C# 以编程方式创建的web服务在客户端服务调用时失败

C# 以编程方式创建的web服务在客户端服务调用时失败,c#,.net,web-services,wcf,ssl,C#,.net,Web Services,Wcf,Ssl,我创建了一个控制台应用程序项目,以编程方式托管web服务,但当我尝试为web服务创建一个客户端代理并对其调用一个方法时,出现以下错误: 向发出HTTP请求时出错 . 这可能是因为 服务器证书未使用HTTP.SYS正确配置 在HTTPS案例中。这也可能是由于 客户端和服务器之间的安全绑定 其内部例外: 基础连接已关闭:上发生意外错误 一封信 其内部例外: 无法从传输连接读取数据:现有 远程主机已强制关闭连接 其内部例外: 远程主机已强制关闭现有连接 程序.cs: class Program {

我创建了一个控制台应用程序项目,以编程方式托管web服务,但当我尝试为web服务创建一个客户端代理并对其调用一个方法时,出现以下错误:

向发出HTTP请求时出错 . 这可能是因为 服务器证书未使用HTTP.SYS正确配置 在HTTPS案例中。这也可能是由于 客户端和服务器之间的安全绑定

其内部例外:

基础连接已关闭:上发生意外错误 一封信

其内部例外:

无法从传输连接读取数据:现有 远程主机已强制关闭连接

其内部例外:

远程主机已强制关闭现有连接

程序.cs

class Program
{
    static void Main(string[] args)
    {
        var address = "https://localhost:8000/FileRetrievalPoC";
        Console.WriteLine("Starting a service at {0}...", address);
        FileRetrievalService.Start(address, StoreLocation.LocalMachine, StoreName.My, "localhost");
        Console.WriteLine("Service started.");
        Console.WriteLine("Press Enter to create a new proxy client and call the Get method.");
        Console.WriteLine("Press Escape to end the application.");
        while (true)
        {
            var key = Console.ReadKey();
            if (key.Key == ConsoleKey.Enter)
            {
                var proxy = FileRetrievalService.Connect(address, "localhost", "exampleUsername", "examplePassword", StoreLocation.LocalMachine, StoreName.My, "localhost");
                proxy.Get(@"C:\Users\User\Desktop\Document.txt");
                ((IClientChannel)proxy).Close();
            }
            else if (key.Key == ConsoleKey.Escape)
                break;
        }
        FileRetrievalService.Stop();
    }
}
[ServiceContract]
public interface IFileRetrieval
{
    [OperationContract]
    string Get(string path);
    [OperationContract]
    void Set(string path, string contents);
}
class FileRetrievalService : IFileRetrieval
{

    private static BasicHttpsBinding _binding = new BasicHttpsBinding()
    {
        Name = "FileRetrievalPoC",
        HostNameComparisonMode = HostNameComparisonMode.Exact,
        Security = new BasicHttpsSecurity()
        {
            Message = new BasicHttpMessageSecurity()
            {
                AlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256Rsa15,
                ClientCredentialType = BasicHttpMessageCredentialType.UserName
            },
            Mode = BasicHttpsSecurityMode.TransportWithMessageCredential,
            Transport = new HttpTransportSecurity()
            {
                ClientCredentialType = HttpClientCredentialType.Windows
            }
        },
        SendTimeout = TimeSpan.FromMinutes(1),
        CloseTimeout = TimeSpan.FromMinutes(1),
        OpenTimeout = TimeSpan.FromMinutes(1),
        ReceiveTimeout = TimeSpan.FromMinutes(1)
    };
    private static ChannelFactory<IFileRetrieval> _channelFactory;
    private static ServiceHost _host;

    public static void Start(string address, StoreLocation location, StoreName name, string subject)
    {
        _host = new ServiceHost(typeof(FileRetrievalService));
        _host.Credentials.ServiceCertificate.SetCertificate(location, name, X509FindType.FindBySubjectName, subject);
        _host.AddServiceEndpoint(typeof(IFileRetrieval), _binding, address);
        _host.Open();
    }

    public static void Stop()
    {
        if (_host != null)
            _host.Close();
        if (_channelFactory != null)
            _channelFactory.Close();
    }

    public static IFileRetrieval Connect(string address, string domain, string username, string password, StoreLocation location, StoreName name, string subject)
    {
        if (_channelFactory == null)
            _channelFactory = new ChannelFactory<IFileRetrieval>(_binding, address);
        _channelFactory.Credentials.ClientCertificate.SetCertificate(location, name, X509FindType.FindBySubjectName, subject);
        _channelFactory.Credentials.UserName.UserName = username;
        _channelFactory.Credentials.UserName.Password = password;
        _channelFactory.Credentials.Windows.ClientCredential = new NetworkCredential(username, password, domain);
        return _channelFactory.CreateChannel();
    }

    public string Get(string path)
    {
        throw new NotImplementedException();
    }

    public void Set(string path, string contents)
    {
        throw new NotImplementedException();
    }
}
IFileRetrieval.cs

class Program
{
    static void Main(string[] args)
    {
        var address = "https://localhost:8000/FileRetrievalPoC";
        Console.WriteLine("Starting a service at {0}...", address);
        FileRetrievalService.Start(address, StoreLocation.LocalMachine, StoreName.My, "localhost");
        Console.WriteLine("Service started.");
        Console.WriteLine("Press Enter to create a new proxy client and call the Get method.");
        Console.WriteLine("Press Escape to end the application.");
        while (true)
        {
            var key = Console.ReadKey();
            if (key.Key == ConsoleKey.Enter)
            {
                var proxy = FileRetrievalService.Connect(address, "localhost", "exampleUsername", "examplePassword", StoreLocation.LocalMachine, StoreName.My, "localhost");
                proxy.Get(@"C:\Users\User\Desktop\Document.txt");
                ((IClientChannel)proxy).Close();
            }
            else if (key.Key == ConsoleKey.Escape)
                break;
        }
        FileRetrievalService.Stop();
    }
}
[ServiceContract]
public interface IFileRetrieval
{
    [OperationContract]
    string Get(string path);
    [OperationContract]
    void Set(string path, string contents);
}
class FileRetrievalService : IFileRetrieval
{

    private static BasicHttpsBinding _binding = new BasicHttpsBinding()
    {
        Name = "FileRetrievalPoC",
        HostNameComparisonMode = HostNameComparisonMode.Exact,
        Security = new BasicHttpsSecurity()
        {
            Message = new BasicHttpMessageSecurity()
            {
                AlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256Rsa15,
                ClientCredentialType = BasicHttpMessageCredentialType.UserName
            },
            Mode = BasicHttpsSecurityMode.TransportWithMessageCredential,
            Transport = new HttpTransportSecurity()
            {
                ClientCredentialType = HttpClientCredentialType.Windows
            }
        },
        SendTimeout = TimeSpan.FromMinutes(1),
        CloseTimeout = TimeSpan.FromMinutes(1),
        OpenTimeout = TimeSpan.FromMinutes(1),
        ReceiveTimeout = TimeSpan.FromMinutes(1)
    };
    private static ChannelFactory<IFileRetrieval> _channelFactory;
    private static ServiceHost _host;

    public static void Start(string address, StoreLocation location, StoreName name, string subject)
    {
        _host = new ServiceHost(typeof(FileRetrievalService));
        _host.Credentials.ServiceCertificate.SetCertificate(location, name, X509FindType.FindBySubjectName, subject);
        _host.AddServiceEndpoint(typeof(IFileRetrieval), _binding, address);
        _host.Open();
    }

    public static void Stop()
    {
        if (_host != null)
            _host.Close();
        if (_channelFactory != null)
            _channelFactory.Close();
    }

    public static IFileRetrieval Connect(string address, string domain, string username, string password, StoreLocation location, StoreName name, string subject)
    {
        if (_channelFactory == null)
            _channelFactory = new ChannelFactory<IFileRetrieval>(_binding, address);
        _channelFactory.Credentials.ClientCertificate.SetCertificate(location, name, X509FindType.FindBySubjectName, subject);
        _channelFactory.Credentials.UserName.UserName = username;
        _channelFactory.Credentials.UserName.Password = password;
        _channelFactory.Credentials.Windows.ClientCredential = new NetworkCredential(username, password, domain);
        return _channelFactory.CreateChannel();
    }

    public string Get(string path)
    {
        throw new NotImplementedException();
    }

    public void Set(string path, string contents)
    {
        throw new NotImplementedException();
    }
}
文件检索服务.cs

class Program
{
    static void Main(string[] args)
    {
        var address = "https://localhost:8000/FileRetrievalPoC";
        Console.WriteLine("Starting a service at {0}...", address);
        FileRetrievalService.Start(address, StoreLocation.LocalMachine, StoreName.My, "localhost");
        Console.WriteLine("Service started.");
        Console.WriteLine("Press Enter to create a new proxy client and call the Get method.");
        Console.WriteLine("Press Escape to end the application.");
        while (true)
        {
            var key = Console.ReadKey();
            if (key.Key == ConsoleKey.Enter)
            {
                var proxy = FileRetrievalService.Connect(address, "localhost", "exampleUsername", "examplePassword", StoreLocation.LocalMachine, StoreName.My, "localhost");
                proxy.Get(@"C:\Users\User\Desktop\Document.txt");
                ((IClientChannel)proxy).Close();
            }
            else if (key.Key == ConsoleKey.Escape)
                break;
        }
        FileRetrievalService.Stop();
    }
}
[ServiceContract]
public interface IFileRetrieval
{
    [OperationContract]
    string Get(string path);
    [OperationContract]
    void Set(string path, string contents);
}
class FileRetrievalService : IFileRetrieval
{

    private static BasicHttpsBinding _binding = new BasicHttpsBinding()
    {
        Name = "FileRetrievalPoC",
        HostNameComparisonMode = HostNameComparisonMode.Exact,
        Security = new BasicHttpsSecurity()
        {
            Message = new BasicHttpMessageSecurity()
            {
                AlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256Rsa15,
                ClientCredentialType = BasicHttpMessageCredentialType.UserName
            },
            Mode = BasicHttpsSecurityMode.TransportWithMessageCredential,
            Transport = new HttpTransportSecurity()
            {
                ClientCredentialType = HttpClientCredentialType.Windows
            }
        },
        SendTimeout = TimeSpan.FromMinutes(1),
        CloseTimeout = TimeSpan.FromMinutes(1),
        OpenTimeout = TimeSpan.FromMinutes(1),
        ReceiveTimeout = TimeSpan.FromMinutes(1)
    };
    private static ChannelFactory<IFileRetrieval> _channelFactory;
    private static ServiceHost _host;

    public static void Start(string address, StoreLocation location, StoreName name, string subject)
    {
        _host = new ServiceHost(typeof(FileRetrievalService));
        _host.Credentials.ServiceCertificate.SetCertificate(location, name, X509FindType.FindBySubjectName, subject);
        _host.AddServiceEndpoint(typeof(IFileRetrieval), _binding, address);
        _host.Open();
    }

    public static void Stop()
    {
        if (_host != null)
            _host.Close();
        if (_channelFactory != null)
            _channelFactory.Close();
    }

    public static IFileRetrieval Connect(string address, string domain, string username, string password, StoreLocation location, StoreName name, string subject)
    {
        if (_channelFactory == null)
            _channelFactory = new ChannelFactory<IFileRetrieval>(_binding, address);
        _channelFactory.Credentials.ClientCertificate.SetCertificate(location, name, X509FindType.FindBySubjectName, subject);
        _channelFactory.Credentials.UserName.UserName = username;
        _channelFactory.Credentials.UserName.Password = password;
        _channelFactory.Credentials.Windows.ClientCredential = new NetworkCredential(username, password, domain);
        return _channelFactory.CreateChannel();
    }

    public string Get(string path)
    {
        throw new NotImplementedException();
    }

    public void Set(string path, string contents)
    {
        throw new NotImplementedException();
    }
}
class FileRetrievalService:IFileRetrieval
{
私有静态BasicHttpsBinding _binding=new BasicHttpsBinding()
{
Name=“FileRetrievalPoC”,
HostNameComparisonMode=HostNameComparisonMode.Exact,
Security=new basichtpssecurity()
{
Message=new BasicHttpMessageSecurity()
{
AlgorithmSuite=SecurityAlgorithmSuite.Basic256Sha256Rsa15,
ClientCredentialType=BasicHttpMessageCredentialType.UserName
},
模式=BasicHttpsSecurityMode.TransportWithMessageCredential,
传输=新的HttpTransportSecurity()
{
ClientCredentialType=HttpClientCredentialType.Windows
}
},
SendTimeout=TimeSpan.FromMinutes(1),
CloseTimeout=TimeSpan.FromMinutes(1),
OpenTimeout=TimeSpan.FromMinutes(1),
ReceiveTimeout=TimeSpan.FromMinutes(1)
};
私人静态信道工厂(信道工厂);;
私有静态服务主机_主机;
公共静态无效开始(字符串地址、StoreLocation位置、StoreName名称、字符串主题)
{
_主机=新服务主机(typeof(FileRetrievalService));
_host.Credentials.ServiceCertificate.SetCertificate(位置、名称、X509FindType.FindBySubjectName、主题);
_AddServiceEndpoint(typeof(IFileRetrieval),\u绑定,地址);
_host.Open();
}
公共静态无效停止()
{
如果(_host!=null)
_host.Close();
如果(_channelFactory!=null)
_channelFactory.Close();
}
公共静态IFileRetrieval连接(字符串地址、字符串域、字符串用户名、字符串密码、StoreLocation位置、StoreName名称、字符串主题)
{
如果(_channelFactory==null)
_channelFactory=新的channelFactory(_绑定,地址);
_channelFactory.Credentials.ClientCertificate.SetCertificate(位置、名称、X509FindType.FindBySubjectName、主题);
_channelFactory.Credentials.UserName.UserName=用户名;
_channelFactory.Credentials.UserName.Password=密码;
_channelFactory.Credentials.Windows.ClientCredential=新的网络凭据(用户名、密码、域);
返回_channelFactory.CreateChannel();
}
公共字符串获取(字符串路径)
{
抛出新的NotImplementedException();
}
公共无效集(字符串路径、字符串内容)
{
抛出新的NotImplementedException();
}
}
这一切都是通过编程完成的,我已经查看了堆栈溢出,但找不到发生这种情况的原因。有人知道问题出在哪里吗?这段源代码,您可以添加到一个新的控制台应用程序,并运行它在您的本地机器上进行试验,并亲眼目睹它的发生。是SSL证书吗?如果是这样的话,我怎样才能得到更多关于错误原因的详细信息呢?这不是一个非常有用的例外

编辑:我想我可能错过了这一步。

我的问题是。打开管理命令提示符并调用:

netsh http add sslcert ipport=0.0.0.0:8000 appid=<A randomly generated GUID for your application> certhash=<Your localhost certificate's thumbprint from the default MY store, which is under Local Machine -> Personal, which you can get from the MMC Certificates snap-in>
netsh http add sslcert ipport=0.0.0.0:8000 appid=certhash=