How to invoke web service in client which has CustomBinding endpoints? - wcf

I have WCF web service with custombinding as endpoint. I would like to invoke this web service (hosted on IIS) from my client application.
The service contract looks as below:
[ServiceContract(Namespace = "http://schemas.microsoft.com/windows/management/2012/01/enrollment")]
[XmlSerializerFormat]
public interface IDiscoveryService
{
[OperationContract(Name = "Get")]
[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat=WebMessageFormat.Xml, ResponseFormat=WebMessageFormat.Xml)]
string DiscoveryGet();
}
The Web.COnfig file contents looks like:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NewBinding0">
<textMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
<services>
<service name="DiscoveryWebService.DiscoveryService">
<endpoint address="" binding="customBinding" bindingConfiguration="NewBinding0"
contract="DiscoveryWebService.IDiscoveryService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
The client application codes looks like:
string uri = " http://localhost/EnrollmentServer/Discovery.svc";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
req.ContentType = "unknown";
req.Method = "GET";
WebResponse response = req.GetResponse();
StreamReader loResponseStream = new StreamReader(response.GetResponseStream(), false);
string responseString = loResponseStream.ReadToEnd();
I am getting HTML content of WSDL file instead of the string returned by Get method. I am not getting whether I am doing it in the right way or not?
I would appreciate the help in this regard.

The [WebGet] (and [WebInvoke]) attribute is only honored for an endpoint which uses the webMessageEncoding binding element; with a HTTP transport with the manualAddressing property set to true, and also the <webHttp/> endpoint behavior - which your service doesn't have. If you make the changes listed below, it should work:
Service contract:
[ServiceContract(Namespace = "http://schemas.microsoft.com/windows/management/2012/01/enrollment")]
[XmlSerializerFormat]
public interface IDiscoveryService
{
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
string DiscoveryGet();
}
Web.config:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NewBinding0">
<webMessageEncoding />
<httpTransport manualAddressing="true" />
</binding>
</customBinding>
</bindings>
<services>
<service name="DiscoveryWebService.DiscoveryService">
<endpoint address="" binding="customBinding" bindingConfiguration="NewBinding0"
contract="DiscoveryWebService.IDiscoveryService" behaviorConfiguration="Web" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="Web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Client code:
string uri = "http://localhost/EnrollmentServer/Discovery.svc/DiscoveryGet";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
req.Method = "GET";
WebResponse response = req.GetResponse();
StreamReader loResponseStream = new StreamReader(response.GetResponseStream(), false);
string responseString = loResponseStream.ReadToEnd();

Related

WCF JSON Format - while consuming in Client side getting an error message

Client side Code
I have created web application and added service reference to the Client Project
I tried creating a client Object like this:
Service1Client a = new Service1Client();
but getting an error message :
Could not find default endpoint element that references contract 'ServiceReference_test.IService1' 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.
Could you please let me know what mistake am I doing, I am new to WCF please help me
WCF service which returns JSON Format:
namespace WcfService1
{
public class Service1 : IService1
{
public string GetData(string Id)
{
return ("You entered: " + Id);
}
}
}
namespace WcfService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetData/{Id}",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped
)]
string GetData(string Id);
// TODO: Add your service operations here
}
}
Web.Config file
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="ServiceBehaviour">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="WcfService1.IService1"/>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="false" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
You should add following tags in your client App.config or Web.config:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="WebHttpBinding" />
</webHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/fine_service/FineService/soap"
binding="webHttpBinding" bindingConfiguration="WebHttpBinding"
contract="ServiceReference1.IService1" name="WebHttpBinding" />
</client>
</system.serviceModel>
if you have this tags in your cofig file then make sure that client endpoint contract name should be the same as it is in your service endpoint. In your case contract name is IService1
EDIT:
also see this

Invoking WCF service in browser similar to asmx

I have made a WCF service in NET 4.0 and it returns the XML, I have tested it using SoapUI and i can see the required response xml. But my WCF service would be called by 3rd party software and they want to use it through a URL like asmx. I have googled and found that i need to make using REST guidelines. However i have not found a proper link showing making web-service using REST and then accessing the method from the browwer similar to web services.
Below is the interface code which i have used to return the format in XML
public interface IService1
{
[WebGet(
UriTemplate = "/GetDocument/",
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Xml)]
[OperationContract, XmlSerializerFormat]
XmlElement GetDocument();
// TODO: Add your service operations here
}
Below is my config settings.
<system.serviceModel>
<services>
<service name="BritishLandXML.BritishLandXML1" behaviorConfiguration="metadataBehavior">
<endpoint address="" binding="basicHttpBinding" contract="BritishLandXML.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding>
<security mode="None"></security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp helpEnabled="true" faultExceptionEnabled="true" automaticFormatSelectionEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
Please let me know how can i achieve this and what exact settings will be required.

wcf rest service consumption in c# console application

I made wcf rest service by going New->projects->WCF Service Application
I am unable to use methods in console application while i have hosted wcf rest service and referenced wcf rest service in application
My Application code is below :
IRestServiceImpL
[ServiceContract]
public interface IRestServiceImpL
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Xml,
RequestFormat = WebMessageFormat.Xml, UriTemplate = "XmlData/{id}")]
string XmlData(string id);
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json, UriTemplate = "JsonData/{id}")]
string JsonData(string id);
}
RestServiceImpL.svc.cs
[AspNetCompatibilityRequirements(RequirementsMode
= AspNetCompatibilityRequirementsMode.Allowed)]
public class RestServiceImpL : IRestServiceImpL
{
public string XmlData(string id)
{
return "you requested for " + id;
}
public string JsonData(string id)
{
return "you requested for " + id;
}
}
Config File
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="StreamedRequestWebBinding"
bypassProxyOnLocal="true"
useDefaultWebProxy="false"
hostNameComparisonMode="WeakWildcard"
sendTimeout="10:15:00"
openTimeout="10:15:00"
receiveTimeout="10:15:00"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
transferMode="StreamedRequest"
crossDomainScriptAccessEnabled="true"
>
<readerQuotas maxArrayLength="2147483647"
maxStringContentLength="2147483647" />
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="RestService.RestServiceImpL" behaviorConfiguration="ServiceBehaviour">
<!--<endpoint address="" binding="basicHttpBinding" contract="RestService.IRestServiceImpL"></endpoint>-->
<endpoint address="" binding="webHttpBinding" name="StreamedRequestWebBinding" bindingConfiguration="StreamedRequestWebBinding" contract="RestService.IRestServiceImpL" behaviorConfiguration="web"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
</system.serviceModel>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
I host this service application in IIS
Now after giving reference to console application when i call its methods
by using proxy class then i got error of Invalid Operation Contract Exception
that endpoint not specified
calling code is below :
ServiceClient oServiceClient = new ServiceClient();<br/>
oServiceClient.JsonData("123");
Please suggest what is problem in the code.
Thanks stack overflow for support...I did it..
The calling Wcf Rest Service code is written below :
//code for xml Response consumption from WCF rest Service[Start]
WebRequest req = WebRequest.Create(#"http://RestService.com/WcfRestService/RestServiceImpL.svc/XmlData/sad");
req.Method = "GET";
req.ContentType = #"application/xml; charset=utf-8";
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
if (resp.StatusCode == HttpStatusCode.OK)
{
XmlDocument myXMLDocument = new XmlDocument();
XmlReader myXMLReader = new XmlTextReader(resp.GetResponseStream());
myXMLDocument.Load(myXMLReader);
Console.WriteLine(myXMLDocument.InnerText);
}
//code for xml Response consumption from WCF rest Service[END]
//****************************************************************************
//code for json Response consumption from WCF rest Service[Start]
WebRequest req2 = WebRequest.Create(#"http://RestService.com/WcfRestService/RestServiceImpL.svc/JsonData/as");
req2.Method = "GET";
req2.ContentType = #"application/json; charset=utf-8";
HttpWebResponse response = (HttpWebResponse)req2.GetResponse();
string jsonResponse = string.Empty;
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
jsonResponse = sr.ReadToEnd();
Console.WriteLine(jsonResponse);
}
//code for json Response consumption from WCF rest Service[END]

FileTransfer to WCF Service receiving 405

I'm working on a mobile app using PhoneGap, and one of the features involves uploading an image to a web service for processing. I've written a WCF service that's hosted in IIS to accept the image, with a contract that looks like the following:
[ServiceContract]
public interface IImages
{
[OperationContract(Name="UploadImage")]
[WebInvoke(UriTemplate = "?file_key={fileKey}", Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
ImageResource UploadImage(string fileKey, Stream imageStream);
}
The configuration section in my web.config looks like:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<serviceActivations>
<add service="Services.Images" relativeAddress="images.svc" />
</serviceActivations>
</serviceHostingEnvironment>
<services>
<service behaviorConfiguration="DefaultServiceBehavior" name="Services.Images">
<endpoint behaviorConfiguration="DefaultEndpointBehavior" binding="webHttpBinding" bindingConfiguration="PublicStreamBinding" contract="Services.Contracts.IImages" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="PublicStreamBinding"
maxReceivedMessageSize="2000000000" transferMode="Streamed">
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="DefaultEndpointBehavior">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="DefaultServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="30" maxConcurrentInstances="30" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
When I attempt to upload a file to the endpoint, using PhoneGap's FileTransfer class, the response returned from the service is a 405 Method Not Allowed. What am I doing wrong here?
UPDATE: The function in my mobile app that's uploading the file is below. This code previous worked fine when pointed to an older ASMX service.
ns.UploadImage = function(){
//alert(ns.Dictionary['LocalImagePath']);
var uri = ns.Dictionary['LocalImagePath'];
try {
var options = new FileUploadOptions();
options.fileKey = uri.substr(uri.lastIndexOf('/')+1) + ".jpeg";
options.fileName = uri.substr(uri.lastIndexOf('/')+1) + ".jpeg";
options.mimeType = "image/jpeg";
var ft = new FileTransfer();
ft.upload(uri, GetServerUrl()+"images.svc?file_key="+options.fileKey, ns.UploadImageSuccess, ns.UploadImageError, options);
} catch (e) {
ns.UploadImageError(e);
}
};
Ok so I think I figured this out. Apparently, when the method is hosted at the root like this, if you don't follow the name of the service in the uri with '/', the request won't get routed correctly. So, in the function that uploads the file, I changed the ft.upload line to the following:
ft.upload(uri, GetServerUrl()+"images.svc/?file_key="+options.fileKey, ns.UploadImageSuccess, ns.UploadImageError, options);
Which worked.

WCF Generate help for REST POST call

Using WCF, it is possible to generate help for a webHTTPBinding. With a WebGet operation, it works like charm. Using a WebInvoke (Method = "POST") however doesn't give me any help. In the pages I can see this:
Url:
http://localhost/edumatic3/trunk/services/service.svc/rest/saveUser
HTTP Method: POST
Message direction Format Body
Request Unknown Could not generate schema document.
Response Unknown Could not generate schema document.
Any ideas?
Web.Config system.serviceModel
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBindingConfiguration">
<security mode="TransportWithMessageCredential" />
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="HelpEndPointBehavior">
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="false" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType=
"Edu3.Service.OpenApi.Security.CustomUserNameValidator
, Edu3.Service.OpenApi" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="OpenApiService"
behaviorConfiguration="ServiceBehavior">
<endpoint name="soap"
address="soap"
binding="basicHttpBinding"
contract="Edu3.Service.OpenApi.Interface.IService"
bindingConfiguration="basicHttpBindingConfiguration"/>
<endpoint name="rest"
address="rest"
behaviorConfiguration="HelpEndPointBehavior"
binding="webHttpBinding"
contract="Edu3.Service.OpenApi.Interface.IService"/>
<endpoint name="mex"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="services/service.svc"
service="OpenApiService"
factory="Spring.ServiceModel.Activation.ServiceHostFactory"/>
</serviceActivations>
</serviceHostingEnvironment>
Service Contract:
The GetNodeByKey gives me clear help. The SaveUser not.
[ServiceContract]
public interface IService
{
[OperationContract]
[WebGet(UriTemplate = "login?userName={userName}&password={password}")]
void Login(string userName, string password);
[OperationContract]
[WebGet(UriTemplate = "getNodeByKey/{key}?getAllDescendants={getAllDescendants}"
, ResponseFormat = WebMessageFormat.Json)]
[ServiceKnownType(typeof(BranchNodeDTO))]
[ServiceKnownType(typeof(LeafNodeDTO))]
[ServiceKnownType(typeof(CasusNodeDTO))]
[ServiceKnownType(typeof(BucketNodeDTO))]
NodeDTO GetNodeByKey(string key, string getAllDescendants);
[OperationContract]
[WebInvoke(UriTemplate = "saveUser", Method = "POST"
, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
UserDto SaveUser(UserDto user, int channelId);
}
What about your DataContract? Are there any enums which have FlagsAttribute? It seems that when you use [Flags] WCF isn't able to correctly generate the help page.
Source: http://support.microsoft.com/kb/2020406/en-us