LINQ to XML in SILVERLIGHT 3.0

Objective

This article will explain how to use LINQ to XML to read data from a XML file and bind that to SILVERLIGHT 3.0 Data Grid. XML file will be read in a WCF service and WCF service will return a List to be bind in a Grid.

Step 1

Create a SILVERLIGHT application. Select hosting in WEB Application project option.

Step 2: Add XML file in Web project.

If you have any existing XML file add that by selecting Add Existing Item option by right clicking on WEB (SilverLightApplication1.Web) project else select add new item option and select XML file from DATA tab. Copy paste the below XML file in your newly created XML file. Give any name of your choice to XML file. Name I am giving is Books.Xml.

Your XML file in Web Application project must look like.

Books.XML

<?xml
version=1.0?>
<catalog>

<book
id=bk101>

<author>Gambardella, Matthew</author>

<title>XML Developer’s Guide</title>

<genre>Computer</genre>

<price>44.95</price>

<publish_date>2000-10-01</publish_date>

<description>

An in-depth look at creating applications

with XML.

</description>

</book>

<book
id=bk102>

<author>Ralls, Kim</author>

<title>Midnight Rain</title>

<genre>Fantasy</genre>

<price>5.95</price>

<publish_date>2000-12-16</publish_date>

<description>

A former architect battles corporate zombies,

an evil sorceress, and her own childhood to become queen

of the world.

</description>

</book>

<book
id=bk103>

<author>Corets, Eva</author>

<title>Maeve Ascendant</title>

<genre>Fantasy</genre>

<price>5.95</price>

<publish_date>2000-11-17</publish_date>

<description>

After the collapse of a nanotechnology

society in England, the young survivors lay the

foundation for a new society.

</description>

</book>

<book
id=bk104>

<author>Corets, Eva</author>

<title>Oberon’s Legacy</title>

<genre>Fantasy</genre>

<price>5.95</price>

<publish_date>2001-03-10</publish_date>

<description>

In post-apocalypse England, the mysterious

agent known only as Oberon helps to create a new life

for the inhabitants of London. Sequel to Maeve

Ascendant.

</description>

</book>

<book
id=bk105>

<author>Corets, Eva</author>

<title>The Sundered Grail</title>

<genre>Fantasy</genre>

<price>5.95</price>

<publish_date>2001-09-10</publish_date>

<description>

The two daughters of Maeve, half-sisters,

battle one another for control of England. Sequel to

Oberon’s Legacy.

</description>

</book>

<book
id=bk106>

<author>Randall, Cynthia</author>

<title>Lover Birds</title>

<genre>Romance</genre>

<price>4.95</price>

<publish_date>2000-09-02</publish_date>

<description>

When Carla meets Paul at an ornithology

conference, tempers fly as feathers get ruffled.

</description>

</book>

<book
id=bk107>

<author>Thurman, Paula</author>

<title>Splish Splash</title>

<genre>Romance</genre>

<price>4.95</price>

<publish_date>2000-11-02</publish_date>

<description>

A deep sea diver finds true love twenty

thousand leagues beneath the sea.

</description>

</book>

<book
id=bk108>

<author>Knorr, Stefan</author>

<title>Creepy Crawlies</title>

<genre>Horror</genre>

<price>4.95</price>

<publish_date>2000-12-06</publish_date>

<description>

An anthology of horror stories about roaches,

centipedes, scorpions and other insects.

</description>

</book>

<book
id=bk109>

<author>Kress, Peter</author>

<title>Paradox Lost</title>

<genre>Science Fiction</genre>

<price>6.95</price>

<publish_date>2000-11-02</publish_date>

<description>

After an inadvertant trip through a Heisenberg

Uncertainty Device, James Salway discovers the problems

of being quantum.

</description>

</book>

<book
id=bk110>

<author>O’Brien, Tim</author>

<title>Microsoft .NET: The Programming Bible</title>

<genre>Computer</genre>

<price>36.95</price>

<publish_date>2000-12-09</publish_date>

<description>

Microsoft’s .NET initiative is explored in

detail in this deep programmer’s reference.

</description>

</book>

<book
id=bk111>

<author>O’Brien, Tim</author>

<title>MSXML3: A Comprehensive Guide</title>

<genre>Computer</genre>

<price>36.95</price>

<publish_date>2000-12-01</publish_date>

<description>

The Microsoft MSXML3 parser is covered in

detail, with attention to XML DOM interfaces, XSLT processing,

SAX and more.

</description>

</book>

<book
id=bk112>

<author>Galos, Mike</author>

<title>Visual Studio 7: A Comprehensive Guide</title>

<genre>Computer</genre>

<price>49.95</price>

<publish_date>2001-04-16</publish_date>

<description>

Microsoft Visual Studio 7 is explored in depth,

looking at how Visual Basic, Visual C++, C#, and ASP+ are

integrated into a comprehensive development

environment.

</description>

</book>

</catalog>

Step 2: Creating WCF service

Right click on Web Project and add WCF service from Web tab. Give any name of your choice, I am giving name here MyService.


 Creating Data Contract
This class will get serialized at client side.

Creating Service Contract

IMyService.cs

namespace SilverlightApplication1.Web{
[ServiceContract]

public interface IMyService

{

[OperationContract]

List<BooksDTO> GetBookDetails();

 }
}

Creating Service Implementation

MyService.svc.cs

using System;
using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.Text;

using System.Web;

using System.Xml.Linq;

namespace SilverlightApplication1.Web{
public class MyService : IMyService
{
public List<BooksDTO> GetBookDetails()
{

 XDocument xmlDocument = XDocument.Load(@”c:\\Books.XML”);
var books = from r in xmlDocument.Descendants(“book”)
select new BooksDTO
{
Author = r.Element(“author”).Value,

Title = r.Element(“title”).Value,Genere = r.Element(“genre”).Value,

Price = r.Element(“price”).Value,

PublishDate = r.Element(“publish_date”).Value,

Description = r.Element(“description”).Value,

};
return books.ToList();

 }

}

}

Few points

  1. Using namespace System,.XML.Linq to use LINQ to XML features.
  2. Load method of XDocument class is being used to load XML document.
  3. Searching for all the descendents in XML document for the element Book. And retrieving all the child elements value.
  4. Service is returning List of BooksDTO class.

Compile the web project and after successfully compilation right click on service and view in browser.

Step 3: Consuming in SILVERLIGHT client

  1. Add Service Reference.
  2. While adding service reference, select advanced tab and change return type from Array to List.
  3. Add Data Grid on XAML. Give any name. I am giving name here MyGrid.
  4. On page load simply bind the result returning from service to Data Grid.
  5. Make sure your startup project is SilverLightApplication1.Web and startup page is SilverLightApplicatio1Testpage.aspx . Else you might yield with Cross domain problem.

     MainPage.Xaml

<UserControl xmlns:my=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data”
x:Class=”SilverlightApplication1.MainPage”

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;


xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;


xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243;


xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;


mc:Ignorable=”d”


d:DesignHeight=”300″ d:DesignWidth=”400″>


<Grid x:Name=”LayoutRoot” Background=”White”>


<my:DataGrid x:Name=”myGrid” AutoGenerateColumns=”True” Background=”Azure” ></my:DataGrid>


</Grid>

</UserControl>


 

 

MainPage.Xaml.CS

using System;
using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using SilverlightApplication1.ServiceReference1;

namespace SilverlightApplication1

{


public artial class MainPage : UserControl

{

public MainPage()

{

InitializeComponent();


MyServiceClient proxy = new MyServiceClient();

proxy.GetBookDetailsCompleted += new EventHandler<GetBookDetailsCompletedEventArgs>(proxy_GetBookDetailsCompleted);

proxy.GetBookDetailsAsync();}

 void proxy_GetBookDetailsCompleted(object sender, GetBookDetailsCompletedEventArgs e)
{
myGrid.ItemsSource = e.Result;
}}}

Output


 Conclusion
I have explained how to return data from XML file using LINQ to XML and bind to SILVERLIGHT data grid. In next article I will show other CRUD operations. Thanks for reading.

Seven quick points in Understanding SharePoint 2007 list definition

 Objective
This article will give basic 7 theatrical points on SharePoint List definition.

  1. When we create a new site in SharePoint, it gets created as instance of SharePoint Site Definition. Each instance of Site Definition is having List Definitions. So when we create a list in SharePoint site, it gets created as instance of List Definition of the site. 
  2. Each list gets its definition from the two files. These files are applied globally to the site.

    Two files are as below,

  3. Each List folder is having 5 files. They are as follows

    These files can be found at 

    Local_Drive:\Program Files\Common Files\Microsoft Shared\web server extensions\60\TEMPLATE\Locale_ID\Site_Definition\LISTS
    directory

  4. All the three XML files for a list use CAML language to define how list instance should be created.
  5. Never modify content of FLDTYPES.XML.
    Because wrong updating or modification in this file can break the entire site definition for particular front end server.
  6. All ASPX page of a list item contains same Page Directive, Meta Data, Script, and Server controls.
  7. Each ASPX page contains a table with three rows.

TOP Navigation

Title

Left Navigation

Content

 

In next articles; I will show how to customize above four parts of a SharePoint List form. Thanks for reading.

LINQ to XML Part # 5: Catching Parsing Exceptions

Objective

This is a very high level article which will explain; how to handle exception in parsing XML using LINQ to XML.

Problem

Let us say, we are parsing a below string using XElement.Parse

String strParse = “<Address><Name>Dhananjay Kumar </Name> “;

This string is not valid formed. But XElement.Parse won’t be able to catch the exception. So if we will run the below code

String strParse = “<Address><Name>Dhananjay Kumar </Name> “;

XElement xmlTree = XElement.Parse(strParse);

Console.WriteLine(xmlTree);
 

We will get the below run time error.

Five Facts

  1. LINQ to XML is implemented through XMLReader.
  2. Parse methods on various LINQ to XML class are unable to handle the Exception.
  3. At time of parsing if input is invalid XML or not formed exception occurs.
  4. At Exception the underlying XMLReader will throw the Exception.
  5. High level Exception would be System.Xml.XmlException

How to handle the Exception?

Programmer has to explicitly handle the Exception while parsing. Parsing code need to be put in try catch and Exception must be handled explicitly.


try

{


String strParse = “<Address><Name>Dhananjay Kumar </Name> “;


XElement xmlTree = XElement.Parse(strParse);


Console.WriteLine(xmlTree);

}


catch (System.Xml.XmlException e)

{


Console.WriteLine(e.Message);

}

Output


 Conclusion
In this article, I showed how to handle exception in parsing XML using LINQ to XML. Thanks for reading.

LINQ to XML Part #4: Different way of Parsing string to create XML tree

Objective

In this article, I will show different way of parsing string to create XML tree using LINQ to XML.

What is Parsing of XML document?

Parsing of XML document means reading XML document, identifies the function of each of the document and then makes this information available in memory for rest of the program.

XElement.Parse () method

  1. This method is used to parse a string.
  2. This is an overloaded method.

    Methods are as below.


2nd overloaded method is having a parameter LoadOptions; this parameter defines whether to preserve space line information or not.

 LoadOptions enum

  1. This is inside System.Linq namespace.
  2. This enum is having 4 properties.
using System;

namespace System.Xml.Linq

{ 

[Flags]

public enum LoadOptions{

None = 0,

PreserveWhitespace = 1,

SetBaseUri = 2,

SetLineInfo = 4,

}

}

 Way # 1 Parsing String to create XML Tree
In this sample, I will create a XML tree from string.

  1. Using first method to create XML Tree.
  2. There is only one parameter being passed.
XElement xmltree = XElement.Parse(@”<Address><Name>Dhananjay Kumar </Name> <Road> Padma Road </Road> </Address>”);

Console.WriteLine(xmltree);

Output

In this sample, I will create a XML tree from string.

  1. Using second method to create XML Tree.
  2. There is two parameter being passed.
  3. We are passing preserve space as load options.
XElement xmltree = XElement.Parse(@”<Address><Name>Dhananjay Kumar </Name> <Road> Padma Road </Road> </Address>”,LoadOptions.PreserveWhitespace);

Console.WriteLine(xmltree);

Output

We can see the difference in output. That white space is preserved.

Conclusion

In this article, I explained how to parse a string to create XML tree. Thanks for reading.

LINQ to XML Part # 3: Functional Construction of XML Tree

Objective

This article will give an explanation on; how to create a XML tree using Functional Construction method of LINQ to XML.

What is Functional Construction?

Functional Construction is ability to create a XML tree in a single statement. LINQ to XML is being used to create XML tree in a single statement.

The features of LINQ to XML enables functional construction are as follows

  1. The XElement class constructor takes various types of arguments
    1. For child element takes another XElement as argument.
    2. For attribute of element takes XAttribute as argument.
    3. For text content of element takes simple string as argument.
  2. For complex type of content pass parameter as Array of Objects.
  3. If an object implements IEnumerable(T) , then the collection is enumerated. If the collection contains XElement or XAttributes objects then result of LINQ query can be passing as parameter to XElement constructor.

Sample #1

Here we are creating a XML tree by passing XElement as child element and XAttribute as attribute to one of the element.

XElement xmltree = new XElement(“Root”,

new XElement(“Element1”, new XAttribute(“name”, “Dj”), 1),
new XElement(“Element2”, new XAttribute(“ID”,“U18949”),
new XAttribute(“DEPT”,“MIT”),2),
new XElement(“Element3”, “3”),
new XElement(“Element4”, “4”)
);
Console.WriteLine(xmltree);

Please do not forget to add System.XML.LINQ namespace. Output in a console print may look like


 Sample # 2

Now we will try to use feature #3 (Discussed above) that if object implements IEnumerable(T) we can pass result of a LINQ query as parameter .

So let us say, that in above XML Tree (Created as sample1), we are retrieving child elements with content 3 and 4 and passing the result as parameter of constructor of XML element to create XML tree.

XElement xmltree = new XElement(“Root”,

new XElement(“Element1”, new XAttribute(“name”, “Dj”), 1),
new XElement(“Element2”, new XAttribute(“ID”, “U18949”),
new XAttribute(“DEPT”,“MIT”),2),
new XElement(“Element3”, “3”),
new XElement(“Element4”, “4”)

);

Console.WriteLine(xmltree);
XElement newXmlTree = new XElement (“ROOT”,
new XElement(“Element1”,1),
new XElement(“Element2”,2),
from e in xmltree.Elements() where (int) e >2
select e
);
Console.WriteLine(“New XML Tree using LINQ query “);
Console.WriteLine(newXmlTree);

 If you see the above code, the second XML tree, we are passing LINQ query result as parameter of XElement. We will get expected output as below.

Conclusion

In this article, I explained about FUNCTIONAL CONSTRUCTION way of creating XML TREE. Thanks for reading.

LINQ to XML Part #2(XElement Class)

Objective

In this article, I will give explanation on XElement class. This class is used to construct XML Elements.What is Elements in XML?

XML Element is fundamental XML constructs. An Element has a name and optional attributes. An XML Elements can have nested Elements called Nodes also.


 XElement class
XElement Class is defined as below in namespace System.Xml.Linq. And it inherits the class XContainer that derives from XNode .

namespace System.Xml.Linq{
[XmlSchemaProvider(“”, IsAny = true)]

public class XElement : XContainer, IXmlSerializable
{
public XElement(XElement other);
public XElement(XName name);
public XElement(XStreamingElement other);
public XElement(XName name, object content);
public XElement(XName name, paramsobject[] content);

 5 Facts

  1. It is one of the base and fundamental class in LINQ to XML.
  2. It represents XML element.
  3. This class can be used to change the content of the element.
    1. It can add child element.
    2. It can delete child element.
    3. It can change child element.
    4. It can add attributes to an element.
  4. This class can be use to serialize the content in a text form.
  5. This class can be used to create XML tree.

Constructor of XAttribute

If you see above definition of XAttribute class; there are five constructors. Usually we use the below constructor

public XElement(XName name, object content);

name: It is unique name of Attribute in XML tree.

content: It is content of the attribute. It is of type object.

Example

In below example; I am constructing a XElment called xmltree. This root element is having many nested XElement,

  1. XElement
    Data1 is having one XAttribute. Name of the Attribute is “name” and value of attribute is “dj“.
  2. XElement
    Data2 is having two XAttribute. They are ID and DEPT with values U18949 and MIT respectively.
XElement xmltree = new XElement(“Root”, new XElement(“Data1”, newXAttribute(“name”, “Dj”), 1),                 new XElement(“Data2”, new XAttribute(“ID”, “U18949”),
                 new XAttribute(“DEPT”,“MIT”),2),
                 new XElement(“Data3”, “3”),
                 new XElement(“Data4”, “4”)
);
Console.WriteLine(xmltree);

 Output

Conclusion

In this article; I explained about XElement class. In next article, I will explain about CRUD operation on XML using LINQ to XML Thanks for reading.

LINQ to XML Part #1(XAttribute Class)

Objective

In this article, I will give explanation on XAttribute class. This class is used to construct Attributes in XML Elements.

What is Attribute in XML?

XML Attribute is a Name/Value pair associated with XML elements. XAttribute class represents XML Attributes.

XAttribute class

XAttribute Class is defined as below in namespace System.Xml.Linq. And it inherits the class XObject

using System;using System.Collections.Generic;using System.Xml; 

namespace System.Xml.Linq

{

public class XAttribute : XObject
{
public XAttribute(XAttribute other);
public XAttribute(XName name, object value);
…….
}
}

5 Facts

  1. XElement contains a list of attribute for that element.
  2. Attributes must have unique name for that particular element.
  3. Attributes are not node they are Key/value pair associated with an element.
  4. Attributes are maintained in XML tree in order they are added to the element.
  5. When attributes are returned from element they are not sorted.

Constructor of XAttribute

If you see above definition of XAttribute class; there are two constructors. Usually we use the second constructor

public XAttribute(XName name, object value);

name: It is unique name of Attribute in XML Element. It is of type XName.

value: It is value of the attribute. It is of type object.

Example

In below example; I am constructing a XElment called xmltree. This root element is having many nested XElement,

  1. XElement
    Data1 is having one XAttribute. Name of the Attribute is “name” and value of attribute is “dj“.
  2. XElement
    Data2 is having two XAttribute. They are ID and DEPT with values U18949 and MIT respectively.
XElement xmltree = new XElement(“Root”,new XElement(“Data1”, newXAttribute(“name”, “Dj”), 1),
new XElement(“Data2”, new XAttribute(“ID”, “U18949”),
new XAttribute(“DEPT”,“MIT”),2),
new XElement(“Data3”, “3”),
new XElement(“Data4”, “4”)
);
Console.WriteLine(xmltree);

Output

Conclusion

In this article; I explained about XAttribute class. In next article, I will explain about XElement class. Thanks for reading.

Forms on SharePoint lists

Objective

This article will give a very high level description on various forms on a SharePoint list.  

When we create a new custom list in SharePoint, SharePoint creates three forms (*.aspx) for the custom list. In fact for all list these forms are provided by SharePoint.

 

 

Let us say, there is a list called TestList in your SharePoint site. Columns of list are as follows;

 

Adding New Item

Now when you add new item in the list, NewForm.aspx will get open. You can see the below URL in your browser while adding new item in the list.

http://ABCSERVER:9722/sites/Test4/Lists/TestList/NewForm.aspx?RootFolder=%2Fsites%2FTest1%2FTest4%2FLists%2FTestList&Source=http%3A%2F%2Fc849uss%3A9722%2Fsites%2FTest1%2FTest4%2FLists%2FTestList%2FAllItems%2Easpx

There are two query parameters,

  1. RootFolder: This parameter defines, in which folder Item will get saved.
  2. Source: This parameter defines after completion of action where to navigate.

Note: More on these two parameters in next articles.

 

Editing Existing Item

Now when you edit existing item in the list, EditForm.aspx will get open. You can see the below URL in your browser while editing existing item in the list.

http://ABCSERVER:9722/sites/Test1/Lists/TestList/EditForm.aspx?ID=3&Source=http%3A%2F%2Fc849uss%3A9722%2Fsites%2FTest1%2FTest4%2FLists%2FTestList%2FAllItems%2Easpx

There are two query parameters,

  1. ID: This parameter takes id of the item in list to be edited. If you pass ID which does not exist in the list, SharePoint will throw you below error.
No item exists at http://c849uss:9722/sites/Test1/Test4/Lists/TestList/EditForm.aspx?ID=300&Source=http://c849uss:9722/sites/Test1/Test4/Lists/TestList/AllItems.aspx.  It may have been deleted or renamed by another user.Web Parts Maintenance Page: If you have permission, you can use this page to temporarily close Web Parts or remove personal settings. For more information, contact your site administrator.

Troubleshoot issues with Windows SharePoint Services.

  1. Source: This parameter defines after completion of action where to navigate.

     

Displaying Existing Item

Now when you display existing item in the list, DispForm.aspx will get open. You can see the below URL in your browser while editing existing item in the list.

http://ABCSERVER:9722/sites/Test1/Lists/TestList/DispForm.aspx?ID=3&Source=http%3A%2F%2Fc849uss%3A9722%2Fsites%2FTest1%2FTest4%2FLists%2FTestList%2FAllItems%2Easpx&RootFolder=%2Fsites%2FTest1%2FTest4%2FLists%2FTestList

There are two query parameters,

  1. ID: This parameter takes id of the item in list to be displayed.
  2. Source: This parameter defines after completion of action where to navigate.

Working with Dynamic Object in c# 4.0 Part #1

Objective

This article will give a basic introduction of Dynamic Object in c# 4.0

DynamicObject class

  1. This provides a base class for specifying dynamic behavior at run time.
  2. This class must be inherited to use.
  3. This class cannot be instantiated.
  4. This class is inside namespace System.Dynamic
  5. This class implements IDynamicMetaObjectProvider
  6. This class enables to define which operation can be performed at the run time.
  7. This class enables to decide how to perform operations on dynamic objects.
  8. Own member can be added to class inherited from DynamicObject.

     

     Override TryInvokeMember Method

  1. It provides the implementation for operations that invoke members.
  2. Class derived from DynamicObject class can override this method to specify dynamic behavior for operation such as calling a method.

This method is defined as below,

public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args,out
object result)
{

}

There are three arguments for this method

Binder

  1. This argument provides information about dynamic operation.
  2. binder.Name provides the name of the member on which dynamic operation is performed.
  3. Type of this argument is InvokeMemberBinder.

Let us say, myDynamicObject is name of the instance and myDynamicMethod is name of the dynamic method in class inherited from DynamicObject. If you are calling

myDynamicObject. myDynamicMethod then in that case binder.Name = myDynamicMethod

 Args

This parameter defines the arguments pass as the input to the method of dynamic class. Let us say myDynamicMethod takes two input parameters int x and string y. so Args parameter will define these two input parameters of the method in dynamic class.

Type: array of System.Object []

Result

This is result of the system invocation.

If result = true then operation is successful.

If result=false then, then runtime binder of language determine the behavior. In most cases it will throw run time exception.

Note: If you override the TryInvokeMember method, the dynamic dispatch system first attempts to determine whatever specified method exists in the class. If it does not find the method , it uses the TryInvokeMember implementation.

Sample

  1. Open Visual Studio 2010 and create a new console application.
  2. Add a class. Give name. I am giving name here as MyDynamicClass
  3. Inherit the class from DynamicObject
  4. Overriding TryInvokeMember method.

MyDynamicClass.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Dynamic ; 

namespace DynamicObjectsample

{

class MyDynamicClass : DynamicObject{

public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (string.Equals(binder.Name, “MyMethod”))

{

Console.WriteLine(“U have hacked”);
result = true;
return true;
}
else
{
Console.WriteLine(binder.Name + ” Method not present in this class “);
result = true;
return true;
}}}}

If you see the above class, we are overriding TryInvokeMember. We are checking if method name called is MyMethod or not?

Using the MyDynamicClass

namespace DynamicObjectsample{

class Program

{

static void Main(string[] args)

{

dynamic obj = new MyDynamicClass();

obj.MyMethod();

Console.ReadKey();
obj.Abc();
Console.ReadKey();
}}}

 Output


Creating message body by parsing document from Document Library and sending mail in SharePoint 2007

Objective

This article will give an idea of,

  1. How to parse a document from Document Library and replace with dynamic values at run time.
  2. How to send mail in SharePoint using SPUtility class.
  3. Introduction of a real time problem to use above said features of SharePoint.

Background
There was a requirement in one of my project. I will divide requirement as follows

  1. There are documents in Document Library.
  2. Content of documents will be sending as body of Email.
  3. Document will be containing static data as well as dynamic data.
  4. Value for dynamic data will be replaced at the run time.

So, requirement could be summarized as; we need to fetch a document from document library and parse that. While parsing, we will replace dynamic variables with real value and then we will be sending the mail. Content of the document will be parsed as string and will be sent as body of the mail.

Let us say, we are having a document named Notification.txt in SharePoint Document library. Content of document is as follows

Notification.txt

Hi [Name], 

This is Notification Mail From SharePoint server. You are supposing to Report to [ManagerName] on [Date] for the [ProjectName].  

[UriToNavigate] to Navigate.  

Thanks with Regards.  

***Do not reply to this mail***

 Note: Dynamic variables are enclosed in square braces.

  1. We need to read this document from SharePoint Document library using object model.
  2. Replace dynamic variables enclosed with square braces with values at run time.
  3. Parse content of document and return a string. This string will be used as body of the mail.

Finally after creating body from document of document library, we will send mail using SPUtility.

Creating Body from Document of SharePoint Document Library

Step 1: Create Hash Table

Hash table will contain values for all the dynamic variables.

public
Hashtable CreateHashTableForMessageBody(string name, string managerName,string date, string projectName, string linkToNavigate)

{

Hashtable hashTableForMessageBody = new
Hashtable();

link = String.Format(“<a href = {0} >click here.</a>”, linkToNavigate);

hashTableForMessageBody.Add(“Name”, name);

hashTableForMessageBody.Add(“ManagerName”, managerName);

hashTableForMessageBody.Add(“Date”, date);

hashTableForMessageBody.Add(“ProjectName”, projectName);

hashTableForMessageBody.Add(“UriToNavigate”,link);

return hashTableForMessageBody;

}

  1. We are passing all the required values for dynamic variables as input parameter to function.
  2. We are creating a Hash table.
  3. Function is returning a hash table.
  4. Make sure name of the key is exactly the same as of name of the dynamic variables. Dynamic variables are enclosed in square braces. Cases of the Dynamic variables and key of hash table must be same. For example key “Name” in Hash table will be parsed and replaced for [Name] dynamic variable in document.

Step 2: Parsing content of document to return a string as message body.

Public static
string GetEmailBody(String spSite, Hashtable emailAttribute, string templateName)
{

string templateStr = “”;
string bottomMessage = “”;

try
{
using (SPSite site = new SPSite(spSite)){
using (SPWeb uspWeb = site.OpenWeb())
{
this.emailAttributes = emailAttributes;
SPList emailTemplates = uspWeb.Lists[“NotificationTemplate”];
SPQuery qry = new SPQuery();
qry.Query = string.Format(“<Where><Eq><FieldRef Name=’FileLeafRef’ /><Value Type=’File’>{0}</Value></Eq></Where>”, templateName);
SPListItemCollection templateCollection = emailTemplates.GetItems(qry);
if (templateCollection.Count > 0){
SPListItem template = templateCollection[0];
byte[] templateByte = template.File.OpenBinary();
System.Text.Encoding enc = System.Text.Encoding.ASCII;
templateStr = enc.GetString(templateByte);
foreach (object obj in emailAttribute.Keys)
{
if (emailAttribute[obj] != null)
{
templateStr = templateStr.Replace(“[“ + obj.ToString() + “]”, emailAttribute[obj].ToString());
}}
bottomMessage = “*** This is system-generated email. Do not reply. *** “;
templateStr = templateStr +“\n” + bottomMessage;
}
return templateStr;}

  1. Function takes three input parameters. First parameter is URL as string to create instance of SPSIte. Second parameter is Hash table. Third parameter is name of the template to be parsed.
  2. NotificationTemplate is name of the Document Library in SharePoint site.
  3. We are iterating through the Document library using CAML query and searching for the template name (.txt file uploaded)
  4. We are iterating through all the keys in hash table and replacing the keys with values while getting matched with dynamic variable in document of document library.
  5. We are returning string message as body of the mail.

Sending mail using SPUtility

So far, we have created the body of the mail; we are going to send. In this section we will see how we can send Email using SPUtility class on Windows.SharePoint.Services.dll

  1. Creating hashtable to create message body.
  2. Passing hashtable in function creating messagebody.
  3. Creating a dictionary to set To, From, Subject and Body of the mail.
  4. SendMail static function of SPUtility class is used to send mail.

Function to send Email using SPUtility

 

String name = “Dhananjay Kumar”

Striing subject = String.Empty;


String managername =“Anoj P”


String linktonavigate = “Default.apsx”;


String date = String.Empty;


String projectname = “My Project”;

String messageBody = String.Empty;


Hashtable hashTableForMessageBody = null;

hashTableForMessageBody = CreateHashTableForMessageBody(name, managername, date, projectname,linktonavigate);

messageBody = GetEmailBody(spsite, hashTableForMessageBody,
Notification.txt);

#region sending Mail

subject = “This is Test Mail”
try

{StringDictionary headers = new StringDictionary();

headers.Add(“subject”, subject);
headers.Add(“from”, GetFromAddress(spsite));

headers.Add(“to”,”abc@abc.com”);


SPUtility.SendEmail(web, headers, messageBody);

}


catch (Exception ex)

{

web.Dispose();

site.Dispose();


ErrorLogger.LogError(“Creating message Body – sending mail”, ex);

}

#endregion