这是我为测试服务调用其他服务而构建的示例项目
这是由其他服务调用的服务
namespace WCFPub
{
[ServiceContract]
public interface IStudent
{
[OperationContract]
string getName(string name);
}
}
namespace WCFPub
{
public class Student : IStudent
{
public string getName(string name)
{
return "Your name is " + name;
}
}
}
托管上述服务的控制台应用程序
namespace WCFHost
{
class Program
{
static void Main(string[] args)
{
try
{
ServiceHost sh = new ServiceHost(typeof(WCFPub.Student));
ServiceMetadataBehavior serviceMetadataBehaviour = new ServiceMetadataBehavior()
{
HttpGetEnabled = true,
};
sh.Description.Behaviors.Add(serviceMetadataBehaviour);
sh.AddServiceEndpoint(typeof(WCFPub.IStudent), new WSDualHttpBinding(), "PS");
Console.WriteLine("Host Ready, Listening on 7060");
Console.WriteLine("Hit Enter to Stop..");
sh.Open();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
调用第二项服务的服务
namespace WCFPub2
{
[ServiceContract]
public interface IMaster
{
[OperationContract]
string getNameFromStudent(string name);
}
}
namespace WCFPub2
{
public class Master : IMaster
{
public string getNameFromStudent(string name)
{
Proxy2.StudentClient client = new Proxy2.StudentClient();
return client.getName("ABdi");
}
}
}
托管上述服务的控制台应用
namespace WCFHost2
{
class Program
{
static void Main(string[] args)
{
try
{
ServiceHost sh = new ServiceHost(typeof(WCFPub2.Master));
ServiceMetadataBehavior serviceMetadataBehaviour = new ServiceMetadataBehavior()
{
HttpGetEnabled = true,
};
sh.Description.Behaviors.Add(serviceMetadataBehaviour);
sh.AddServiceEndpoint(typeof(WCFPub2.IMaster), new WSDualHttpBinding(), "PS");
Console.WriteLine("Host Ready, Listening on 7061");
Console.WriteLine("Hit Enter to Stop..");
sh.Open();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
客户
namespace WCFClient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Proxy.MasterClient client = new Proxy.MasterClient();
MessageBox.Show(client.getNameFromStudent("ABdi"));
}
}
}
这不起作用并抛出异常
System.ServiceModel.FaultException`1 [System.ServiceModel.ExceptionDetail]:
无法在ServiceModel客户端配置部分中找到引用合同“Proxy2.IStudent”的默认端点元素。这可能是因为没有为您的应用程序找到配置文件,或者因为在客户端元素中找不到与此合同匹配的端点元素。
(故障详细信息等于ExceptionDetail,可能由IncludeExceptionDetailInFaults = true创建,其值为:
System.InvalidOperationException:无法在ServiceModel客户端配置部分中找到引用合同“Proxy2.IStudent”的默认端点元素。这可能是因为没有为您的应用程序找到配置文件,或者因为在客户端元素中找不到与此合同匹配的端点元素。在System.ServiceModel.Description.ConfigLoader.LoadChannelBehaviors(ServiceEndpoint serviceEndpoint,String configurationName)
在System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName,Configuration configuration)
在System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName)
at System.ServiceModel.ChannelFactory.InitializeEndpoint(String configurationName,EndpointAddress address)
在System.ServiceModel.ChannelFactory`1..ctor(String endpointConfigurationName,EndpointAddress remoteAddress)
在System.ServiceModel.Configu ...)。
我需要帮助
答案 0 :(得分:0)
我不知道你在哪里指定服务和客户的地址(我不知道如何。主机=新的ServiceHost(新的Service.BossService(), baseUrl ) ;或新的Proxy.MasterClient(endpointConfiguraionName)或Proxy.MasterClient(binding,baseAddress))。 如果您在任何地方使用配置文件(其中包含地址),那么您不需要任何额外的步骤来设置服务(Behaviors.Add,... AddServiceEndpoint) - 所有服务创建步骤都将使用config自动执行。 / p>
我的建议:
1)删除所有服务托管代码,仅使用基于配置文件的配置(包括基址,如果您以* .svc或绝对托管,则可以是相对的)。这是更加灵活和方便的方式(如果你有可能使用配置文件,有时你不会有) - 我用了多年。见simple wcf configuration example)
2)使用单一实例(更可预测)。
最后,您将只有一行代码,例如Host = new ServiceHost(new MyService())
。
3)不要使用generated(svcutil)wcf客户端代码。只需在服务和客户之间共享合同库(服务合同,数据合同)。然后使用ChannelFactory调用服务方法:Channel = new ChannelFactory<MyService>("bindingConfigurationName").CreateChannel()
或new ChannelFactory<MyService>(binding, serviceAddress).CreateChannel()
。这很好,足以同步调用服务方法(通过一些额外的工作,您甚至可以通过了解和使用简单的同步服务接口来异步调用服务方法!)
4)不要使用WSDualHttpBinding - 它不能正常工作(至少在互联网和防火墙上)。我建议使用tcpbinding(双工本质,几乎无处不在)。但是,如果您使用WSDualHttpBinding - 为什么不使用双向方法(双工合同,请参阅example)?
5)使用标准客户端测试服务,例如wcftestclient,SoapUI,甚至是fiddler或postman(用于RESTful服务)。