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 ;).

Monday, 17 February 2014

Quick Guide for setting up SharePoint environment for Apps

Following several guides and going through many articles at last I am able to install SharePoint Apps on my environment, you will find several incomplete and confusing articles on internet.

I followed Vlad Catrinescu article which is to the point and actually works, it took me just 5 minutes to configure my test environment for installing apps from SharePoint online Store.

Here's link to Vlad's article,

http://www.scribd.com/doc/124831209/Configure-an-Environment-for-Apps-for-SharePoint-2013-Step-by-Step-Guide

Since the above article gets into much details along with screenshots, I will just mention important points you need to go through to get it working,

- Create a forward look-up zone with zone name e.g. "exampleapps.com"

- Create a New Alias (CNAME) with name as "*" and FQDN for target host as full name of your     SharePoint Server, e.g. www.exampleServer.com or whatever's your server's name is

- Now on your try to ping Apps-23423423423.exampleapps.com and get the response, if it doesn't work then either you entered FQDN of target host wrong or your DNS server isn't locating your SharePoint web server. Put a comment if you get stuck here and I will try to help.

- Create, configure and start SharePoint App management and Subscription server on your SharePoint server

-  Now Configure App URLs in Central Admin, App domain going to be exampleapps.com in this case and App prefix will be "Apps"

- You will need to configure internet facing endpoints for apps, so I just enabled web application scoped feature named as "Apps that require accessible internet facing endpoints" on my port 80 web application.

- Create a new web application on port 80, but keep the Host Header option empty and rest options as usual, now note, if you used SharePoint configuration wizard then you don't need to create a new web application because SharePoint configuration wizard by default creates a web application without host headers, so all you need to do is to create a root site collection.

- Last but important step, delete Default Website in IIS Server, otherwise you will receive 404 errors for sharepoint apps.

Note: I followed these steps on a development server, so try them on production on your own risk :-).

MSDN article if you want to follow for setting up App domain.

http://technet.microsoft.com/en-us/library/fp161236.aspx

Saturday, 15 February 2014

Error occurred in deployment step 'Uninstall app for SharePoint': The local SharePoint server is not available.

Hmmm, was excited enough to deploy my first SharePoint hosted app but this error ruined the joys,

Error occurred in deployment step 'Uninstall app for SharePoint': The local SharePoint server is not available. Check that the server is running and connected to the SharePoint farm.

Now what ? error doesn't help much at all, so lets look at logs, the way I debug any issue regarding SharePoint is,

 - Check event logs in Event Viewer.

 - If don't find anything in Event Viewer then ULS Viewer, check this post if you don't know how to debug       using ULS Viewer.


Other than that you can also use SVC_Trace exe or fiddler for debugging web services or client side code, anyway coming back to topic, in this case I find the real error in event viewer,

SQL database login for 'TestServer01_Config' on instance 'SQLTEST01' failed. Additional error information from SQL Server is included below.
Login failed for user 'DEV\mr'.

So when we deploy a solution to SharePoint site using Visual Studio, it uses the account we are running Visual Studio as to deploy the solution, which in return makes changes to SharePoint config database, so if account doesn't have access to SP config, it will fail to deploy solution. As you would had figured out the solution, just give development account permission to SharePoint config database.

Edit

I have given my development account SP_DATA_ACCESS permissions on all relevant databases as shown in picture below,



Edit-2

Unfortunately above steps didn't solved the problem and lead to another error,
SQL Database 'WSS_Content_Dev' on SQL Server instance 'TESTSERVER01' not found. Additional error information from SQL Server is included below.
Cannot open database "WSS_Content_Dev" requested by the login. The login failed.
Login failed for user 'DEV\mr'.

Giving development user "dev\mr" in this case "SP_Data_Access" permissions on WSS_Content_Dev solved the problem :-).

This solved the problem of deploying my first app to SharePoint server.



Note:
I am giving development account permissions to SharePoint configuration database because it's a test environment, however if on production environment, your SharePoint administrator account should be deploying the solution and should have right permissions already.

Thursday, 6 February 2014

Debugging WCF service using SvcTraceView on application server

Debugging web services can be pain, specially when they are hosted on a application server within a SharePoint farm. There are several ways one can debug web services though, e.g. using a visual studio remote debugger but what if it doesn't hit your web services breakpoints or your network administrator do?

Easiest way to figure out what's wrong with web services is to use SvcTraceViewer.exe e.g. why my code not able to find the hosted service or if the problem is with service account authentication.

Not so difficult to set it up, all you need to do is to add a some tag in your hosted WCF services and then open the SvcTraceViewer to view the created file.

Step-1:
Find hosted WCF service's web.config and add following tag to it within configuration tag. It will recycle the application pool of hosted service itself when you will save changes to web.config file.


<configuration>
<system.diagnostics>
    <trace autoflush="true" />
    <sources>
            <source name="System.ServiceModel" 
                    switchValue="Information, ActivityTracing"
                    propagateActivity="true">
            <listeners>
               <add name="sdt" 
                   type="System.Diagnostics.XmlWriterTraceListener" 
                   initializeData= "WcfConfigExample.e2e" />
            </listeners>
         </source>
    </sources>
</system.diagnostics>
</configuration>


Step-2:
Find SvcTraceViewer.exe within installed Visual studio files, location might change depending on version of VS, however since I am using VS 2010 ultimate so I find EXE file at,

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools

In some cases you will need to open the EXE file as administrator.

Step-3:
Do something to trigger WCF services and check folder where web.config file exists as that's where it will create "SdrConfigExample.e2e" log file, once you find it. just open the SvcTraceViewer.exe file.

Step-4:
Press Ctrl + O keys; Navigate to SdrConfigExample.e2e file to load log trace file in viewer.

Step-5:
Search for specific terms using Ctrl + F or just go through logs. You can also add custom logs to your WCF service and find them in here to figure out where exactly your code is getting exception at, You can find more about Trace Viewer at, http://msdn.microsoft.com/en-us/library/aa751795(v=vs.110).aspx

Thursday, 17 October 2013

C# The Handle is Invalid


I have been given a task to debug a SharePoint event receiver as it wasn't doing what was meant to do, so I started by looking at event viewer logs. 

Event viewer error didn't helped much other then saying;

Error loading and running event receiver **Assembly Details**. Additional information is below.
: The handle is invalid

Searched google lot but couldn't find anything relevant in SharePoint context, but somehow figured out, this error "The handle is invalid" comes up when user doesn't have enough permissions to perform a task and in my case it was when event receiver tried to create a new event log or even when try to write a log to already created event log.

Fixed the issue by putting code within   SPSecurity.RunWithElevatedPrivileges(delegate(){  }); block, however couldn't figure out which exact permission was required to let user to write event logs but adding above fixed the issue for me, so all good.

Tuesday, 1 October 2013

Mass unfollow on twitter using chrome

Simply go to https://twitter.com/following and then inspect any element, find console tab and type this script line 

$('.unfollow-text').click() 

It will press all the unfollow buttons for you, if you want to unfollow all then use page down key so all people you are following will become visible on page then run above script in console.