Tuesday 18 March 2014

System.ServiceModel assembly is not marked as serializable


Most frustrating thing you ever going to come across is debugging web services, but not if you know the tricks & tools which you could use to get to the root of problem causing the error in the services at the first place. Web services related errors can be deceiving and forcing you to look at places that work perfectly. 

Today I have been working on a custom WCF web services which was trying to download a document from a SharePoint list to a workflow server, it worked perfectly until we decided to change the way our workflow server authenticates(for some reason), so we created a proxy which will be used to call custom WCF service from workflow server instead of adding a web reference.

As soon as we changed the way we were calling custom WCF web services, we started getting this error,


 Description: Type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' in Assembly 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=""' is not marked as serializable.
Server stack trace:
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)

So looking at error initially, I thought it because we are not serializing the document who's details were wrapped up within a object, so I added this "[Serializable]" to our document class,


    [DataContract]
    [Serializable]
    public class DocumentObject
    {
        [DataMember]
        public string documentName;
        [DataMember]
        public byte[] data;
    }

   [ServiceContract]
   public interface IDocuments
   {
        [OperationContract]
        DocumentObject[] GetDocumentsFromList(string listName, string[] documentNames);
   }


On the other side when we tried to deserialize the document I still kept getting this error,

Type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' in Assembly 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=f4tue731934e089' is not marked as serializable.
 Server stack trace:
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)


Since the error saying that, something went wrong while deserializing the object but why though ? I tried using BinaryFormatter to desearlize the method's response from webservices but it didn't helped as same code worked when there was no proxy... anyway, I added includeExceptionDetailInFaults="true" to my custom application's web.config, which was calling the WCF web services, to get the inner or real exception,

<?xml version="1.0"?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    </startup>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="debug">
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>


Adding above helped me get to the bottom of problem, which was the size of document it was trying to desearlize. Size limit was exceeding,

The InnerException message was 'There was an error deserializing the object of  type MySolution.WebServices.DocumentObject[]. The maximum array length quota (16384) has been exceeded while reading XML data. 

To fix the above, you can either change the web.config of your WCF service and change MaxArrayLength or you can do it within code,

XmlDictionaryReaderQuotas readerQuotas = new XmlDictionaryReaderQuotas();
readerQuotas.MaxArrayLength = 1024 * 1024 * 102;  //102 Mega bytes
readerQuotas.MaxDepth = int.MaxValue;
binding.ReaderQuotas = readerQuotas;


This solved the issue for me.

Tuesday 4 March 2014

Mailbox unavailable. The server response was: 5.7.1 Unable to relay for

Working on SharePoint 2013, running some custom code, which was trying to send an email through a shared SMTP server (virtual SMTP on IIS 6 as IIS7 doesn't supports it as far as I know, it's something I still need to look at so don't take my words on "it doesn't work on IIS7"), I received this error,

 Mailbox unavailable. The server response was: 5.7.1 Unable to relay for me@myCompany.com

Sending an email code was working on another server in the farm but not on mine, so a bit of googling find me this solution,


 1) Go to Server where you or your Network Administrator setup virtual SMTP server

 2) Go to Administrative Tools and click on IIS 6.0 Manager

 3) Right click "SMTP Virtual Server"

 4) Select Access tab

 5) Click on "Relay" in section Relay Restrictions

 6) Add 127.0.0.1 if not already in list(for me it was there)and then your server IP address to the list

 7) Click "OK" and job Done.


 I have followed these steps on a development machine and it made the code work for me perfectly, try these steps on Production server on your own risk ;).