WCF net.pipe aborts when receiving response - wcf

This has been resolved
This is a contract I'm unable to get from a service call:
[DataContract]
public class myInitializationData : ClientInitializationData
{
[DataMember]
public Dictionary<string, string> CultureNameLookup { get; set; }
}
Here's it's base type,
[DataContract]
public class ClientInitializationData
{
[DataMember]
public List<IServiceType> ServiceTypes { get; set; }
}
IServiceType is an interface. I realize I cannot send an interface across the wire. There is an EntityFramework entity, ServiceType, implementing the IServiceType interface:
public partial class ServiceType : IServiceType
{
//...
}
My goal is to send ServiceType entities across the wire via the myInitializationData contract.
I am prevented from decorating the myInitializationData or ClientInitializationData classes with a KnownType of ServiceType, because these classes are shared (linked) to Silverlight project(s). So if I decorate either of these classes with a KnownType of ServiceType, the Silverlight side(s) will fail to compile.
Instead of decorating the classes directly, I decorated the service contract with with a ServiceKnownType of ServiceType:
[ServiceContract]
[ServiceKnownType(typeof(ServiceType))]
public interface IService
{
[OperationContract]
myInitializationData InitializeClient();
}
Should this work?
When calling IService.InitializeClient, I receive the following error on the client:
There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).
I have enabled trace debugging but found no messages regarding failure to serialize in the trace for either client or server.
Server trace:
Receives a message ever a channel
(Action: http://tempuri.org/IService/InitializeClient)
To: Execute
(IService.InitializeClient)
From: Execute
(IService.InitializeClient)
Sends a message over a channel
(Action: http://tempuri.org/IService/InitializeClientResponse)
Warning
Faulted System.ServiceModel.Channels.ServerSessionPreambleConnectionReader+ServerFramingDuplexSessionChannel
Warning
Faulted System.ServiceModel.Channels.ServiceChannel
Replying to an operation threw an exception
(The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.)
Client trace:
Sends a message over a channel
(Action: http://tempuri.org/IService/InitializeClient)
Throwing an Exception
(There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).)
If I opt the ServiceTypes property out of the ClientInitializationData DataContract, this error goes away. So I assume this must be a serialization issue re: the interface and KnownTypes, but WCF isn't claiming to have any serialization issues in the trace, and I'm not sure what the trace means in this case.
Solution
This was not a KnownTypes issue. It was the result of LazyLoading having been spontaneously enabled on the entity context defining the ServiceType type.
Although there is no mention of excessive message or a buffer sizes being violated in the trace (on either the client or server sides), I must assume the enabling of LazyLoading on the EF context caused the DataContractSerializer to trigger EF into fetching a lot of records, which in turn resulted in a massive graph being (attempted) on the wire. The server side was simply (and ambiguously) faulting the channel during the message write.
Returning LazyLoading to a disabled state on the EF context has since solved this problem.

This was not a KnownTypes issue. It was the result of LazyLoading having been spontaneously enabled on the entity context defining the ServiceType type.
Although there is no mention of excessive message or a buffer sizes being violated in the trace (on either the client or server sides), I must assume the enabling of LazyLoading on the EF context caused the DataContractSerializer to trigger EF into fetching a lot of records, which in turn resulted in a massive graph being (attempted) on the wire. The server side was simply (and ambiguously) faulting the channel during the message write.
Returning LazyLoading to a disabled state on the EF context has since solved this problem.

Related

How to fix 'System.ServiceModel.Channels.ReceivedFault' cannot be serialized

I have a workflow service. I also use workflow persistence in that service. But after I deployed workflow in IIS, from client I make a request to workflow service, in log file on server. I see a message
The execution of the InstancePersistenceCommand named {urn:schemas-microsoft-com:System.Activities.Persistence/command}SaveWorkflow was interrupted by an error.InnerException Message: Type 'System.ServiceModel.Channels.ReceivedFault' cannot be serialized.
Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.
If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.
I tried research about this exception, but I didn't find anything.
How to fix this problem ? or let me know what is the reason about above exception ?
System.ServiceModel.Channels.ReceivedFault is a non-serializable internal .NET framework class, so unfortunately there is nothing you can do to correct the actual root cause (i.e. making said class serializable).
You are probably calling an external service via WCF which faults, i.e. a System.ServiceModel.FaultException is thrown. IIRC, somewhere deep down in that FaultException object is a reference to the culprit, a ReceivedFault instance.
Solution: Catch all FaultExceptions, transfer the information you need to know from the FaultException into a serializable exception, and throw the latter:
try
{
CallService();
}
catch (FaultException ex)
{
// Gather all info you need from the FaultException
// and transport it in a serializable exception type.
// I'm just using Exception and the message as an example.
throw new Exception(ex.Message);
}

How client application comes to know that a particular wcf method throws faultexception or not?

I know a wcf method throws fault exception and client application catches that fault exception. But is there any way to know that whether that wcf method throws fault exception or not at client side ?
When you create a WCF service you could decorate your operation contract with the [FaultContract] attribute:
[ServiceContract]
public interface IService1
{
[OperationContract]
[FaultContract(typeof(MyFaultContract))]
void DoWork();
}
This emits information about this MyFaultContract in the metadata (WSDL) of the service. Then when you create a client proxy (either using the Add Service Reference in VS or directly by the svcutil.exe) this fault contract is known by the client and you can catch exceptions of this type.
So the idea here is to look whether your operation contract is decorated with the [FaultContract] attribute to know which type of fault contracts this operation might throw. If it hasn't any custom FaultContract attributes defined on it it means that on the client you can catch only for the non-generic version of the FaultException.

Error when in Silverlight when trying to reach an RIA Services endpoint

I created a Ria services endpoint. Silverlight passes data into the RIA Services. The end point then writes/updates this data to the file system. We are experiencing the following exception:
System.ServiceModel.DomainServices.Client.DomainOperationException:
Invoke operation
'ModifyLogiDashletXmlFile' failed.
Exception of type
'System.ServiceModel.DomainServices.Client.DomainOperationException'
was thrown. at
Phoenix.UI.SL.Infrastructure.Services.LogiReportService.<>c_DisplayClass8.<ModifyLogiDashletXmlFile>b_7(InvokeOperation
operation) at
System.ServiceModel.DomainServices.Client.InvokeOperation.<>c_DisplayClass41.<Create>b__0(InvokeOperation1 arg) at
System.ServiceModel.DomainServices.Client.InvokeOperation`1.InvokeCompleteAction()
at
System.ServiceModel.DomainServices.Client.OperationBase.Complete(Exception
error) at
System.ServiceModel.DomainServices.Client.InvokeOperation.Complete(Exception
error) at
System.ServiceModel.DomainServices.Client.DomainContext.CompleteInvoke(IAsyncResult
asyncResult) at
System.ServiceModel.DomainServices.Client.DomainContext.<>c_DisplayClass38.<InvokeOperation>b__34(Object )
the attributes on the class:
[EnableClientAccess(RequiresSecureEndpoint = true)]
[LinqToEntitiesDomainServiceDescriptionProvider(typeof(PhoenixEntities))] // IMPORTANT: Must have this because we are returning/passing EF Entities from Phoenix Context
[RequiresAuthentication]
public class LogiReportService : DomainService
{
...
}
The entry method:
[Invoke]
public void ModifyLogiDashletXmlFile(IEnumerable<ParameterNameValuePair> paramNameValuePairs, Guid clientId, string dashletInstanceId)
{
// Validate Client is has a valid relationship to the User (i.e. no disabled)
if (this.PhoenixUser.MembershipClientIds.Contains(clientId))
{
ModifyLogiXmlFile(PhoenixUser.UserId, clientId.ToString(), dashletInstanceId, paramNameValuePairs);
}
}
What's baffling is other endpoints work fine. The differences between this endpoint and the other is this one writes and reads files from the file-system. The app-domain user has full-rights and the error returned does not appear to be a permissions issue.
All idea's are welcomed. I'm hitting up against a wall with this issue.
This issue turned out to be a permissions issue on the server. A file was being written to the system.
RIA services was swallowing the error and presenting a generic error in it's stead. I put a try catch around the entry method and logged the error to the database. Then I was able to discover the real issue.

WCF/WebService: Interoperable exception handling

I understand that WCF will convert an exception into a fault and send it back as a SOAP message, but I was wondering if this is truly interoperable. I guess I'm having a tough time trying to figure out this possible scenario:
Client (Java) calls a WCF Service
(LoginService).
Server checks for proper authorization, user authorization fails.
Server throws an UnauthorizedAccessException.
WCF converts this into a Fault somehow. (* - See Below As Well)
Client has to be able to know how to read this Fault.
I guess I'm just having a tough time understanding how this could still be interoperable because it is expecting Java to know how to translate a SOAP Fault that .NET encodes from an UnauthorizedAccessException.
Also, how does .NET actually convert the exception to a fault, what goes in as the fault code, name, etc. Some of the things seem to be "duh"s like perhaps the Fault Name is "UnauthorizedAccessException", but I'd rather know for sure than guess.
There is no "automatic conversion". WCF will return a fault (I forget which one) when you have an unhandled exception. But since you didn't declare that fault, many, if not most, clients will fail if you return it.
You are meant to define your own faults and to return them instead. Consider:
[DataContract]
public class MySpecialFault
{
public string MyMessage { get; set; }
}
[ServiceContract]
public interface IMyService
{
[FaultContract(typeof (MySpecialFault))]
[OperationContract]
void MyOperation();
}
public class MyService : IMyService
{
public void MyOperation()
{
try
{
// Do something interesting
}
catch (SomeExpectedException ex)
{
throw new FaultException<MySpecialFault>(
new MySpecialFault {MyMessage = String.Format("Sorry, but {0}", ex.Message)});
}
}
}
Any client capable of handling faults will deal with this. The WSDL will define the fault, and they will see a fault with the Detail element containing a serialized version of the MySpecialFault instance that was sent. They'll be able to read all the properties of that instance.
Faults have been part of the SOAP specification since v1.1. They are explained in the SOAP Specification.
It is up to implementations (WCF, Java etc) to ensure that Faults are handled according to the specification.
Since WCF converts FaultExceptions to Faults according to the SOAP specification, FaultExceptions thrown from WCF are interoperable.
SOAP faults are interoperable but .Net exception classes are not good to be used in SOAP faults. Instead define your own DataContract class (e.g. AccessFault) and then use it in a FaultContract.
see http://msdn.microsoft.com/en-us/library/ms733841.aspx
Whenever there is a UnauthorizedAccessException thrown at service boundary convert it to FaultException.
This can be done in several ways like using Microsoft Enterprise Library Exception Handling Block or implementing the IErrorHandler interface.

What is the best approach to handle exceptions in WCF service?

I have a WCF service deployed on two or more remote machines and there is a desktop based application that is used by the client to access any wcf service.
The WCF service is connected to SQL server 2005 to read and write data.
This is an intranet scenario in which the client should be on same domain.
Now there can be scenarios where the wcf service throws exceptions:
Invalid URL
WCF service is down
SQL server 2005 is not running
Client is not on the same domain
Authentication fails
Authorization fails
and many other exceptions.
For every exception I have to perform some action or update a status bar, depending on the exception. For example if authorization fails I have to prompt the user to re-enter their credentials.
Please suggest the best design approach to handle this.
You can definitely catch and handle all exceptions that happen on your service class and turn them into a FaultException or FaultException exception.
That way, you won't "fault" (or tear down) the communications channel between your client and server.
Even better approach would be to implement the IErrorHandler interface on your service class that provides a way to globally catch all exceptions as they happen and provide a FaultException instead, that's SOAP compliant.
You can even turn your IErrorHandler into a configurable behavior that can be turned on or off in config.
See these articles and blog posts for more details:
Rory Primrose: Implementing IErrorHandler
Useful WCF behaviors: IErrorHandler
Create a custom fault class that is marked with the DataContract attribute
Mark the method on the service contract interface with FaultContract. Ie. [FaultContract(typeof(CustomFault))]
In your service method, catch any applicable internal exceptions and throw a FaultException<CustomFault>. Alternatively, as marc_s mentioned, you can use IErrorHandler to map the exception to the fault.
Personally, I create a base Fault class that has a Reason property and I extend all custom faults from this class. When I want to throw the fault, I call:
throw Fault.Create<CustomFault>(new CustomFault("Boo hoo"));
It's also worth noting that I version my fault classes (including the common Fault class) along with all my other services. This is only a concern if service versioning is a concern, though.
Here's the basic Fault class (I've removed argument validation for brevity):
[DataContract(Namespace = XmlVersionNamespace.FaultNamespace)]
public abstract class Fault
{
internal FaultReason Reason { get; set; }
protected Fault(string reasonText)
{
Reason = new FaultReason(new FaultReasonText(reasonText, CultureInfo.CurrentUICulture));
}
public override string ToString()
{
return Reason.ToString();
}
internal static FaultException<TDetail> Create<TDetail>(TDetail fault) where TDetail : Fault
{
return new FaultException<TDetail>(fault, fault.Reason);
}
}
You can design the specific Fault Data Contracts for each of the exception scenario in your WCF service so that you can handle the fault/exception at client side respectively.
try
{
// Actions
}
catch (Exception ex)
{
// Log the exception
// Throw Fault Exception back to client
FaultException fe = new FaultException(ex.Message, new FaultCode("Your fault code"));
//throw fault exception back to WCF client
throw fe;
}