Saturday, January 02, 2010

Halloween 2009

Here are some pictures that I have been meaning to upload from Austin's Lego Halloween costume. I put it together using the box from a case of Diet Pepsi, some pegs I cut out of a ceiling tile (because it was relatively soft and cheap), and some spray paint. I used a jigsaw to cut the ceiling tile and reinforced the box using some glue and extra cardboard before I sanded and painted it. Austin wasn't as crazy about it as I was until the candy started flowing :)

Saturday, July 18, 2009

List Excel Table Names (Sheet Names) with Iron Python

I thought I would share another Iron Python snippet I hacked together a few weeks ago. The PrintTables method accepts a OleDbConnection to the spreadsheet and returns a list of Excel Table (Sheet) names. You are going to have to add something resembling the following:
from System.Data.OleDb import OleDbConnection, OleDbDataAdapter, OleDbCommand, OleDbSchemaGuid
somewhere.

def PrintTables(connection):
names = []
schemaTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,Array[object]([None, None, None, "TABLE"]))

if (schemaTable and schemaTable.Columns.Count > 0):
nameIndex = schemaTable.Columns.IndexOf("TABLE_NAME")

for dr in schemaTable.Rows:
names.append(dr.ItemArray[nameIndex])
return names

Thursday, April 09, 2009

Validating Infopath 2003 DataConnections with IronPython

I have been using IronPython lately to write utility applications- Taking a break from C# to hack away in IronPython is great. Below is a snippet from a utility that I threw together to validate infopath 2003 dataconnections. Using mostly the clr System.Net and System.Xml libraries, I retreived the dataconnection webservice calls from my manifest.xsf file using the following xpath- "/xsf:xDocumentClass/xsf:dataObjects/xsf:dataObject/xsf:query/xsf:webServiceAdapter". I then passed the schema and serviceUrl xml attributes to the PrintStatus method, and ended up with output resembling:

OrderService -> amazon.com... OK

This utility is also handy to quickly verify that all your dataconnection hostnames are pointing to the correct environment- development, production or whatever.
Update: code modified to fixed a incorrect exception handling statement and also to change the "getstatus" method- it now returns a string instead of printing in order to simplify unit testing.
def QueryDataObjectUrl(url):
request = HttpWebRequest.Create(url)
request.Credentials = CredentialCache.DefaultCredentials
try:
response = request.GetResponse()
if(response):
statusCode = response.StatusCode
statusDescription = response.StatusDescription
response.Close()
except WebException, ex:
statusCode = ex.Response.StatusCode
statusDescription = ex.Message

return statusCode, statusDescription

def GetStatusString(name, urlString):
try:
url = Uri(urlString)
statusCode, statusDescription = QueryDataObjectUrl(url)
if(statusCode == HttpStatusCode.OK):
return "%s -> %s ...%s" % \
(name, url.Host, statusDescription)
else:
return "%s -> %s ...%s" % \
(name, urlString, statusDescription)
except UriFormatException, ex:
return "%s -> %s ...%s" % \
(name, urlString, ex.Message)

Monday, January 12, 2009

New Google Gadget Submission

I submitted a new gadget to google this evening that can be used to encode and decode URL querystrings. I took the javascript off of the Albion Research Ltd. website, which hosts one of the most useful pages on the Internet. I made a few minor updates including removing the form tags, substituting Google's _gel api shortcut in a few spots, and adding in a missing end "</TR>" tag. You can use the button below to add the gadget directly to your iGoogle homepage.

Add to Google

What was my motivation for doing this? To quickly encode and decode sharepoint list guid querystrings of course (without wasting anymore A.R. bandwidth)!

Wednesday, November 12, 2008

Error 0x80004005 while deleting a list field

A quick Sharepoint tip: While calling the UpdateList method of the Lists.asmx web service, you may receive a "Operation Failed" message while attempting to delete a field (with an error code of 0x80004005). One potential cause of this generic error message is that you are trying to delete a read-only field.

The work around for this problem is to simply update the field's ReadOnly property with a value of False using the same method before again calling UpdateList to delete the field.

Update: Another note- you can use the configuration page (http://site/_layouts/FldEdit.aspx?List=<listguid>&Field=<fieldname>) to quickly diagnose any delete field problems you are having as it seems to do a much better job of relaying descriptive error messages than the UpdateList web service does. Even though hidden and read-only fields may not be available through the sharepoint GUI, you can still access them by simply formatting the FldEdit.aspx page querystring as above.

Thursday, September 11, 2008

Programatically Connecting Sharepoint Smart Parts

I recently ran into a (admittedly esoteric) scenario where it made sense to programmatically connect Smart Parts that implemented the SmartPart.IConnectionConsumerControl interface. So, in order to wire up my Smart Parts (in a manner similar to what is described here) , I needed to do a quick search through the Smart Part source on Codeplex in order to identify the following SmartPart.IConnectionConsumerControl connection point IDs of "CellConsumer_WPQ_" and "CellProvider_WPQ_".

Then all that remained was to add code similar to the following to the FeatureActivated Event of my SPFeatureReceiver:

SPLimitedWebPartManager wpm = spFile.GetLimitedWebPartManager(PersonalizationScope.Shared);
WebPart WP1 = wpm.WebParts["WP1"] as WebPart;
WebPart WP2 = wpm.WebParts["WP2"] as WebPart;

if (WP1 != null && WP2 != null)
{
if ((WP1.ConnectionID.CompareTo(Guid.Empty) == 0)
WP1.ConnectionID = Guid.NewGuid();

if ((WP2.ConnectionID.CompareTo(Guid.Empty) == 0)
WP2.ConnectionID = Guid.NewGuid();

WP1.Connections = GetWSSConnectionsString(
WP2.ConnectionID,
WP1.ConnectionID);

wpm.SaveChanges(WP2);
wpm.SaveChanges(WP1);
}

private string GetWSSConnectionsString(Guid ProviderID, Guid ConsumerID)
{
string ConsumerInterfaceName = "CellConsumer_WPQ_";
string ProviderInterfaceName = "CellProvider_WPQ_";

return string.Format("{0},{1},{2},{3},{2},{3}",
ConsumerID,
ProviderID,
ConsumerInterfaceName,
ProviderInterfaceName);
}

Wednesday, January 23, 2008

Handy Visual Studio Customization

Someone reminded me today about this neat Visual Studio customization. It really comes in handy for deploying items developed for Sharepoint. Anyways- the tip was related to getting the public key blob for any assembly. It basically involves adding sn.exe as the command for an external tool that points to your target assembly by using the following argument: -Tp $(TargetPath). This is 100% better that the way I used to do it using the Microsoft.NET Framework Configuration tool. Check it out!

Friday, December 14, 2007

Installfest and my favorite .Net 3.5/Visual Studio 2008 feature(s)

While I am a little disappointed our local user group (MADNUG) wasn't selected as one of the hosts of the Visual Studio 2008 InstallFests, Microsoft has proved, yet again, that its developer community involvement is head and shoulders above anyone else's. The Indianapolis event sounded very cool, providing free VS Pro copies and hosting mini demos of favorite features.

So, because I was unable to attend the event, I am going to blog about my 2 favorite VS2008 features in a shameless attempt to win a free MS ZUNE(thanks Dave) . My favorite features aren't the most sexy ones out there, but they are practical.

My favorite features are the JavaScript intellisense and the .Net framework multitargeting. The J.I. is a favorite simply because everyone that does web development has to occasionally do some JS work. Multitargeting also sounds very cool because I want to immediately start using the new IDE instead of switching between 2005 and 2008 during our gradual app. migration process.

Open Remedy User Client via Hyperlink

Here is a snippet of code I wrote to to allow embedding of Remedy client shortcuts on a web page. To use this application to open a specific ticket, you simply format the link in your datagrid, report, etc as follows: http://[application path].aspx?eid=[request id]&form=[remedy form]&server=[remedy server] . This method is preferable to simply linking to the Remedy web UI because the Remedy client doesn't require you to log in as it caches your authentication information. I whipped this up after downloading and checking out the composition of the Remedy shortcuts that we receive as email attachments.


string strTicketID = Request.QueryString["eid"];
string strFormID = Request.QueryString["form"];
string strServer = Request.QueryString["server"];
if (!string.IsNullOrEmpty(strTicketID) && !string.IsNullOrEmpty(strFormID) && !string.IsNullOrEmpty(strServer))
{
Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "application/octet-stream; name=ARNotification.ARTask";
Response.ContentEncoding = System.Text.Encoding.ASCII;
Response.AppendHeader("Content-ID", "ARNotification.ARTask");
Response.AppendHeader("Content-Disposition", "attachment; filename=ARNotification.ARTask");

StringBuilder sb = new StringBuilder();
sb.AppendLine("[Shortcut]");
sb.AppendFormat("Name = {0}", strFormID);
sb.AppendLine();
sb.AppendLine("Type = 0");
sb.AppendFormat("Server = {0}", strServer);
sb.AppendFormat("Ticket = {0}", strTicketID);
sb.AppendLine();
Response.Write(sb.ToString());
Response.Flush();
Response.Close();
}

Thursday, October 11, 2007

Cool C# keyword 'yield'

I like using C# language features you don't usually run across- just because it makes life (mine?) more interesting.

Jean-Paul S. Boodhoo's Blog has a post up on using the 'yield' keyword to instead of creating temporary lists. Very cool- that is the first I have seen of it.