Cannot turn on includeExceptionDetailInFaults for certain WCF service - c#

I have a WCF project with two endpoints. One endpoint "EP1" shows detailed exceptions in the WCF Test Client but "EP2" does not and shows an error message saying:
The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client
I am wondering why this is? I have set the web.config in the same way as "EP1" and on the "EP2" web service class I have added:
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
I can't imagine what could be different. I have double checked the class name is definitely correct. Here is the section of the web config:
<system.serviceModel>
<services>
<service name="Portal.EP1" behaviorConfiguration="debug"></service>
<service name="Portal.EP2" behaviorConfiguration="debug"></service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="debug">
<!-- 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="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Am I crazy?

Related

Using REST GET in WCF as 2nd endpoint

I trying to add 2nd endpoint in existing WCF Application and my REST method doesn't work.
I created new Interface
[ServiceContract]
public interface IRestService
{
[OperationContract]
[WebGet(UriTemplate = "RestURI", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string SomeMethod();
}
And implemented it in existing service
public string SomeMethodImplementation()
{
//some logic
}
I'm trying to access this method using basicaddress/service/RestURI but getting 400 Bad Request response.
After that I added protocolMapping, 2nd endpoint and endpoint behavior to config file but it didn't help.
Right now my config file looks like this:
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<behaviors>
<serviceBehaviors>
<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 name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="servicename">
<endpoint address="" binding="webHttpBinding" contract="IRestService" behaviorConfiguration="web"/>
<endpoint address="" binding="basicHttpBinding" contract="ISoapService"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" receiveTimeout="00:10:00" sendTimeout="00:10:00">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16348" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
</binding>
</basicHttpBinding>
</bindings>
I'm not getting any 400 anymore but instead of that 'cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher.' error appeared. Also after adding protocolMapping, my soap methods have disappeared when I open wsdl in browser. Without it my rest method can be seen in the list like this:
<wsdl:port name="BasicHttpBinding_IRestService" binding="i0:BasicHttpBinding_IRestService">
After that I added AddressFilterMode = AddressFilterMode.Any) in attributes of my Service but it doesn't help.
I found a lot of answers here but somehow not a single one help me to resolve this problem.
What did I miss?
I found the solution after I installed WCF for visual studio. All this time I had wrong namespaces in my web.config and had no idea but VS marked it after installing module. I added right namespace and problem went away. I really suggest to install WCF in VS.
The issue boils down to the fact that we fail to host the service in Restful style.
Ordinarily, there are two ways to configure the Restful style service created by Webhttpbinding.
1.Using the service section to configure the interface and implementation.
<services>
<service name="WcfService3.Service1">
<endpoint address="" binding="webHttpBinding" contract="WcfService3.IService1" behaviorConfiguration="rest"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
There are two points we should pay attention to. In the service section, we are supposed to use the corresponding interface and implementation.
<service name="WcfService3.Service1">
<endpoint address="" binding="webHttpBinding" contract="WcfService3.IService1"
Adding a webhttp endpoint behavior also is essential then apply it by using Behaviorconfiguration property.
behaviorConfiguration="mybinding"
In the latest feature, we could create a WCF Restful style service with protocol mapping.
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="webHttpBinding" scheme="http"/>
It should be noted that we need to add an endpoint behavior without a name.
Based on your configuration, since you have multiple interfaces I suggest you remove the service section and host the service with a protocol mapping feature.
1. Remove service section in the configuration.
2. Remove the name of the endpoint behavior.
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<behaviors>
<serviceBehaviors>
<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>
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
Then we could access the service by the below Uri.
basicaddress/service.svc/RestURI
Feel free to let me know if there is anything I can help with.

Defining baseURL and EndPoint

I made a WCF with three methods:
[ServiceContract]
public interface IService1
{
[OperationContract]
String devolverPisosA();
[OperationContract]
String devolverPisosV();
[OperationContract]
String devolverNoticias();
}
I need to define baseAddress and EndPoint in Web.config file but I don´t know how:
I´m trying this (and some variations) but this is not working... (between system.serviceModel)
<services>
<service
name="ProyectoJosephWCF.Service1">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/Iservice1/"/>
</baseAddresses>
</host>
<endpoint address="devolverPisoA"
binding="wsHttpBinding"
contract="ProyectoJosephWCF.Service1" />
<endpoint address="devolverPisoV"
binding="wsHttpBinding"
contract="ProyectoJosephWCF.Service1" />
<endpoint address="devolverNoticias"
binding="wsHttpBinding"
contract="ProyectoJosephWCF.Service1" />
</service>
</services>
EDITED: If I´m not defining the baseAddress and endpoint before (using default configuration which was created when I created the project), and I launched the Services1.svc, I can reach the result json through testing windows but I can´t (or at least I don´t know how) to reach that JSON result from Android (by Retrofit). I supposed that I configured Retrofit (baseAddress and Endpoint values wrong), so I decided to set those values by my own...
For that I set the code before in Web.config, but I can´t reach them as well...
Beside, I would like to reach JSON result by Mozilla (in browser I mean), because someone said me that could me help to understand what baseAddress and Endpoint I´m using...
EDITED2: Behaviors are settings as:
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
And still don´t reach result by android or browser...
You need to set httpGetEnabled="true" for having WSDL available like below
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Include the same behavior configuration in your service declaration like
<service name="ProyectoJosephWCF.Service1"
behaviorConfiguration="NewBehavior">
See serviceMetadata for more information.
Finally... Check it out if you need it.
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior" >
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior>
<!-- 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>
And:
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "devolverPisoA")]
List<pisosAlquiler> devolverPisosA();

How to determine if I am using a Restful service or not?

I need to create a Restful service for my application. More I dig deep in to this more I get confused. I understand that a Restful service uses http for CRUD operations which makes it faster and lighter. But I am not sure how to determine if a web service is Restful or not.
However I found some help online that claims to be a Restful service but that has some Custombinding type . Here is how the web.config looks like
<system.serviceModel>
<services>
<service behaviorConfiguration="" name="RestRaw.Service1">
<endpoint address="" behaviorConfiguration="web" contract="RestRaw.IService1" binding="customBinding" bindingConfiguration="RawReceiveCapable"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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" />
<bindings>
<customBinding>
<binding name="RawReceiveCapable">
<webMessageEncoding webContentTypeMapperType="RestRaw.RawContentTypeMapper, RestRaw, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<httpTransport manualAddressing="true" maxReceivedMessageSize="524288000"
transferMode="Streamed" />
</binding>
</customBinding>
</bindings>
</system.serviceModel>
Is that a Restful service. If yes how can that be determined??
I am confused at the moment any suggestions to clarify my doubt would be really appreciated.
In this particular case you can tell it's a REST style webservice by the added behavior.
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
The webHttp behavior modifies the operation dispatch pipeline and instead of reading a destination action from a SOAP body, it uses the service interface attributes to decide where to route it. Here is a good page on msdn that shows the basics of creating a REST style webservice in WCF. The following example is from that page.
[ServiceContract]
interface ICustomer
{
//"View It" -> HTTP GET
[WebGet( UriTemplate="customers/{id}" )]
Customer GetCustomer( string id ):
//"Do It“ -> HTTP PUT
[WebInvoke( UriTemplate="customers/{id}", Method="PUT" )]
Customer UpdateCustomer( string id, Customer newCustomer );
}
The WebGet attribute matches the GET verb, then the request URI is pattern matched to decide which method to call. Then parts of the URI can be extracted and converted to parameters and passed to the method call. In the second method, UpdateCustomer, the Customer parameter comes from the request body as it's the only parameter that doesn't get matched elsewhere. In order for the request body to be used like this, the webMessageEncoding binding element is used in the custom binding. If you simply use the WebHttpBinding, it does all of this for you. The config you provided is doing it the explicit way.
The web.config file shows a typical WCF application. To check whether it is RESTful, you might learn WCF REST related topics, such as
https://msdn.microsoft.com/en-us/library/dd203052.aspx

Return image from WCF web service

I have created my first WCF webservice and I am trying to return an image from it based on some passed parameters. I am getting the error:
The content type image/jpeg of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly.
What do I need to do to resolve this issue?
The web.config file of my website that is calling the service has the following config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IRestImageService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:59473/RestImageService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IRestImageService"
contract="RestImageService.IRestImageService" name="BasicHttpBinding_IRestImageService" />
</client>
The webservice web.config looks like this:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<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>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true"/>
The Service Contract:
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "Image/{type}/{typeid}/{imageid}/{size}/{extension}",
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped)]
Stream Image(string type, string typeid, string imageid, string size = "lrg", string extension = "jpg");
I am very new at WCF, so any help/pointers would be greatly appreciated!
Update
After implementing Tim's suggestion, I am getting a new error:
There was no endpoint listening at localhost:59473/RestImageService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
I am not sure how to configure the web service to fix this issues. Any suggestions?
This is how I'm accessing the web service:
RestImageServiceClient client = new RestImageServiceClient();
client.Image(WSC.Common.BO.User.User.ImageFolder.Buyer, "27085", "BuyerPhoto", "LRG", "jpg");
I hope to be able to set the src tag of my image to the web service url once I get it working.
basicHttpBinding is SOAP (version 1.1). To enable REST-based services, I believe (haven't done much of it myself) that you need to use the webHttpBinding.
I would try something like this. In your service's config file, make the following changes:
<protocolMapping>
<add binding="webHttpBinding" scheme="http"/>
</protocolMapping>
This should configure your default binding to be webHttpBinding for http calls.
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<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>
</behaviors>
The above code should add a default endpoint behavior for webHttp.
Finally, in your client config file, make the following change:
<client>
<endpoint address="http://localhost:59473/RestImageService.svc"
binding="webHttpBinding"
contract="RestImageService.IRestImageService"
name="WebHttpBinding_IRestImageService" />
</client>
I can't say for certain that this will work, but I've done a lot with WCF (on the SOAP side), so I think this will at least get you pointed in the right direction.
EDIT
RestImageServiceClient is a SOAP client. To use a REST service, you need to use an HTTP API. Here's an example from [WCF REST Service with JSON]http://www.codeproject.com/Articles/327420/WCF-REST-Service-with-JSON):
WebClient client = new WebClient();
byte[] data = client.DownloadData("http://localhost:11523/Service1.svc/GetData");
Stream stream = new MemoryStream(data);
DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(string));
string result = obj.ReadObject(stream).ToString();
I recommend googling "WCF REST JSON Client exmaple" - you'll get lots of hits and a few different ways to do this.
As an added note, you could make a SOAP call with your SOAP client, as long as you have a SOAP endpoint exposed on the service.

Invalid Operation Exception

I created a WCF Serice that worked fine when hosted on IIS.
now, I took the same service, and created a host application in WPF, and when trying to start the service from that application, I get this exception :
The HttpGetEnabled property of ServiceMetadataBehavior is set to true and the
HttpGetUrl property is a relative address, but there is no http base address.
Either supply an http base address or set HttpGetUrl to an absolute address.
The error is quite clear - you're using HTTP, you have enabled HttpGetEnabled on your ServiceMetadata behavior, but you have not provided a base address in your config.
In IIS, base addresses are neither needed, nor used, since the location of the *.svc file defines your service address. When you're self-hosting, you can and should use base addresses.
Change your config to look something like this:
<system.serviceModel>
<services>
<service name="YourService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/YourService" />
</baseAddresses>
</host>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
..... (your own other endpoints) ...........
</service>
</services>
</system.serviceModel>
Now, the "HttpGetEnabled" has a base address http://localhost.8080/YourService to go to to get the metadata from.
Or if you don't like this, again, the error message is quite clear on your alternative: define an absolute URL for the HttpGetUrl in your ServiceMetadata:
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata
httpGetEnabled="true"
httpGetUrl="http://localhost:8282/YourService/mex" />
</behavior>
</serviceBehaviors>
The clients can get your metadata from your "mex" endpoints, either at a fixed URL defined as in this second example, or they will go to the base address of the service for the metadata (if there is one).
If you're coming from IIS and haven't adapted anything, you'll have neither a base address, nor an explicit, absolute URL for your Metadata exchange endpoint, so that's why you get the error you're seeing.
Marc
I faced this error when I tried to use net.pipe binding.In my case, the default service behavior published the service metadata, This is the cause of my error. My solution is to use different behavior for your services. , then I changed my config file according to #marc_s answer and make different service behaviors as follows:
<serviceBehaviors>
<!--Default behavior for all services (in my case net pipe binding)-->
<behavior >
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<!--for my http services -->
<behavior name="MyOtherServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
Check that the service class is correct.
It's solved my problem
// Create a ServiceHost for the CalculatorService type and
// provide the base address.
serviceHost = new ServiceHost(typeof(ServiceClass));

Categories