Sandeep Khandelwal's Blog

SharePoint, ASP.net & other related stuffs

Load InfoPath XML in SQL Database

clock October 31, 2008 03:10 by author Sandeep Khandelwal

In my earlier post, I showed one of the ways to 'get' InfoPath files from SharePoint 2003 Forms Library. Once the xml files are extracted onto local directory or network share, now the task is to read the xml files and load it in database. Well, since this is a typical ETL (extraction, transformation & load) task, the obvious solution for us Microsoft techies is SSIS (or DTS for old timers). Using a XML Data source, embedded inside a 'for loop' - this could really be an easy job. Wrong! The real challenge is that InfoPath form has multiple namespaces. An XML Data source cannot work with multiple namespaces. So, you have to use an XML task to use an XSLT to strip multiple namespaces, before you execute XML Datasource. There is an excellent post by Ashwin at SQLJunkies site that you can refer on how to strip out multiple namespaces from an InfoPath data file. Here is a link to that article.

http://www.sqljunkies.ddj.com/Article/67C11DD1-080E-4F46-818B-4B9BD332DCA6.scuk 

After removing multiple namespace, now your task is rather simpler. Use a For Loop inside, and move your data flow and xml task. When all said and done your final control flow should look something like this.

But I took a totally different approach. I actually had to leverage the business Logic and data access layer which the Client uses for all their data processing. Now, I could use a .net assembly and call that from SSIS package, but this approach requires the assembly to be strongly named and GAC'ed. So, in order to save some trouble and work for the IT team here, I wrote a simple Console application in C#. This application reads the XML files and loads the data using the framework blessed by IT and Enterprise Architecture. The 'ProcessExtracts' function, loops through the folder and instantiate an XMLDocument object for each file, which further gets passed to 'SetCustomerServiceObject' function which does the real processing. In order to deal with multiple namespaces, I use 'InitNameSpaceManager' function which returns a namespace manager for the XML Objects to understand "my:" in all the InfoPath xml nodes.

public void ProcessExtracts()

{

string[] Files = Directory.GetFiles(GetAppDirectory());foreach(string file in Files)

{

 

FileInfo fileI = new FileInfo(file);

XmlDocument xDoc = new XmlDocument();

xDoc.Load(file);

SetServiceObject(xDoc);

 

}

}

private void SetServiceObject(XmlDocument xDoc)

{

XmlNamespaceManager xns = InitNamespaceManager(xDoc);

XmlNodeList xnList = xDoc.SelectNodes("//my:myFields", xns);

foreach (XmlNode xn in xnList)

{

//MetaData

Service.FormLastModifiedDt = _lastModifiedDt;

Service.AsOfDt = System.
DateTime.Now;

 

//FormData

Service.Invoice= xn["my:Invoice"].InnerText;

Service.EnteredBy = xn["my:EnteredBy"].InnerText;

IServiceRepository repository = RepositoryFactory.Create<IServiceRepository>("ConnectionString");
repository.Add(Service); 
}

}

I took the approach of using a Console application to run on a nightly basis solely because of the requirement of leveraging existing framework and business logic. If I had a choice, I would have used SSIS to execute these jobs. But the bottomline is, this makes my client happy :-). Hopefully, you had something to learn reading this blog.

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


InfoPath 2003, SharePoint Forms Library & Reporting

clock October 24, 2008 10:42 by author Sandeep Khandelwal

In my current project, I was presented with strong arguments why InfoPath is a good solution for quickly developing something and getting it out in front of users. Well, the first question I asked, how do you go about writing reports? . And the answer was, well we didn't really had that requirement hence we didn't think about it. And believe it or not, 5 weeks into this project and a user group wants to see InfoPath forms(hosted on SPS 2003 hence InfoPath 2003) data in a nice reporting services report. hmm! My worst nightmare came true . Here is the synopsis of what exactly need to happen.


1. 'Get' xml files from InfoPath forms library to a shared file location.
2. Read the xml file one by one and populate database tables.
3. Create a Reporting Services Report against accumulated data.
 
In my today's post, I will walk you through the process of 'getting' xml files from the SharePoint forms library. I keep saying xml files because, InfoPath stores its data in .xml format (InfoPath 2007 & MOSS forms server, it is a different story). Since the requirement is to run the utility outside of SharePoint server, I didn't had the luxury of working against SharePoint Object Model. But, we do have web services that can help get the xml files out of the system.

Start out by creating a new C# Console application in VS 2005. After that add a web reference to your project and point it to the SharePoint forms library. If the URL of your site is http://sps/corporate/sites/mysite then add web reference as http://sps/corporate/sites/mysite/_vti_bin/Lists.asmx. Once the reference is set you make a connection to your webservice using the following line.


MyWebReference.Lists wsList = new MyReference.Lists();


If your SPS site authenticates users against Active Directory, then you want to impersonate your wsList object. The following two lines are extremely important without which you will not be able to code against SharePoint lists.


wsList.PreAuthenticate = true;
wsList.Credentials = System.Net.CredentialCache.DefaultCredentials;
After this, you must have permissions to query against the SharePoint lists. The following code create XML object and in a for loop calls another function which use HTTPWebRequest object to get the XML file and dump it in a network shared folder.

                XmlNode allLists = wsList.GetListCollection();
                XmlDocument allListsDoc = new XmlDocument();
                allListsDoc.LoadXml(allLists.OuterXml);
                XmlNamespaceManager ns = new XmlNamespaceManager(allListsDoc.NameTable);
                ns.AddNamespace("d", allLists.NamespaceURI);
                XmlNode dlNode = allListsDoc.SelectSingleNode("/d:Lists/d:List[@Title='" + documentLibraryName + "']", ns);
                if (dlNode == null)
                {
                    Console.WriteLine("Document Library '{0}' not found!", documentLibraryName);
                }
                else
                {
                    string documentLibraryGUID = dlNode.Attributes["ID"].Value;
                    Console.WriteLine("Opening folder '{0}' GUID={1}", documentLibraryName, documentLibraryGUID);
                    XmlDocument viewFieldsDoc = new XmlDocument();
                    XmlNode listContent = wsList.GetListItems(documentLibraryGUID, null, null, null, null, null);
                    XmlDocument xmlResultsDoc = new XmlDocument();
                    xmlResultsDoc.LoadXml(listContent.OuterXml);
                    ns = new XmlNamespaceManager(xmlResultsDoc.NameTable);
                    ns.AddNamespace("z", "#RowsetSchema");
                    XmlNodeList rows = xmlResultsDoc.SelectNodes("//z:row", ns);
                    string sFileName = string.Empty;
                    if (rows.Count == 0)
                    {
                        Console.WriteLine("No content found");
                    }
                    int iCounter = 0; ;
                    if (!RecycleExtracts()) { throw new InvalidProgramException("Recycle of records failed: ");}
                    foreach (XmlNode row in rows)
                    {
                        sFileName = rows[iCounter].Attributes[1].Value; // Get file Name
                        Extract(sFileName);
                        iCounter++;
                    }
                }
And here is the Extract function:
        private static void Extract(string sFileName)
        {
            string httpLocation = FormsLibraryLocation + sFileName;
            string extractPath = GetAppDirectory() + sFileName;
           
            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(httpLocation);
                req.Credentials = System.Net.CredentialCache.DefaultCredentials;
                req.Timeout = 10000;
                req.AllowWriteStreamBuffering = false;
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                Stream st = resp.GetResponseStream();
                StreamReader sr = new StreamReader(st, Encoding.UTF8);
                string buffer = sr.ReadToEnd();
                File.WriteAllText(extractPath, buffer);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception while creating " + sFileName + "  " +ex.Message);
            }
        }
That’s it folks. This little piece of code 'gets' the xml files from the SharePoint 2003 Portal Server forms library and create a file with the exact same name on the network shared folder. In my future post, I will write about how to read these xml files and populate in database. Until then, happy coding!

 

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


A simple wrapper email component

clock October 22, 2008 04:18 by author Sandeep Khandelwal

Almost all the projects have some requirement of sending emails out of the system. In this post, I will walk through a simple email wrapper class that I wrote and have used it successfully in several projects.

Step 1:

Add the following entry in your app.config or web.config file.


<system.net>
  <
mailSettings>
    <
smtp from=mailto:from=from@yourcorp.com>
      <
network host="mail.yourcorp.com"/>
    </
smtp>
  </
mailSettings>
</
system.net>

Step 2:

Use the email.cs class provided in this post. If you are developing asp.net application, simply add this file to your app_code folder. One thing that you must ensure is that the Email class have access to SMTP settings which we created in step 1.

Step 3:

Now, only part remaining is to instantiate the email class object and call SendMail function. The following line should do the tricks for you.

Email oEmail = new Email();
oEmail.SendMail("
YourEmail@YourCorp.com","To_1@YourCorp.com,To_2@YourCorp.com,To_3@YourCorp.com"," Some Subject", "Some Body");

If you have need to send CC and Bcc then there are few overloads to SendMail function available. Besides, all the mailobjects setting are declared as public, so you can also explicitly set To, CC, BCC, Subject, Body etc and simply call oEmail.SendMail(). The object requires To, From, Subject & Body filled in and rest of the settings are totally optional. In case if you are missing the required settings, the mailObject will error out and you will see an ArgumentException exception.

Why use a wrapper class:

There are several reasons to use a wrapper class as opposed to going directly against System.Net.Mail. Here are few that I am listing for your convenience.
A) You want more control over how the message is formatted in a consistent way.
B) You want ease of creating a mail message. Out of Box asp.net mail object doesn't support comma delimited To, CC and Bcc addresses. This class helps you get over that hurdle.
C) You can set and enforce standards by using wrapper classes. This stands true with any wrapper class that you want to create.

Conclusion:

This class has worked great and have met my requirements of sending emails from .net application. The real kicker is when a company has special security mandate that disallows sending emails from the front end web servers. In which case, I would recommend moving this class behind firewall and then using .net Remoting or Web Services to send emails. Let me know your thoughts.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Running WSS on Windows Vista

clock October 20, 2008 10:58 by author Sandeep Khandelwal

A biggest challenge of being a SharePoint Developer is creating correct/appropriate environment to write code against WSS object model. A normal setup for a SharePoint Developer looks something like this.

  1. Run VPC, Install Windows Server 2003 and above, WSS 3.0, Visual Studio, SQL Server and other related tools to enable development.
  2. Install development tools on one of the sandbox and continue development there. There are 2 free remote desktop license granted by default which would allow 2 developers to work simultaneously. But this methodology has lots of loose ends and by no means this post is to endorse this methodology.
  3. Mix and match of several other techniques.

I came across a potential solution from Bamboo Nation. Ok, I admit that this is not really a full blown solution but really a 'hack'. If you folks dont know about Bamboo, they are premier tools and utilities vendors in SharePoint arena. Here is a post from Bamboo's team blog that details the steps required to run Windows SharePoint Service on Vista.

http://community.bamboosolutions.com/blogs/bambooteamblog/archive/2008/05/21/how-to-install-windows-sharepoint-services-3-0-sp1-on-vista-x64-x86.aspx

The only additional thing that I had to do is turn off UAC on Vista Machine. UAC was causing problems while trying to create Sites and Collections.

Currently rated 3.0 by 1 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Blogs mmm! I say why not?

clock October 16, 2008 10:11 by author Sandeep Khandelwal

I have seen several colleagues, friends, family write blogs all these years. I have always been compelled to write my own and I didn't really realize the power of blogs until I had a chance to work on a project with a specialty insurance company in Kansas City, who, by virtue of faith, developed an innovative product that offers insurance against errors and ommisions in blogging world. Cool eh? Well, that opened my eyes. Now that I know all the loopholes in the application process, I might as well start writing blogs. Right?Wink. But seriously guys, if you are looking for killing your time, I suggest there are better ways to do that (google for Pamela Anderson or Ted Bundy).

Purpose

So what is the purpose of writing this blog? Well, I intend to write tech articles, issues/resolution, or my personal view points on latest and greatest technology. So keep your eyes and ears to the ground and I promise that you will not be disappointed.

Currently rated 3.0 by 5 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


About the author

I work as SharePoint Consultant and Lead ECM Solution Expert for Integration Now (a pioneer in SharePoint solutions in midwest region). Besides having PMP, MCP, MCTS and other technical certifications, I am also an MBA (Finance) from UMKC. I lead & oversee SharePoint engagements in 4 states around Kansas City (MO, KS, IA, & NE).

Tag cloud

Page List

Sign in