如果我将此代码用于控制台应用程序中的self Host WCF服务,它将正常工作。我运行主机应用程序,然后从另一个应用程序(我称之为客户端应用程序)添加服务引用,方法是:从visual studio >解决方案资源管理器>添加服务引用> http://10.131.131.14:8080/sendKioskMessage >单击“转到”,毫无问题地添加服务并从客户端应用程序(这是一个windows窗体)使用它。
但是,如果我在Windows窗体中运行相同的代码,我首先运行(自身宿主WCF) windows窗体应用程序,然后从visual studio中的另一个应用程序(客户端应用程序)尝试从解决方案资源管理器中的添加服务引用添加服务引用(与以前的工作方式相同,但使用控制台应用程序自身宿主),但它抛出了以下错误:
*
尝试在http://10.131.131.14:8080/sendKioskMessage查找服务时发生
错误(详细信息)。
(如果我单击详细信息链接,将显示以下内容:)
下载'http://10.131.131.14:8080/sendKioskMessage/$metadata‘时出错。无法连接到远程服务器。元数据包含无法解析的引用:“http://10.131.131.14:8080/sendKioskMessage”。在http://10.131.131.14:8080/sendKioskMessage上没有侦听可以接受消息的终结点。这通常是由不正确的地址或SOAP操作引起的。有关更多详细信息,请参阅InnerException。无法连接到远程服务器。如果服务是在当前解决方案中定义的,请尝试生成解决方案并再次添加服务引用。
*
我使用的IP是运行这两个应用程序的pc的IP。我也使用localhost而不是我的实际IP,结果是相同的。
Windows窗体代码(无法从其他应用程序添加服务):
public partial class KioskosServerForm : Form
{
[ServiceContract]
public interface IKioskMessageService
{
[OperationContract]
string SendKioskMessage(string message);
}
public class KioskMessageService : IKioskMessageService
{
public string SendKioskMessage(string message)
{
return string.Format("Message sent: {0}", message);
}
}
public KioskosServerForm()
{
InitializeComponent();
}
private void KioskosServerForm_Load(object sender, EventArgs e)
{
Uri baseAddress = new Uri("http://10.131.131.14:8080/sendKioskMessage");
try
{
// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(KioskMessageService), baseAddress))
{
// Enable metadata publishing.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
// 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.
host.Open();
}
}
catch (Exception exp)
{
MessageBox.Show(exp.InnerException.Message);
}
}
}
控制台应用程序代码(有效!我可以从其他客户端应用程序添加服务):
[ServiceContract]
public interface IKioskMessageService
{
[OperationContract]
string SendKioskMessage(string message);
}
public class KioskMessageService : IKioskMessageService
{
public string SendKioskMessage(string message)
{
return string.Format("Message sent: {0}", message);
}
}
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("http://localhost:8080/sendKioskMessage");
// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(KioskMessageService),baseAddress))
{
// Enable metadata publishing.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
// 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.
host.Open();
Console.WriteLine("The service is ready at {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();
// Close the ServiceHost.
host.Close();
}
}
}
如果服务是在控制台应用程序中自托管的,我不知道为什么我可以使用该服务,但如果服务是在Windows窗体中自托管的,我不能添加它。
我将非常感谢您的帮助来实现这一点从Windows从,因为我需要自己托管的WCF服务从一个windows窗体,没有一个控制台应用程序。
我使用的是Visual Studio 2017,.Net框架4.6.1
提前感谢各位!
发布于 2018-09-27 07:21:24
TL;DR控制台应用程序之所以能工作,是因为您在关闭服务之前有延迟;而WinForms主机则不能
host.Open();
Console.WriteLine("The service is ready at {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine(); // <-------- program waits here
// Close the ServiceHost.
host.Close();
服务被中断的...after。在此之前,您的其他客户端可以很好地连接并添加服务引用。
WinForms应用程序没有这样的延迟:
private void KioskosServerForm_Load(object sender, EventArgs e)
{
Uri baseAddress = new Uri("http://10.131.131.14:8080/sendKioskMessage");
try
{
// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(KioskMessageService), baseAddress))
{
// Enable metadata publishing.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
// 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.
host.Open(); // <------ opened here
} // <------ shutdown here
}
catch (Exception exp)
{
MessageBox.Show(exp.InnerException.Message);
}
}
当代码超出using
块的作用域时,...it会立即关闭。using
将自动调用host
对象上的Dispose()
,该对象依次调用Close()
。
考虑将主机放入一个变量中,如下所示:
ServiceHost _host; // <---------- new!
private void KioskosServerForm_Load(object sender, EventArgs e)
{
Uri baseAddress = new Uri("http://10.131.131.14:8080/sendKioskMessage");
try
{
// Create the ServiceHost.
_host = new ServiceHost(typeof(KioskMessageService), baseAddress))
// Enable metadata publishing.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
_host.Description.Behaviors.Add(smb);
// 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.
_host.Open();
}
catch (Exception exp)
{
MessageBox.Show(exp.InnerException.Message);
}
}
稍后,您可以通过调用Close
来关闭_host
实例。
https://stackoverflow.com/questions/52527074
复制相似问题