Tuesday, May 12, 2009

How to programmatically attach a document or file in a SPListItem

How to programmatically attach a document or file in a SPListItem

In this post I discussed, how we can programmatically attach a document or file in a SPListItem of SPList (SharePoint's List).

Following method contains the logic to attach the document / file (codes with comments are self-explainatory).



/// <summary>
/// Programmatically Attach document in SPDocument Library
/// </summary>
void documentAttachmentInSPList()
{
//SPListItem spListItem = null; //write code to get the SPListItem.
//fileUpload is control ID of ASP.Net FileUpload control
if (!string.IsNullOrEmpty(fileUpload.FileName))
{
//Get file extension ( *.doc OR *.docx )
string fileExtension
= fileUpload.FileName.Substring(fileUpload.FileName.IndexOf("."));

//FILENAME is file name visible in SPListItem
//Check file is already added or not. If added then delete it.
for (int i = 0; i < spListItem.Attachments.Count; i++)
{
if ((spListItem.Attachments[i] != null)
&& (spListItem.Attachments[i].Equals("FILENAME" + fileExtension)))
{
spListItem.Attachments.Delete("FILENAME" + fileExtension);
break;
}
}

//Attach the file.
spListItem.Attachments.Add("FILENAME" + fileExtension, fileUpload.FileBytes);

//LISTNAME is SPList's name
//See the attached file as link in user-created custom column.
string attachmentURL = Request.Url.Scheme + "://" + Request.Url.Authority
+ "/Lists/" + "LISTNAME" + "/Attachments/" + spListItem.ID + "/";

spListItem["Attached File"]
= attachmentURL + "FILENAME" + fileExtension + ", View FILE";
}
}

How to programmatically upload a document in a SPDocumentLibrary

In this post I discussed, how we can programmatically upload a document in a SPDocumentLibrary (SharePoint's document library).

Following method contains the logic to upload the document (codes with comments are self-explainatory).



/// <summary>
/// Programmatically UPLoad document in SPDocument Library
/// </summary>
void documentUploadInSPDocumentLibrary()
{
//fileUpload is ASP.Net FileUpload control.
if (!string.IsNullOrEmpty(fileUpload.FileName))
{
SPSite oWebsite = SPContext.Current.Web;
oWebsite.AllowUnsafeUpdates = true;
SPDocumentLibrary docLib
= oWebsite.Lists["DOCLIB_NAME"] as SPDocumentLibrary;

//Get file extension ( *.doc OR *.docx )
string fileExtension
= fileUpload.FileName.Substring(fileUpload.FileName.IndexOf("."));
byte[] fileBytes = fileUpload.FileBytes;
string destUrl
= docLib.RootFolder.Url + "/" + "MyFileName" + fileExtension;
SPFile destFile = docLib.RootFolder.Files.Add(destUrl, fileBytes, true);
destFile.Update();

oWebsite.AllowUnsafeUpdates = true;
}
}

Check Record or FileName in a SPDocument Library

In this post I discussed how we can check whether a particular record / filename exist in a SPDocumentLibrary (SharePoint's document library) or not.

In the following method, first I discussed the 4 approaches suggested in following blog/forum, then the 5th apporach (in which I used SPQuery).

According to me the 5th and last approach is good-one because it would't raise an Exception.




/// <summary>
/// Check FileName/Records in SPDocumentLibrary
/// </summary>
void docLibFileExits()
{
SPWeb currentSite = SPContext.Current.Web;
SPDocumentLibrary docLib
= (SPDocumentLibrary)currentSite.GetList(currentSite.Url + "/Documents");

//APPROACH 1
if (docLib.RootFolder.Files[fileName] != null)
{
// do something
//This throws an Argument Exception
}

//APPROACH 2
if (docLib.RootFolder.Files[fileName].Exists == true)
{
// do something
//Again this throws a Argument Exception
}

//APPROACH 3
if (currentSite.GetFile(fileName).Exists == true)
{
// do something
//work
}

//APPROACH 4
bool fileExist = true;

try { docLib.RootFolder.Files[fileName]; }
catch (ArgumentException) { fileExist = false; }

if (fileExists)
{
//...
}



//APPROACH 5
SPSite oWebsite = SPContext.Current.Web;
SPList docLib = oWebsite.Lists["docLib"] as SPDocumentLibrary;
SPListItemCollection itemcolCVs = null;
SPQuery oQueryFileCheck = new SPQuery();

string FILENAME = ""; //FileName that you want to search.

//You can use EQUALS or CONTAINS operation as per your requirement.
//
/*
StringBuilder strBFileCheckQuery = new StringBuilder(
"<Where>" +
"<Eq>" +
"<FieldRef Name='FileLeafRef' />" +
"<Value Type='Text'>FILENAME</Value>" +
"</Eq>" +
"</Where>");
*/

StringBuilder strBFileCheckQuery = new StringBuilder(
"<Where>" +
"<Contains>" +
"<FieldRef Name='FileLeafRef' />" +
"<Value Type='Text'>FILENAME</Value>" +
"</Contains>" +
"</Where>");

oQueryFileCheck.Query = strBFileCheckQuery.ToString();
if (docLib.GetItems(oQueryFileCheck).Count > 0)
{
//To do
}

}





P.S. Here CAML Query Builder helped me a lot to identify and build above SPQuery.

CAML Tips n Tricks --- Part 2

CAML --- Collaborative Application Markup Language

In continuation with my previous post ---
CAML Tips n Tricks

In this post I am going to discuss about CAML query for batch Update and Delete.

1) BATCH DELETE


    
/// <summary>
/// Get the CAML query for BATCH DELETION
/// </summary>
/// <param name="spList">SPList instance</param>
/// <returns>SPQuery</returns>
StringBuilder buildBatchDeleteCommand(SPList spList)
{
StringBuilder sbDelete = new StringBuilder();
sbDelete.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");

string command = "<Method>" +
"<SetList Scope=\"Request\">" + spList.ID + "</SetList>" +
"<SetVar Name=\"ID\">{0}</SetVar>" +
"<SetVar Name=\"Cmd\">Delete</SetVar>" +
"</Method>";

foreach (SPListItem item in spList.Items)
{
sbDelete.Append(string.Format(command, item.ID.ToString()));
}
sbDelete.Append("</Batch>");
return sbDelete;
}

/// <summary>
/// Multiple records Deletion with SPQuery
/// </summary>
void BatchDelete(Object sender, EventArgs e)
{
//Get the SPQuery
StringBuilder finalDeleteAllQuery = buildBatchDeleteCommand(oList);

//Get the SPSite and Allow unsafe updates
SPSite oWebsite = SPContext.Current.Web;
oWebsite.AllowUnsafeUpdates = true;

//Run the Batch command
oWebsite.ProcessBatchData(finalDeleteAllQuery.ToString());

//Disable unsafe updates
oWebsite.AllowUnsafeUpdates = false;
}




2) BATCH UPDATE


/// <summary>
/// Get the CAML query for BATCH UPDATION
/// Here building SPQuery to change "Final Status" column's value
/// </summary>
/// <param name="spList">SPList instance</param>
/// <returns>SPQuery</returns>
StringBuilder buildBatchUpdateCommand(SPList spList)
{
StringBuilder sbDelete = new StringBuilder();
sbDelete.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");

string command = "<Method>" +
"<SetList Scope=\"Request\">" + spList.ID + "</SetList>" +
"<SetVar Name=\"ID\">{0}</SetVar>" +
"<SetVar Name=\"Cmd\">Save</SetVar>" +
"<SetVar
Name=\"urn:schemas-microsoft-com:office:office
#Final_x0020_Status\">{1}</SetVar>" +
"</Method>";

//SPView specific SPListItems, you can skip following 3 lines
//and directly run foreach on SPList.
//E.g, foreach (SPListItem item in spList.Items)
SPView spView = spList.Views["SPView_NAME"];
SPViewFieldCollection collViewFields = spView.ViewFields;
SPListItemCollection collItemsSrc = spList.GetItems(spView);

foreach (SPListItem item in collItemsSrc)
{
sbDelete.Append(string.Format(command, item.ID.ToString(), "Completed"));
}

sbDelete.Append("</Batch>");
return sbDelete;
}

/// <summary>
/// Multiple records Update with SPQuery
/// </summary>
void BatchUpdate()
{
//Get the SPQuery
StringBuilder finalUpdateAllQuery = buildBatchUpdateCommand(oList);

//Get the SPSite and Allow unsafe updates
SPSite oWebsite = SPContext.Current.Web;
oWebsite.AllowUnsafeUpdates = true;

//Run the Batch command
oWebsite.ProcessBatchData(finalUpdateAllQuery.ToString());

//Disable unsafe updates
oWebsite.AllowUnsafeUpdates = false;
}

Programmatically Export records from SPList to MS Excel

Programmatically export records from SPList to MS Excel in SharePoint.
What does above sentence mean???

Basically if you are a SharePoint developer OR user then you might know that we can do Import/Export between SPList and Microsoft Excel.
In this post I will discuss only about Export of records from SPList to MS Excel.
If you open a SharePoint's SPList, then in Action Toolbar, contains a link to open/export the SPList (in current applied SPView) in Excel Workbook and hence save it a Excel file (*.xls / *.iqv).

Now to achieve the above task programmatically we have to do some extra efforts:

1) Get the GUID of SPList - from where you want to export the records/SPListItem.



//SPList oList = ""; //Code to get the SPList

//Here I convert the GUID in Uppercase
//and remove the special character hypen ('-') with required string.
string listGUID = oList.ID.ToString().ToUpper().Replace("-", "\u00252D");



2) Get the GUID of SPView - it can be default one (All Items) or custom SPView with required columns and settings like sorting, filter, etc.



//Here I convert the GUID in Uppercase
//and remove the special character hypen ('-') with required string.
string viewGUID
= oList.Views["ExportRecords"].ID.ToString().ToUpper().Replace("-", "\u00252D");



3) Build the command, that will get executed on link's click.


//string spListName --- is SPList name.
//I removed the special characters in that also.

//Here for readibility point of view I used string,
//you must use StringBuilder from performance point of view.
string strCommand = "javascript:EnsureSSImporter();"
+ "javaScript:ExportList('\u002f_vti_bin\u002fowssvr.dll?CS=65001\u0026"
+ "Using=_layouts\u002fquery.iqy\u0026"
+ "List=\u00257B" + listGUID + "\u00257D\u0026"
+ "View=\u00257B" + viewGUID + "\u00257D\u0026"
+ "RootFolder=\u00252FLists\u00252F"
+ spListName.Replace("_", "\u00255F") + "\u0026"
+ "CacheControl=1')";



4) Consume/Call the above command via link's click.


<a id="linkExportData" onclick="<%=strCommand %>"
class="ms-sitetitle" style="font-size: 10px;">Export Records</a>




You can write the C# code of Step 1,2 and 3 in Page_Load event and HTML code of step 4 anywhere in you aspx page.

So when you click the "Export Records" link, it pop-up a dialog box to open the Records/SPList in Execl Workbook, that you can later on SAVE AS Excel file.

Once again IE Developer toolbar helped me to find the above solution/trick :)

Friday, March 20, 2009

Object Oriented Programming (OOPs) in JavaScript

In this post basically I am trying to use Object Oriented Programming (OOPs) concept in JavaScript. Normally we tend to write just simple functions in JavaScript file, by this we are doing Procedural Programming. In this post I incorporated following OOPs concepts:
Object, Class, Inheritance, Encapsulation, Property, Polymorphism (Override).

Following is the sample code of JavaScript file (codes are self-explanatory with adequate comments):



//Class diagram --- Employee class inherits Person class and
// Person class itself contains Academic class.
//
// Person ---> Academic
// ^
// /|\
// |
// |
// Employee

//OOPS features ---
//Object, Class, Inheritance, Encapsulation, Property, Polymorphism (Override).

//==============================================================================//
//==============================================================================//

//Global functions, just like a Utility library.
//Function to display Academic's data.
Function.prototype.DisplayAcademic = function(paramAcademic)
{
alert("In DisplayAcademic -> " + "Degree :: " + paramAcademic.degree
+ ", Year :: " + paramAcademic.year + ", College :: "
+ paramAcademic.college + ", Percentage :: " + paramAcademic.percentage);
}

//Function to display Person's data.
Function.prototype.DisplayPerson = function(paramPerson)
{
alert("In DisplayPerson -> " + "Name :: " + paramPerson.name
+ ", Age :: " + paramPerson.age
+ ", Gender :: " + paramPerson.gender);

//Function call to display Academic's data.
Function.prototype.DisplayAcademic(paramPerson.GetAcademic());
}

//==============================================================================//
//==============================================================================//

//Person class definition.
function Person(paramName, paramAge, paramGender)
{
//Person class variable.
this.name = paramName;
this.age = paramAge;
this.gender = paramGender;

//Get/Set property of Person class.
var academic;
this.GetAcademic = function(){return academic;}
this.SetAcademic = function(paramAcademic){academic = paramAcademic;}

//Function to display Person's data.
this.display = function(objectEmployee)
{
Function.prototype.DisplayPerson(objectEmployee);
}
}

//Academic class definition.
function Academic(paramDegree, paramYear, paramCollege, paramPercentage)
{
//Academic class variables.
this.degree = paramDegree;
this.year = paramYear;
this.college = paramCollege;
this.percentage = paramPercentage;
}


//Employee class definition.
function Employee(paramCompany, paramExperience)
{
//Employee class variables.
this.company = paramCompany;
this.experience = paramExperience;

/*
//User inputs
var degree = prompt("Degree", "Please enter your degree.");
var year = prompt("Year", "Please enter your passing year.");
var college = prompt("College", "Please enter your college.");
var percentage = prompt("Percentage", "Please enter your percentage.");
*/
//Call to set the academic property in Person class.
//this.SetAcademic(new Academic(degree, year, college, percentage));

this.SetAcademic(new Academic("M.C.A", 2005, "D.D.U", 67.00));

//Function to display Employee class data.
this.displayEmployee = function()
{
alert("In Employee -> " + "Company :: " + this.company
+ ", Experience :: " + this.experience);
this.display(this);
}
//To override base class function, just keep the function name same.
//In above function, if we change the function name from 'displayEmployee'
//to 'display', then always child class function gets called.
}

//==============================================================================//
//==============================================================================//

//Page load function.
function load()
{
/*
//User inputs.
var name = prompt("Name", "Please enter your name.");
var age = prompt("Age", "Please enter your age.");
var gender = prompt("Gender", "Please enter your gender.");
var companyName = prompt("Company Name", "Please enter your company name.");
var experience = prompt("Experience", "Please enter your total experience.");
*/
//Create a Employee class instance.
//var avin = new Employee(companyName, experience, name, age, gender);

//Set the base (Person) class.
Employee.prototype = new Person("Avi", 28, "M");
var avin = new Employee("PSL", 4.00);

alert("Is Employee Object is instance of Employee class? "
+ (avin instanceof Employee)
+ "\nIs Employee Object is instance of Person class? "
+ (avin instanceof Person));

if(confirm("Do you want to display Employee data?"))
{
//Call to display Employee's data.
avin.displayEmployee();

//Direct base (Person) class function call.
avin.display(avin);
}
}




Following is the sample HTML file to test the above JavaScript file:



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>OOPs in JavaScript</title>

<script src="OOPsInJavaScript.js" type="text/javascript"></script>

</head>
<body onload="javascript:load();">
OOPs in JavaScript sample.
</body>
</html>




Following image displays Employee's class object:



Following image displays Academic's class object:



Please feel free to write if I miss something or to improve the post.


References:
The JavaScript Object Model

Object Oriented Programming in JavaScript

Sunday, February 1, 2009

ASP.Net Web Forms Syntax

Following are some useful syntax to write ASP.Net/C# code in Html content:

1) Rendering Code Syntax: <% %> and <%= %>

The following example demonstrates the usage of above syntax:



<% for (int i=0; i<8; i++) { %>
<font size="<%=i%>"> Hello World! </font> <br>
<% } %>



Code enclosed by <% ... %> is just executed, while expressions that include an equal sign, <%= ... %>, are evaluated and the result is emitted as content. Therefore <%="Hello World" %> renders the same thing as the C# code <% Response.Write("Hello World"); %>.

Note: In case of C# language it is important to place semicolon (;) correctly to end or separate statements.



2) Data Binding Syntax: <%# %>

Code located within a <%# %> code block is only executed when the DataBind method of its parent control container is invoked. The following example demonstrates how to use the data binding syntax within an <asp:datalist runat=server> control.

Within the datalist, the template for one item is specified. The content of the item template is specified using a data binding expression and the Container.DataItem refers to the data source used by the datalist MyList.


<asp:datalist id="MyList" runat=server>
<ItemTemplate>
Here is a value: <%# Container.DataItem %>
</ItemTemplate>
</asp:datalist>



In this case the data source of the MyList control is set programmatically, and then DataBind() is called.


void Page_Load(Object sender, EventArgs e) {
ArrayList items = new ArrayList();

items.Add("One");
items.Add("Two");
items.Add("Three");

MyList.DataSource = items;
MyList.DataBind();
}



Calling the DataBind method of a control causes a recursive tree walk from that control on down in the tree; the DataBinding event is raised on each server control in that hierarchy, and data binding expressions on the control are evaluated accordingly. So, if the DataBind method of the page is called, then every data binding expression within the page will be called.



3) Server-Side Comment Syntax: <%-- Comment --%>

The following sample demonstrates how to block content from executing and being sent down to a client.



<%--
<asp:calendar id="MyCal" runat=server/>
<% for (int i=0; i<45; i++) { %>
Hello World <br>
<% } %>
--%>






4) Server-Side Include Syntax: <-- #Include File="Locaton.inc" -->

Server-side #Includes enable developers to insert the raw contents of a specified file anywhere within an ASP.NET page. The following sample demonstrates how to insert a custom header and footer within a page.


<!-- #Include File="Header.inc" -->
...
<!-- #Include File="Footer.inc" -->





5) Expression Syntax: <%$ ... %> (New in ASP.Net 2.0 )

ASP.NET 2.0 adds a new declarative expression syntax for substituting values into a page before the page is parsed. This is useful for substituting connection string values or application settings defined in a Web.config file for server control property values. It can also be used to substitute values from a resource file for locaization.


<asp:SqlDataSource ID="SqlDataSource1"
ConnectionString='<%$ connectionStrings:Pubs %>'
runat="server" SelectCommand="sp_GetAuthors" />

<asp:Label ID="Label1"
Text='<%$ Resources: ExchRate, ConvertLabel %>'
runat="server"/>





To see the practical usage of above syntax you can refer following post:
Custom paging in ASP.Net GridView control


Reference:
Web Forms Syntax Reference

Google