Wednesday, October 31, 2012

SharePoint list : Get distinct field values from silverlight application

I was in search of any way which will give me distinct field values without using server object model.
I wanted to get distinct field values either by client object model or any other way from client side in my silverlight application.

Many days of search...but no luck :(

Then I decided to do some hacking and focused on the way SharePoint gets distinct field values while displaying filter options on list header.

After bit of hacking using fidler I came to know, SharePoint calls filter.aspx page in Layouts folder and displays it in iframe.
That page calls server side method to get distinct values and displays those values in dropdown.
I decided to write a method in my silverlight application which will request filter.aspx.

Here is the code which I have written. It requests page, gets response in the form of html string, parses string to get field values and adds field values to generic list.


private List<string> fieldValues;

        public void GetDistinctFieldValues(string siteUrl,string listGuid, string viewGuid,string fielInternaldName)

        {
            string requestURL = string.Empty;
            //Form request url
            requestURL = siteUrl+"/_layouts/filter.aspx?ListId="+listGuid+"&FieldInternalName="+fielInternaldName+"&ViewId="+viewGuid+"&FilterOnly=1&Filter=1";

            //Create request instance
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(requestURL));
            request.BeginGetResponse(new AsyncCallback(getFieldValueCallback), request);
        }

 
        private void getFieldValueCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);


            using (StreamReader streamReader1 = new StreamReader(response.GetResponseStream()))

            {
                string resultString = streamReader1.ReadToEnd();

                fieldValues = new List<string>();

                resultString = resultString.Replace("\"", string.Empty);

                //Regular expression to match with HTML string and get options from Select.

                Match m = Regex.Match(resultString, @"<OPTION Value=s*(.+?)\s*\>s*(.+?)\s*\</OPTION>");

                while (m.Success)

                {
                    //Add field value to generic list

                    fieldValues.Add(m.Groups[1].Value);

                    m = m.NextMatch();
                }
            }
       }
 
Make sure to add references for:
  System.Net
 and  System.Text.RegularExpressions

Usage: GetDistinctFieldValues(http://<myserver>/sites/prasadtest, "{79351260-0F78-44FD-A5B1-1464F961F044}", "{B4A91266-0570-4563-B6C8-221EE543D328}","Title");
Here I am passing site url, list GUID, list view GUID and internal name of the field for which I want distinct values.

 
This code adds field values to generic list named fieldValues.
 
If we want to get it using JavaScript, then also we can achieve this. I am not a JavaScript expert so I am assigning this task to you. Please achieve same thing with JavaScript and post comment to this article.

Please note that this method will not work if your list view exceeds list item threshold limit. So to get this working configure view correctly with appropriate filtering criteria and row limit.

Wednesday, September 26, 2012

SharePoint – How to get Site Usage Information Using Client Object Model

Getting site usage information using client object model is very simple.
We have to load “Usage” property of site and use “UsageInfo” class provided in client object model.
Data type of Usage property is UsageInfo. We can get information related to usage like hits, site visits and also storage for the site.
Here I have written sample method which will give us required usage data.
private void GetSiteUsageData()
        {
            string usageData = string.Empty;
            clientContext.Load(clientContext.Site,
            s => s.Usage);
            clientContext.ExecuteQueryAsync((s, args) =>
            {
                UsageInfo usageInfo = clientContext.Site.Usage;
                usageData = "No. of hits: " + Convert.ToString("" + usageInfo.Hits) + "; ";
                usageData += "No. of visits: " + Convert.ToString("" + usageInfo.Visits) + "; ";
                usageData += "Storage: " + Convert.ToString("" + usageInfo.Storage) + "; ";
                usageData += "Storage Percentage Used: " + Convert.ToString("" + usageInfo.StoragePercentageUsed) + "; ";
            },
            (s, args) =>
            {
                //"Error loading usage information.
            });           
        }
 
Here are the details of properties,
 
Property Name
Data Type
Description
Hits
Long
Gives total number of hits to the site
Visits
Long
Gives number of page visits
Storage
Long
Gives total storage used in MB
StoragePercentageUsed
Double
Gives percentage of storage used by site
 
This is handy when you want to get usage information using client object model.

Tuesday, September 25, 2012

SharePoint - Get List Item Versions Using Client Object Model


In last few posts I talked about how to work on file versions using web service and using client object model. Those posts described how to play around versions of file in document library. What if I want to get, delete or restore versions of list item?

Obviously, first thing we will do is to find any property related to version for “ListItem” class. But there is no such property available. L

What to do now?

There is a simple way, use methods in my last post and trick is to pass “fileUrl” parameter.

In case of file in document library, I suggested to pass this parameter like:
 

"/sites/prasad/teamsite/MyLibrary/testexcel.xlsx"
 

For list item we have to tweak this and pass “fileUrl” parameter as:
 

"/sites/prasad/teamsite/Lists/MyList/30_.000”
 

Here 30 is item id for item of which I want to get version history.
Yes, we are good to go now. We can play around versions of list items also. Hurray!!!

SharePoint - Get File Versions Using Client Object Model


In two of my previous posts I discussed how to get, delete and resore file versions programmatically.
I suggested way of getting versions using web service. Now let’s do the same thing with Silverlight client object model. Same thing can be done with JavaScript object model with some syntax changes.
Here I am considering same scenarios which we considered when we used web service. To put this in other way I have written sample methods for the operations which are possible by client object model.
These are some sample methods:
I have placed clientcontext object to App level. So I am using App.clientContext in my code.

Remember to load clientcontext before using these methods.

Get all versions:

private void GetAllFileVersions(string fileUrl)

{  

    FileVersionCollection fileVersionCollection;

    file = App.clientContext.Web.GetFileByServerRelativeUrl(fileUrl);

    fileVersionCollection = file.Versions;

    App.clientContext.Load(file);

    App.clientContext.Load(fileVersionCollection);

    App.clientContext.ExecuteQueryAsync((s, args) =>

    {

        int numberOfVersions = fileVersionCollection.Count;

    },

    (s, args) =>

    {

        //"Error loading versions.

    });

}
 

Usage:

GetAllFileVersions("/sites/prasad/teamsite/MyLibrary/testexcel.xlsx");
 

Description:

This method will load file version collection. You can iterate through each file version and get values for various properties which will give you date of creation, user object of user who created version, url of file for that version and Boolean value that tells if it is a current version of file.

  
Delete Specific Version Using Version ID:

        private void DeleteSpecificFileVersion(string fileUrl, int versionId)

        {

            file = App.clientContext.Web.GetFileByServerRelativeUrl(fileUrl);

            App.clientContext.Load(file);

            file.Versions.DeleteByID(versionId);

            App.clientContext.ExecuteQueryAsync((s, args) =>

            {

                //"Deleted file version successfuly.

            },

            (s, args) =>

            {

                //"Error deleting file version.

            });

        }
 

Usage:

DeleteSpecificFileVersion("/sites/prasad/teamsite/MyLibrary/testexcel.xlsx",512);
 

Description:

This method deletes specific version of file when version Id is provided. Interesting fact here is what is version id?

While iterating through versions of file you can get version id from “ID” property of “FileVersion” class.

Version ids are in multiple of 512.i.e. for first version it is 512, for second version it is 1024, for third version it is 1536 and so on.
 

Delete Specific Version Using Version Label:

        private void DeleteSpecificFileVersion(string fileUrl, string versionLabel)

        {

            file = App.clientContext.Web.GetFileByServerRelativeUrl(fileUrl);

            App.clientContext.Load(file);

            file.Versions.DeleteByLabel(versionLabel);

            App.clientContext.ExecuteQueryAsync((s, args) =>

            {

                //"Deleted file version successfuly.

            },

            (s, args) =>

            {

                //"Error deleting file version.

            });

        }
 

Usage:

DeleteSpecificFileVersion("/sites/prasad/teamsite/MyLibrary/testexcel.xlsx", "2.0");
 

Description:

This method deletes specific version of file when version label is provided. Version label means version number which you see on UI. i.e. “1.0”, “2.0”,”3.0” and so on.

While iterating through versions of file you can get version label from “VersionLabel” property of “FileVersion” class.

 

Delete All File Versions:

        private void DeleteAllFileVersions(string fileUrl)

        {

            file = App.clientContext.Web.GetFileByServerRelativeUrl(fileUrl);

            App.clientContext.Load(file);

            file.Versions.DeleteAll();

            App.clientContext.ExecuteQueryAsync((s, args) =>

            {

                //"Deleted all file versions successfuly.

            },

            (s, args) =>

            {

                //"Error deleting old file versions.

            });

        }
 

Usage:

DeleteAllFileVersions("/sites/prasad/teamsite/MyLibrary/testexcel.xlsx");
 

Description:

This simply deletes all the versions of file but current version.
 

Restore Specific Version:

        private void RestoreSpecificFileVersion(string fileUrl, string versionLabel)

        {

            file = App.clientContext.Web.GetFileByServerRelativeUrl(fileUrl);

            App.clientContext.Load(file);

            file.Versions.RestoreByLabel(versionLabel);

            App.clientContext.ExecuteQueryAsync((s, args) =>

            {

                //"Restored file version successfuly.

            },

            (s, args) =>

            {

                //"Error restoring old file versions.

            });

        }
 

Usage:

RestoreSpecificFileVersion("/sites/prasad/teamsite/MyLibrary/testexcel.xlsx", "3.0");
 

Description:

This method restores specific version of file when version label is provided.
 
To get current version of file use “UIVersion” or “UIVersionLabel” properties of “File” class. These properties will return you version id and version label respectively.

Interesting fact is version ids which SharePoint maintains. As I mentioned earlier, these are in multiples of “512”. URL of file version contains this version id in it. E.g.–

URL of first Version:                      http://[My Site URL]/_vti_history/512/MyLibrary/testexcel.xlsx

URL of second Version:               http://[My Site URL]/_vti_history/1024/MyLibrary/testexcel.xlsx

URL of third Version:                    http://[My Site URL]/_vti_history/1536/MyLibrary/testexcel.xlsx

Getting this path is nothing fancy. If you look at the version history of any file you can get this.
Just mouse over the link for each version and observe URL, you will get URL in above mention format.
Most important thing, current version of file will not include version id in its URL.
I learned many things from above exercise. Did you?

Wednesday, September 19, 2012

SharePoint Client Object Model: Using lambda expression for ExecutequeryAsync

When using "ExecuteQueyAsync" method of client object model we genarally write two different callback methods for success and failure. Instead of that we can use "Lambda Expression" and avoid two separate methods. This will also avoid class level variables and we  can access parameters of calling method in callback too.
Here is one simple example of usage of lambda expression.

private void UpdateItem(int itemId, string fieldName, object fieldValue)

{
ListItem item = clientContext.Web.Lists.GetByTitle("MyList").GetItemById(itemId);

item[fieldName] = fieldValue;

item.Update();

clientContext.ExecuteQueryAsync((sender, args) =>

{
//On update success

MessageBox.Show("Item with id "+ itemId.ToString()+" updated successfuly");

},

(s, args) =>

{
//on update failure

MessageBox.Show("Error occurred updating item: " + itemId.ToString());

});

}
Hope this helps to those who are unaware of using lambda expression.

SharePoint: How to move files from one document library to other using RPC in Silverlight application. Presrve created and modified information.

In my last post I talked about Uploading large files to SharePoint using RPC call. In this post I am going to tell how to move or copy file from one document library to other.
For basics of RPC, please follow links given in my last post.
So, here is my code which uses RPC method to copy file.

private string rpcCallString = string.Empty;

private byte[] newFileData;

public void MoveFile(string CurrentWebUrl, string serviceName, string newFilePath, string oldFilePath)

{
string requestUrl = CurrentWebUrl + "_vti_bin/_vti_aut/author.dll";

 string method = GetEncodedString("move document:14.0.0.5123");

serviceName = GetEncodedString("/" + serviceName);

 string putOption = "edit";

oldFilePath = GetEncodedString(oldFilePath);

newFilePath = GetEncodedString(newFilePath);

rpcCallString =
"method={0}&service_name={1}&oldUrl={2}&newUrl={3}&rename_option=findbacklinks&put_option={4}&docopy=false";

rpcCallString = String.Format(rpcCallString, method, serviceName, oldFilePath, newFilePath, putOption).Replace("_", "%5f");

 HttpWebRequest wReq = WebRequest.Create(requestUrl) as HttpWebRequest;

wReq.Method = "POST";

wReq.Headers["Content"] = "application/x-vermeer-urlencoded";

wReq.Headers["X-Vermeer-Content-Type"] = "application/x-vermeer-urlencoded";

wReq.BeginGetRequestStream(new AsyncCallback(gotFileMoveRequestStream), wReq);

}

private void gotFileMoveRequestStream(IAsyncResult asynchronousResult)

{HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;

 Stream requestStream = webRequest.EndGetRequestStream(asynchronousResult);

 byte[] fileData = Encoding.UTF8.GetBytes(rpcCallString);

requestStream.Write(fileData, 0, fileData.Length);

requestStream.Close();

webRequest.BeginGetResponse(
new AsyncCallback(gotFileMoveResponse), webRequest);

}

private void gotFileMoveResponse(IAsyncResult asynchronousResult)

{
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;

 HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);

 Stream responseStream = webResponse.GetResponseStream();

 StreamReader reader = new StreamReader(webResponse.GetResponseStream());

 string responseString = string.Empty;

responseString = reader.ReadToEnd();byte[] fileBuffer = Encoding.UTF8.GetBytes(responseString);

responseStream.Close();

reader.Close();

webResponse.Close();
if (responseString.IndexOf("\n<p>message=successfully") < 0)

{throw new Exception(responseString);
 
}           
}

and here is the utility method.

public string GetEncodedString(string SourceString)

{
if (!string.IsNullOrEmpty(SourceString))

{
return HttpUtility.UrlEncode(SourceString).Replace(".", "%2e").Replace("_", "%5f");

}
 
else

{
return SourceString;

}

}


Let's discuss parameters now.
method is move document. 14.0.0.5123 is server extension version for SharePoint 2010.
oldUrl and newUrl are the paths of old and new files respectively.
rename_option is set to findbacklinks, which means all the references to the file will also be updated for new location.
Here is the parameter for which many like me are looking for. Parameter which will allow us to preserve created and modified information even if we copy or move file from one location to other. And the parameter used is put_option which when set to "overwrite", overwrites file with same name, when set to "edit" prompts with message saying file with same name exists and IF SET TO "migrationsemantics" PRESERVES CREATED and MODIFIED INFORMATION.
If we set docopy to true it will only copy file to new location but if it is set to false it will move file from old location to new location. Default value for it is false.
Here is example of call to above method.
 


MoveFile("http://myserver/sites/prasad/teamsite/", "sites/prasad/teamsite", "Shared Documents/document1.docx", "MyDocLib/document1.docx");

Remember the way paths are provided. It is very important.
For more information about "
move document" method visit MSDN.
This method will be very useful when you want to migrate data from one site to another.
So are you ready to use this method for your next migration task???