简体   繁体   English

找不到引用合同的默认终结点元素(简单的WCF服务不起作用)

[英]Could not find default endpoint element that references contract (simple WCF Service not working)

The full error message: 完整的错误消息:

Could not find default endpoint element that references contract 'SampleProject.ITextMessage' in the ServiceModel client configuration section. 在ServiceModel客户端配置部分中找不到引用合同'SampleProject.ITextMessage'的默认终结点元素。 This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element. 这可能是因为找不到您的应用程序的配置文件,或者是因为在客户端元素中找不到与该协定匹配的端点元素。

This is a console app. 这是一个控制台应用程序。 Can't get much simpler from this. 由此无法简单得多。

No app config desired in this case , just looking to get a simple sample going. 在这种情况下不需要任何应用程序配置 ,只是希望获得一个简单的示例。 I pretty much lifted the code from here: http://msdn.microsoft.com/en-us/library/ms731758.aspx 我几乎从这里取消了代码: http : //msdn.microsoft.com/en-us/library/ms731758.aspx

Any help would be appreciated. 任何帮助,将不胜感激。

   public class SampleProject
    {
        static void Main(string[] args)
        {
            var baseAddr = new Uri("http://localhost:6000/TextMessageSvc.svc");

            using (var localHost = new ServiceHost(typeof(TextMessageClient), baseAddr))
            {
                try
                {
                    //THIS page says an endpoint is not needed, a default will be created automatically:
                    //http://msdn.microsoft.com/en-us/library/ms731758.aspx
                    localHost.AddServiceEndpoint(typeof(ITextMessage),
                                                 new WSHttpBinding(),
                                                 "TextMessageSvc");

                    var behavior = new ServiceMetadataBehavior();
                    behavior.HttpGetEnabled = true;
                    behavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;

                    localHost.Description.Behaviors.Add(behavior);
                    localHost.Open();

                    Console.WriteLine("Service initialized.");

                    //************** Blows up on this line ***********************
                    var x = new TextMessageClient();
                    x.SendTextMessage();

                    Console.WriteLine("Press the ENTER key to terminate service.");
                    Console.ReadLine();

                    localHost.Close();
                }
                catch (CommunicationException ex)
                {
                    Console.WriteLine("Oops! Exception: {0}", ex.Message);
                    localHost.Abort();
                }
            }
        }
    }

    public class TextMessageClient : ClientBase<ITextMessage>, ITextMessage
    {
        public void SendTextMessage()
        {
            base.Channel.SendTextMessage();
        }
    }

    [ServiceBehavior]
    public class TextMessageSvc : ITextMessage
    {
        public TextMessageSvc()
        {

        }

        [OperationBehavior]
        public void SendTextMessage()
        {

        }
    }

    [ServiceContract]
    public interface ITextMessage
    {
        [OperationContract]
        void SendTextMessage();
    }

So it turns out that the issue in this example is (since I'm not using a web config), that TextMessageClient does not have an endpoint . 因此,事实证明,此示例中的问题是(因为我没有使用Web配置),所以TextMessageClient没有端点 (localhost has one, but not TextMessageClient ) When I call SendTextMessage, how is it going to communicate? (本地主机有一个,但没有TextMessageClient )当我调用SendTextMessage时,它将如何通信? Who is it going to talk to?? 要和谁说话?

Well heck, I could create an endpoint and pass it into TextMessageClient, or just create one in its constructor, which I am now doing. 好吧,我可以创建一个端点并将其传递到TextMessageClient中,或者只在其构造函数中创建一个端点,而现在我正在这样做。

So after a renaming of TextMessageSvc to TextMessageProxy and then a refactor. 因此,将TextMessageSvc重命名为TextMessageProxy,然后进行重构。 This is all I now need (If you notice the new code is only consuming a service now, rather than attempting to host one as well: 这就是我现在所需要的 (如果您注意到新代码现在仅使用一种服务,而不是尝试同时托管一个服务:

I now have a function somewhere that sets up an endpoint for TextMessageClient to use. 我现在在某处有一个函数,该函数为TextMessageClient设置要使用的终结点。

var uri = _appSettings.Get("FredServiceURI");  //"http://localhost:3333/FredService.svc/"
var wcfSendTextMessage = new TextMessageProxy(uri);   

The TextMessage class now provides its own endpoint: 现在,TextMessage类提供了自己的终结点:

   public class TextMessageProxy : ClientBase<IFredContract>, IFredContract
    {
        public TextMessageProxy(string url, WebHttpSecurityMode securityMode = WebHttpSecurityMode.None)
            : base(ConstructEndpoint(url, securityMode))
        {
        }

        public string SendTextMessage(string sendToPhoneNumber, string messageText)
        {
            return base.Channel.SendTextMessage(sendToPhoneNumber, messageText);
        }

        // This method constructs a WebHttpBinding endpoint with all the appropriate
        // settings for talking to our services.
        private static ServiceEndpoint ConstructEndpoint(string serviceUri, WebHttpSecurityMode securityMode)
        {
            var contract = ContractDescription.GetContract(typeof(IFredContract));
            var binding = new WebHttpBinding(securityMode);

            var address = new EndpointAddress(serviceUri);
            var endpoint = new ServiceEndpoint(
                contract,
                binding,
                address);

            //custom stuff.  You may or may not need these settings, but I do.. 
            //I would think you need at least the behavior, as it is likely required, as it is in the web.config.
            //-------------
            var webHttpBehavior = new WebHttpBehavior()
            {
                FaultExceptionEnabled = true
            };

            endpoint.Behaviors.Add(webHttpBehavior);
            //-------------

            return endpoint;
        }
    }

Your base address is specifying a service page (TextMessageSvc.svc), so I doubt it's valid for a base address. 您的基地址指定了服务页面(TextMessageSvc.svc),所以我怀疑它对于基地址是否有效。 So when you add the endpoint, you're getting something like this: 因此,当您添加端点时,您将得到以下内容:

`http://localhost:6000/TextMessageSvc/TestMessage.svc/extMesssageSvc")`

Try this: 尝试这个:

var baseAddr = new Uri("http://localhost:6000/TextMessageSvc");  

Also, be aware that default endpoints (as you seem to be using them) are a feature of WCF 4.0 (.NET 4.0/VS 2010), and not available in previous versions. 另外,请注意,默认终结点(似乎在使用它们)是WCF 4.0(.NET 4.0 / VS 2010)的功能,并且在以前的版本中不可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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