Sending an InfoPath 2003 form to people who don’t have the client
February 7, 2007
I needed to send the completed (ie approved) form, read-only, to the company who took care of the orders made in an InfoPath 2003 form. The form is stored in a SharePoint forms library, but the receiving company didn’t have access to this SharePoint site. 2007 would be sweet, but I can’t use that. Hmmm… how to do?
I created a web service, which the form, once approved, sent an email through (all stages in the workflow before approval used the ordinary data connection to the SharePoint forms library).
The web service receives the xml document from InfoPath, via the normal web service data connection available. The web service extracts the filename (stored as a secondary data source inside the form) and makes an html document out of the xml and xsl combined, which then can be viewed on any computer with an internet browser.
There’s one big-ass downside with this though. The xsl file has to be extracted from the infopath form and then edited a little to remove not-supported functions and so on, or else you’ll se some nasty error messages when opening the form in the browser. So if the form has undergone some major changes, you need to re-extract the xsl-file and put it somewhere where the web service can access it, which in my case is in the web service root directory.
Here’s the code:
Service.cs
[WebMethod]
public string InfoPathMailer(XmlDocument xmlDoc)
{
string filename = GetFileName(xmlDoc);Stream stream = new MemoryStream();
XslCompiledTransform xslTransform = new XslCompiledTransform();
xslTransform.Load(Server.MapPath("view1.xsl"));
xslTransform.Transform(xmlDoc, null, stream);
stream.Position = 0;MailSender m = new MailSender("yourmailserver.net", "formsrobot@yourdomain.com", "receiver@company.com", "New End User Request", "Do not reply to this address", filename, stream);
m.Send(); return "";
}private string GetFileName(XmlDocument xmlDoc)
{
string infoPathNamespacePrefix = "my";
string infoPathNamespaceURI = @"http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-11-13T10:36:39";
XmlNamespaceManager namespaceMngr = new XmlNamespaceManager(xmlDoc.NameTable);
namespaceMngr.AddNamespace(infoPathNamespacePrefix, infoPathNamespaceURI); XmlNode node = xmlDoc.SelectSingleNode("//my:Filename", namespaceMngr);
string s = node.InnerText;
s = s.Replace("xml", "html");
return s;
}
And here’s the code for the class MailSender:
using System;
using System.Data;
using System.Configuration;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.IO;public class MailSender
{
MailMessage mail;
String smtpServer; //Constructor for attachment as stream
public MailSender(string server, string sender, string receiver, string subject, string body, string filename, Stream stream)
{
smtpServer = server;
mail = new MailMessage(sender, receiver, subject, body);
Attachment attachment = new Attachment(stream, filename, MediaTypeNames.Text.Html);
mail.Attachments.Add(attachment);
}public void Send()
{
SmtpClient client = new SmtpClient(smtpServer);
client.Credentials = CredentialCache.DefaultNetworkCredentials;
client.Send(mail);
}
}
Hopefully this can help someone out there. Good luck!
“Ambiguous match found” in my default.aspx.cs
January 9, 2007
I stumbled upon the aforementioned error after making some changes in my default.aspx code.
The error message didn’t help a lot, but because of Eran Sandler’s blog Advanced .NET Debugging I managed to sort it out.
Because some variables had the same names in the default.aspx and the default.aspx.cs, but the casing was different, the stuff added in the default.aspx.designer.cs file created errors. Either you can remove the lines added in the designer file or do as I did: rename the error generating variable names (thru refactoring of course ;) ) so that more than the casing differs.
And to Eran for finding this error (and/or possible bug): respect.
Regular expressions condensed
November 10, 2006
If you know the basics of regular expressions in C# and .NET (if a newbie, look here), this “cheat sheet” is a good place to go to whenever you forget the metacharacters etc:
Conditional logic inside repeaters
November 9, 2006
Today I was trying to make some asp:Labels visible or not based on what kind of data the repeater was showing, ie having som kind of if-else-clause to decide what to show.
That wasn’t as easy as I thought, and I saw that many people had had the same problem when googling this question at Google Groups.
The solution for me was to add an OnItemDataBound property to the repeater, like this:
OnItemDataBound="Repeater1_ItemDataBound"
And then, in the codebehind file I added an event handler.
protected void Repeater1_ItemDataBound(Object sender, RepeaterItemEventArgs e)
Inside that event handler I simply added the conditional logic for showing or not showing the stuff I wanted to.
bool visibility;
if(Condition)
{
visibility = true;
}
else
{
visibility = false;
}
((Label)e.Item.FindControl("lblLabelName")).Visible = visibility;
That did the trick for me, hope it helps you.
Using DataSets with TableAdapters I was trying to retrieve the different years listed in a database table since I wanted the unique years to show up on a drop-down list. My SQL-query looked like this:
SELECT DISTINCT DATEPART(yyyy, EntryDate) AS Year
FROM nPressClips
ORDER BY Year DESC
What happened was that the dataset couldn’t fill due to this error:
“Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.”
For some reason unknown to me, the query above also returned a null value PressClipID-column that I didn’t want. A quick solution was to simply return a constant column value to avoid it being null. This is my solution, quick and very dirty:
SELECT DISTINCT DATEPART(yyyy, EntryDate) AS Year, 1 AS PressClipID
FROM nPressClips
ORDER BY Year DESC
If anyone can come up with a better solution than this, do not hesitate to contact me. Until then, this works just fine.
Creating web parts with Visual Studio 2005
October 23, 2006
If you want to learn how to write web parts in Visual Studio 2005, ONDotNet has a great little tutorial which teaches you (or at least me) the very basics. How easy it was!
Try it out for yourself at: ONDotNet.com
Limitations in InfoPath 2007
October 20, 2006
I’ve just started looking at InfoPath 2007 on the behalf of a customer, since they need some forms software. I liked the idea of the new InfoPath since it, unlike the 2003 version, doesn’t require any software being installed on the client computer.
However, I’ve discovered two important limitations that need workarounds. I don’t know why they aren’t enabled by default in InfoPath, it sounds like an easy enough thing to do for Microsoft:
1) In order to publish the form to a web page, you need to either have the web page in SharePoint or modify your aspx-page a little. Not a lot of work, but it still sounds like something that you could make less complex.
2) If you want the forms data to be saved to a database, the InfoPath client has to be installed on your (assuming you’re the form filler) computer. Or you’d (the developer you) have to construct a web service, which InfoPath can use to indirectly communicate with the database. Direct communication from a web form is not supported.
At least that’s what I’ve understood so far by reviewing the documentation for InfoPath 2007. I haven’t really put my hands on it yet, but hopefully it will be soon.
One really nice thing is the intergration with SharePoint 2007 and Visual Studio, which probably should make heavily customized solutions easy to design and implement.