Friday, February 8, 2013

Debugging CSOM (Client Object Model) Client-Side

If you didn't get the pleasure of attending @xenoxg's session at the FEDSPUG last night, you definitely missed some very noteworthy information.  Definitely check it out if you can...

Xenox asked a simple question last night: How many people in the room use Fiddler?
I quickly raised my hand because I have used this many times as well as many other people in the room.

After he showed us the network traffic that was produced from his application, I thought to myself: When was the last time I used Fiddler?  I couldn't answer that question...  I've used this amazing tool, but for some reason I didn't know the last time I actually used it.  The main reason for this is because I live in browsers every waking moment...  The tooling has become quite good on the front-end of the house and I've actually replaced my need of Fiddler with the tools baked into them.

Behold!

Internet Explorer Developer Tools: Network

Setup a Network Capture

IE Dev Tools Network Tab
If you are unfamiliar with the developer tools, just press F12 when you have IE open.  If you have IE9+ (as you should!), you'll see the lovely Network tab.  It's extremely simple to use and gives me all the info that I need.  All you have to do is press the "Start Capturing" button and then render your page.  Here's an example of the types of information you'll typically see.




Since this is a post about CSOM, the relevant line to us is already highlighted.  Notice the Javascript makes a call to http://pathToServer/_vti_bin/client.svc/ProcessQuery.  Once you've found this in the captured network traffic, you simply highlight that particular line and click "Go to detailed view".  This button is located directly underneath the Network tab.

Viewing the Server Response


I'm not going to pretend to know all of what this stuff means, but it is nice to look through it and learn more about how this all is glued together for us.  The two tabs here that I use the most are "Request Body" and "Response Body".  If you are big into the now deprecated web services, you can think of the "Request Body" as your SOAP envelope.  In fact under the hood, it's actually still sending XML to the server:

<!-- START CODEZ -->
<Request xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009" SchemaVersion="14.0.0.0" LibraryVersion="14.0.4762.1000" ApplicationName="Javascript Library">
<Actions>
<ObjectPath Id="1" ObjectPathId="0" />
<ObjectPath Id="3" ObjectPathId="2" />
<ObjectPath Id="5" ObjectPathId="4" />
<ObjectPath Id="7" ObjectPathId="6" />
<ObjectIdentityQuery Id="8" ObjectPathId="6" />
<ObjectPath Id="10" ObjectPathId="9" />
<Query Id="11" ObjectPathId="9">
<Query SelectAllProperties="false">
<Properties />
</Query>
<ChildItemQuery SelectAllProperties="false">
<Properties>
<Property Name="ID" SelectAll="true" />
<Property Name="FileRef" SelectAll="true" />
<Property Name="FSObjType" SelectAll="true" />
<Property Name="FolderChildCount" SelectAll="true" />
<Property Name="ItemChildCount" SelectAll="true" />
<Property Name="Title" SelectAll="true" />
<Property Name="Something01" SelectAll="true" />
<Property Name="Something02" SelectAll="true" />
<Property Name="Something03" SelectAll="true" />
</Properties>
</ChildItemQuery>
</Query>
</Actions>
<ObjectPaths>
<StaticProperty Id="0" TypeId="{3747adcd-a3c3-41b9-bfab-4a64dd2f1e0a}" Name="Current" />
<Property Id="2" ParentId="0" Name="Web" />
<Property Id="4" ParentId="2" Name="Lists" />
<Method Id="6" ParentId="4" Name="GetByTitle">
<Parameters>
<Parameter Type="String">My List Name</Parameter>
</Parameters>
</Method>
<Method Id="9" ParentId="6" Name="GetItems">
<Parameters>
<Parameter TypeId="{3d248d7b-fc86-40a3-aa97-02a75d69fb8a}">
<Property Name="FolderServerRelativeUrl" Type="String">/Lists/SomeListName</Property>
<Property Name="DatesInUtc" Type="Boolean">true</Property>
<Property Name="ViewXml" Type="String">&lt;View&gt;&lt;Query&gt;&lt;OrderBy&gt;&lt;FieldRef Name='Something03' Ascending='True' /&gt;&lt;/OrderBy&gt;&lt;/Query&gt;&lt;/View&gt;</Property>
<Property Name="ListItemCollectionPosition" Type="Null" />
</Parameter>
</Parameters>
</Method>
</ObjectPaths>
</Request>
<!-- END CODEZ -->

The "Response Body" comes to us in the form of JSON:

// START CODEZ
[
{
"SchemaVersion":"14.0.0.0","LibraryVersion":"14.0.4762.1000","ErrorInfo":null
},
1,
{
"IsNull":false
},
3,
{
"IsNull":false
},
5,
{
"IsNull":false
},
7,
{
"IsNull":false
},
8,
{
"_ObjectIdentity_":"740c6a0b-85e2-48a0-a494-e0f1759d4aa7:web:90a9005d-7dcd-4784-9ed0-b4f722941dc0:list:f832844d-5ed1-4e39-98f3-d39f5e37ea3b"
},
10,
{
"IsNull":false
},
11,
{
"_ObjectType_" : "SP.ListItemCollection",
"_Child_Items_": [
{
"_ObjectType_":"SP.ListItem","_ObjectIdentity_":"740c6a0b-85e2-48a0-a494-e0f1759d4aa7:web:90a9005d-7dcd-4784-9ed0-b4f722941dc0:list:f832844d-5ed1-4e39-98f3-d39f5e37ea3b:item:43,1","_ObjectVersion_":"3","ID":43,"FileRef":"\u002fLists\u002fSomethingNav\u002fTest3","FSObjType":"1","FolderChildCount":"5","ItemChildCount":"0","Title":"Test3","Something01":null,"Something02":null,"Something03":1
},
{
"_ObjectType_":"SP.ListItem","_ObjectIdentity_":"740c6a0b-85e2-48a0-a494-e0f1759d4aa7:web:90a9005d-7dcd-4784-9ed0-b4f722941dc0:list:f832844d-5ed1-4e39-98f3-d39f5e37ea3b:item:1,1","_ObjectVersion_":"3","ID":1,"FileRef":"\u002fLists\u002fSomethingNav\u002fTest","FSObjType":"1","FolderChildCount":"4","ItemChildCount":"0","Title":"Test","Something01":null,"Something02":null,"Something03":2
},
{
"_ObjectType_":"SP.ListItem","_ObjectIdentity_":"740c6a0b-85e2-48a0-a494-e0f1759d4aa7:web:90a9005d-7dcd-4784-9ed0-b4f722941dc0:list:f832844d-5ed1-4e39-98f3-d39f5e37ea3b:item:22,1","_ObjectVersion_":"3","ID":22,"FileRef":"\u002fLists\u002fSomethingNav\u002fTest2","FSObjType":"1","FolderChildCount":"5","ItemChildCount":"0","Title":"Test2","Something01":null,"Something02":null,"Something03":3
}
]
}

// END CODEZ

Making Sense of it All

Let's get one thing clear, if you can make sense of this "Response Body" and why it's formulated the way that is it, you deserve a raise.  This portion of JSON that starts to make sense is directly after the 11.  Knowing what your JSON looks like can make it real easy to not only debug your scripts, but also definitively prove your script is communicating with the server correctly.  With this at your fingertips, there's no real need for me to use another piece of software.  And that's why I couldn't remember the last time I used Fiddler.  My browser(s) do everything I was using Fiddler for.  I'm definitely not saying it's a replacement, however for my needs, the browser suffices.  

Happy coding!

No comments: