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. 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开发者_如何学Python, 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
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. (localhost has one, but not TextMessageClient) When I call SendTextMessage, how is it going to communicate? 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.
So after a renaming of TextMessageSvc to TextMessageProxy and then a refactor. 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.
var uri = _appSettings.Get("FredServiceURI"); //"http://localhost:3333/FredService.svc/"
var wcfSendTextMessage = new TextMessageProxy(uri);
The TextMessage class now provides its own endpoint:
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. 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.
精彩评论