WCF anything in the endPointBehavior cancels the metaData exposure? - c#

This is my web.config file:
<bindings>
<basicHttpBinding>
<binding
name="ExtremeBinding"
maxBufferSize="12354000"
maxReceivedMessageSize="12354000" />
</basicHttpBinding>
</bindings>
<services>
<service name="WcfService3.Service1" behaviorConfiguration="myServiceBehaviour">
<endpoint
address=""
binding="basicHttpBinding"
bindingConfiguration="ExtremeBinding"
contract="WcfService3.IService1"
behaviorConfiguration="epBehavior"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="epBehavior">
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="myServiceBehaviour">
<!-- 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>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
If I keep it like this, and run the WCF Test Client, everything works fine.
But if I add anything to the endPoint Behavior, for example:
<behavior name="epBehavior">
<callbackDebug includeExceptionDetailInFaults="true"/>
</behavior>
the WCF Test Client fails with the Error:
Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.
It seems as though it doesn't matter what I put within the . For example:
<behavior name="epBehavior">
<webHttp/>
</behavior>
It's clear to me that I missing something fundamental, but I can't figure what it is.
Thank you very much.

I don't know the exact reason why this happens, but I think you can fix this by adding a serviceMetadata behavior:
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior">
<serviceMetadata httpsGetEnabled="true"
httpsGetUrl="https://myComputerName/myEndpoint" />
</behavior>
</serviceBehaviors>
</behaviors>
This is from:
http://msdn.microsoft.com/en-us/library/ms731317.aspx

Related

WCF REST Endpoint

I am developing a WCF and I want it to be called by both ways SOAP/REST.
Now I am able to get response by SOAP but unable to call the same WCF by JSON request.
IService1.cs
[OperationContract]
[FaultContract(typeof(CustomException))]
[WebInvoke(Method = "POST", UriTemplate = "/Validateuser",
RequestFormat = WebMessageFormat.Xml | WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Xml | WebMessageFormat.Json)]
ResponsetoCustomer Validateuser(ValidateCustomerInput validate);
Web.config
<system.serviceModel>
<services>
<service name="TractorMitraIntegration.IService1" behaviorConfiguration="ServBehave">
<!--Endpoint for SOAP-->
<endpoint
address="soapService"
binding="basicHttpBinding"
contract="TractorMitraIntegration.IService1"/>
<!--Endpoint for REST-->
<endpoint
address="XMLService"
binding="webHttpBinding"
behaviorConfiguration="restPoxBehavior"
contract="TractorMitraIntegration.IService1"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServBehave">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="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 for the REST endpoint for Help enability-->
<behavior name="restPoxBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
Below error I am facing,
Cannot process the message because the content type 'application/json' was not the expected type 'text/xml; charset=utf-8'
Please help!
You probably need defaultOutgoingResponseFormat="Json":
<behavior name="restPoxBehavior">
<webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json" />
</behavior>
You cannot support both soap and rest for the same endpoint.
See this REST / SOAP endpoints for a WCF service for how to.

WCF service inside a Web application is not working through RESTCLIENT?

I have added a RESTful WCF service inside a Web application(Righclicked solution and added WCF service) and while running it is exposing the url as svcutil.exe http://localhost:62783/Service1.svc?wsdl but i have tried calling that service UriTemplate from a RESTCLIENT like http://localhost:62783/AuthenticateUser it is throwing an error like
HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
But if i create a seperate RESTful WCF service and calling from a RESTCLIENT is working fine.Here is my code
[OperationContract]
string AuthenticateUser1();
and
[WebInvoke(UriTemplate = "/AuthenticateUser", Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
public string AuthenticateUser1()
{
return string.Format("Token {0}", new Guid().ToString());
}
and config
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Any suggestion??
Based on your posted config, you have a default endpoint for SOAP of basicHttpBinding, which is (by default) mapped to the http scheme. I've done very little with REST, but I believe you will need to add an endpoint using webHttpBinding to do REST, and most likely the URL will need to be http://localhost:62783/Service1.svc/AuthenticateUser (note the inclusion of the service file), though I'm not 100% sure on that one.
To add a REST endpoint, do something like this in your service's config file:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<!-- Added for REST -->
<endpointBehaviors>
<behavior name="REST">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<!-- REST endpoint -->
<endpoint address="" binding="webHttpBinding"
contract="<contract name with namespace>"
behaviorConfiguration="REST">
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Again, REST is not my strong point, but this should hopefully get you pointed in the right direction at least.

How can I Create this configuration programmatically?

I have an WCF and I'm needing to create this configuration dinamically because my
app.config never changes in client machines.
Any body help?
<behaviors>
<endpointBehaviors>
<!-- REST -->
<behavior name="restBehavior">
<webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<client>
<endpoint name="json" address="http://localhost:8080/json"
binding="webHttpBinding"
bindingConfiguration="webBinding"
behaviorConfiguration="restBehavior"
contract="ServiceReference.ServiceClientContract" />
</client>
Most WCF elements in the config file have a corresponding class or property that can be set in code (which is presumably what you meant by "dynamically"?) For example, 'endpointBehaviors' can be accessed through the Behaviors property of the ServiceEndpoint class:
Uri baseAddress = new Uri("http://localhost:8001/Simple");
ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress);
ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorServiceObject");
endpoint.Behaviors.Add(new MyEndpointBehavior());
Console.WriteLine("List all behaviors:");
foreach (IEndpointBehavior behavior in endpoint.Behaviors)
{
Console.WriteLine("Behavior: {0}", behavior.ToString());
}
http://msdn.microsoft.com/en-us/library/system.servicemodel.description.serviceendpoint.behaviors.aspx
Searching any of the elements your are interested in configuring in MSDN should be enough to get you started.

Change wsHttpBinding binding to webHttpBinding

I am struggeling with a problem with WCF Service configuration.
I have following config:
<behaviors>
<serviceBehaviors>
<behavior name="SampleWebBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="false"/>
It works perfectly, I can try the methods with WcfTestClient.exe and get correct responses. But I need the binding to be webHttpBinding, so I can see the results in browser and create JSON requests and responses.
But when I change the binding to webHttpBinding, it throws an error:
The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
Thaks for any help.
To pull this off you need to do a few things in your config
1) add another endpoint to your service, you can see below I have both basicHttp and webHttp
<system.serviceModel>
<services>
<service name="<serivceclass>" behaviorConfiguration="DefaultBehavior">
<endpoint binding="basicHttpBinding" contract="<serviceinterface>" bindingConfiguration="soapBinding"/>
<endpoint address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="<serviceinterface>" bindingConfiguration="jsonBinding"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</system.serviceModel>
2) add your binding config (again you'll see both web and basichttp)
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="soapBinding" maxBufferPoolSize="9000000" maxBufferSize="9000000" maxReceivedMessageSize="9000000">
<readerQuotas maxArrayLength="9000000" maxBytesPerRead="9000000" maxDepth="9000000" maxNameTableCharCount="9000000" maxStringContentLength="9000000"/>
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="jsonBinding">
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
3) Setup your behaviors - notice the names and how they correlate tot the endpoints listed in step 1
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp defaultOutgoingResponseFormat="Json" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="DefaultBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="9000000" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
While some of the stuff I enable and config are optional this allows you to access the service both ways, one way using web and json stuff and another using the tooling built into visual studio when you are not working in javascript,etc.
Note1: the endpoint when you are using the json part will be for example http://myhost.com/myservice.svc/json/MyMethodName, You can change this by modifying the "address" attribute on the appropriate endpoint line for your service (see how basic address is empty and the webHttp is 'json')
one possibility of the source of this error is: When you changed the configuration you made the change on the server or the client but not on both. The configuration on the server and client must match.

Prioritization within WCF service

Currently I have several endpoints within a single service which invoke the same action but have different throttling configurations based on their priority.
<serviceBehaviors>
<behavior name="PriorityService1">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="3" maxConcurrentSessions="3"
maxConcurrentInstances="3" />
</behavior>
<behavior name="PriorityService2">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="5" maxConcurrentSessions="5"
maxConcurrentInstances="5" />
</behavior>
<behavior name="PriorityService3">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="10" maxConcurrentSessions="10"
maxConcurrentInstances="10" />
</behavior>
</serviceBehaviors>
Each of these deals with the incoming SOAP request in exactly the same way (it just throttles them based on priority). Each of the priorities just inherits from a BaseService class like so.
public class Priority1Service : BaseService { }
public class Priority2Service : BaseService { }
public class Priority3Service : BaseService { }
As you can see, there is no implementation in the Priority classes because I just use the inherited behavior. Is there a better way to do this? Is there a way I can pass the prioritization in the soap message and have the service deal with it based off that? I'd ideally like to be able to get rid of these classes which only inherit behaviour.
Try defining different service configurations at the web.config file;
<services>
<service behaviorConfiguration="PriorityService1" name="Sample.Sample">
...
</service>
<service behaviorConfiguration="PriorityService2" name="Sample.Sample">
...
</service>
<service behaviorConfiguration="PriorityService3" name="Sample.Sample">
...
</service>
</services>

Categories

Resources