Can't Add Service Reference to self-hosted WCF Service
I've created a REST web service that I need to consume from within an asp.net app. The service is hosted from a console window. I can get it running fine, and I can get output from it as well when surfing to it in a web browser. The problem is, when I try to "Add Service Reference" from my asp.net app, it complains of various things depending on which service URL I point it at. End result is I cannot figure out how to add the servi开发者_如何学编程ce reference.
My Interface is defined like so:
[ServiceContract]
public interface IWave {
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/devices")]
List<Device> getDevices();
...
}
Here's how I'm hosting my service:
// Port is 1178
var endPoint = new EndpointAddress(string.Format("http://localhost:{0}/wave", port));
var waveServiceSingleton = new WaveSVC();
binding = new WebHttpBinding();
var behavior = new WebHttpBehavior();
behavior.FaultExceptionEnabled = true;
host = new WebServiceHost(waveServiceSingleton, endPoint.Uri);
// Get the service debug behavior and tell it to include details about errors
ServiceDebugBehavior sdb;
sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>();
sdb.IncludeExceptionDetailInFaults = true;
host.AddServiceEndpoint(typeof(IWave), binding, "");
// Add mex endpoint
ServiceMetadataBehavior mexBehavior = new ServiceMetadataBehavior();
mexBehavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(mexBehavior);
host.AddServiceEndpoint(typeof(IWave), MetadataExchangeBindings.CreateMexHttpBinding(), endPoint.Uri.AbsoluteUri + "/mex");
host.Open();
When I browse to http://localhost:1180/wave/devices, I see a json string in the body of my browser. This is expected and works as desired. I cannot point my "Add Service Reference" wizard to this URL, as it complains that:
The document at the url http://localhost:1178/wave/devices was not recognized as a known document type.
The error message from each known type may help you fix the problem:
- Report from 'XML Schema' is 'Data at the root level is invalid. Line 1, position 1.'.
- Report from 'DISCO Document' is 'Data at the root level is invalid. Line 1, position 1.'.
- Report from 'WSDL Document' is 'There is an error in XML document (1, 1).'.
- Data at the root level is invalid. Line 1, position 1.
Metadata contains a reference that cannot be resolved: 'http://localhost:1178/wave/devices'.
The remote server returned an unexpected response: (405) Method Not Allowed.
The remote server returned an error: (405) Method Not Allowed.
If the service is defined in the current solution, try building the solution and adding the service reference again.
I have a nagging suspicion that I need to point my "Add Service Reference" to the mex, but that doesn't work either and indeed, when I browse to the mex address of http://localhost:1178/wave/mex, I get a blank page.
EDIT 1
Just to eliminate JSON being the culprit, I changed my contract to output Xml instead of Json. The result was the same: I can't add a service reference using this URL: http://localhost:1178/zwave/devices/xml (even though that URL produces XML).
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml, UriTemplate= "/devices/xml")]
Thanks in advance for any help provided.
Traditionally, the "add web reference" option you are using in Visual Studio is meant for referencing XML Web Services only. Your service is defined in terms of rest/json and not in terms of soap/xml/wsdl that visual studio expects.
I suspect that Visual Studio simply isn't able to generate proxies for a json/rest service as yours. This is confirmed in the documentation on the WCF rest starter kit for .NET 3.5 (see the section "Consuming RESTful Services with HttpClient", search for "not possible to generate strongly-typed proxies like you’re used to with SOAP").
I'm not sure whether it is still unsupported in VS2010 / .NET 4.0, but I think you have to look for another option than "add web reference".
Perhaps found for the blank page:
Replace
host = new WebServiceHost(waveServiceSingleton, endPoint.Uri);
with
host = new ServiceHost(waveServiceSingleton, endPoint.Uri);
this worked for me
精彩评论