Tim's .NET Software Architecture Blog

Adventures in Architecting and Developing .NET Applications


News


CAG

Technorati Profile

www.flickr.com
    follow me on Twitter

    My Stats

    • Posts - 178
    • Comments - 98
    • Trackbacks - 42

    Tag Cloud


    Recent Comments


    Recent Posts


    Archives


    Post Categories


    Image Galleries


    Blogs


    Link Blogs


    Links


    Podcasts



    As far as I have seen content controls in Office 2007 render to either a SdtRun or SdtBlock object.  The nice thing is that both of these inherit from SdtElement.  This allows you to take the query from my earlier post and replace SdtBlock with SdtElement and now you have a universal retrieval.  Of course as with any tool you need to be careful you don’t take it too far.  Depending on the structure of you document this may not do what you need.

    Technorati Tags: ,,,


    I try not to  be too much of a reposter, but I got a little nostalgic on this one.  I remember when the first version of this tome came out and I got a free copy when I visited Redmond for the Guided Design conference.  You may not agree with everything you find in here, but it is definitely worth the read to see what Microsoft thinks architecture is.



    If you are using a template document and replacing text programmatically using the Office Open XML SDK 2 API you will need a way to identify the target to be replaced.  One option is to use a Content Control and setting the tag value the same for all of the controls that need to be substituted with a single value.  After some trial and error and a lot of digging through the DocumentReflector I came up with the following LINQ query to get a list of all blocks with the same tag name.

     

    var blocks = from s in part.MainDocumentPart.Document.Descendants<SdtBlock>()
                 where (
                         s.GetFirstChild<SdtProperties>().GetFirstChild<Tag>() != null
                         && s.GetFirstChild<SdtProperties>().GetFirstChild<Tag>().Val.Value.Equals(placeholder)
                         )
                 select s;

     

    The nice thing is that all Word document content controls have the tag property as an option so this works whether you are searching for text, rich text or quick parts.  If you are searching for images and some other content controls you may have to search for SdtRuns instead of SdtBlocks, but the query is essentially the same.

    Technorati Tags: ,,,


    I am branching out.  nPlus1.org is having an ArcSummit event and needed someone to speak on Dependency Injection.  Sign me up.  If you are interested in this or the other topics to be presented please join us.  There is more information about the event and a registration link below.


    https://www.clicktoattend.com/invitation.aspx?code=142763

    About nPlus1.org

    nPlus1.org is a site dedicated to helping Architects, aspiring Architects and Lead Developers learn, connect and contribute. On this site you’ll have access to great first party content written by some of the most skilled and experienced Architects working today. You’ll also have access to, and be able to contribute to a nexus of content from around the Internet aimed at keeping Architects up to date on all the new developments in their fields of interest.

    When

    Monday December 7, 2009 – 10:00PM to 5:00PM

    Where

    Microsoft MTC - Aon Center

    200 E. Randolph

    Suite 200

    Chicago, IL 60601

    driving directions

    Free Lunch Provided

    Agenda

    Morning Session (Optional): An Introduction to Object Oriented Programming

    10:00 AM - 12:00 PM

    Are you new to OOP? Do you want a refresher on the benefits of Interfaces and the differences between implements and extends? The morning session is a two hour introductory course of Object Oriented Programming. If you are new to OOP the lessons in this session will prepare you for the more advanced topics in the afternoon.

    If you are already well versed in OOP then feel free to come have a refresher, or simply join us for lunch and the advanced sessions in the afternoon. The morning session is completely optional.

    Afternoon sessions:
    Session One: Software Patterns

    Patterns are an important tool to use as architects and developers. They provide a common vocabulary for us to design with, as well as a common approach to a common problem. Come learn about useful patterns, and how to use them in your everyday code.

    Session Two: How I Learned To Love Dependency Injection

    Dependency Injection is one of those scary topics that most developers avoid. It sounds all ‘high-falootin’ and complex. It’s not. Really. We wouldn’t lie. It’s a great way to manage complexity in your system, and a great way to make your system so much more testable. And isn’t that what we all want?

    Each session will be followed by open discussions periods.

    A catered lunch will be provided starting at noon. This will divide the morning introductory sessions from the advanced sessions. Register once for all session and choose to attend the morning, the afternoon or both! Lunch is provided for attendees for any of the sessions.



    If you haven’t heard of Office Open XML don’t be surprised.  I hadn’t until a couple of months ago.  In short it is a standardization of the Office document models which allows for more flexible development methods.  You no longer need to have an instance of your target Office application running on a server in order to generate Word, Excel or PowerPoint documents.  This is also the reason that all of the Office file extensions have a “x” suffix these days.

    Office Open XML files are actually zip files.  This is to allow verbose XML files and required associated documents to be kept as a single package instead of in a binary format.  Given that we are talking about XML files in a zip archive, you can really program against Office Open XML documents simply by knowing the schema definition.  But who wants to do that if someone has already given you a strongly typed API library?

    This is where the Open XML SDK 2.0 comes in.  This library gives you strongly typed classes which represent the parts that make up documents.  This in turn makes reading you code easier than simply using a XMLDocument to modify the file.

    When working with the XML of a document I have found it hard to find a compact reference of element types.  Of course you can always refer to the verbose ISO standards document (all 5572 pages worth).  Going forward I hope to have some helpful tips for working with the powerful but under-documented technology.  Stay tuned.



    CAG

    The Chicago Architects Group will be holding its next meeting on October 29th.  Please come and join us and get involved in our architect community.

    Register

    Presenter: David Dickinson
    Topic: Agile Development Principles and their Practical Application
     
    Location: Illinois Technology Association
    200 S. Wacker Dr., Suite 1500
    Room A
    Chicago, IL 60606
    Time: 6:15 - Doors open at 6:00



    There is a lot of this going around lately, either by choice or by force.  For better or for worse (hopefully better) I have moved from Daugherty to PSC.  I am still consulting, but with a company that is more focused on the Microsoft technology stack.  Stay tuned for new adventures.



    There is nothing earth shattering here.  I was just putting together a set of snippets to make life a little easier while developing SharePoint and Office Open XML projects. My search for information crossed a lot of different sites.  MSDN has a number of articles about all the features of creating and managing snippets.   Below is a compilation of the basics around creating these little helpers.  Hopefully it is a little more detailed in the whys then MSDN content.

    Creating A Snippet File

    Snippet files are really just XML files with a .snippet extension.  The main thing is the schema that is applied and the available tags.  I have found a couple of namespaces listed for the CodeSnippets tag, but the following seemed to work most reliably.

    <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">

    Once you have that in place you can start working on the header information.  These include your title, author, description and shortcut.  Most of this shows up in the snippet manager, but the shortcut allows a developer to type the shortcut text and hit tab to invoke the snippet.

    <Header>
      <Title> 
        MySnippet
      </Title>
      <Description>Inserts my favorite code</Description>
      <Author>Tim Murphy</Author>
      <Shortcut>myshortcut</Shortcut>

    </Header>

    Now we get to the meat of the snippet.  The snippet itself is broken into two parts: the declaration and the code.

    The declaration allows you to define the parts of your snippet which the developer will need to replace with their own identifiers.  Declarations themselves come in two flavors: literals and objects.  While this should be pretty self-explanatory lets be thorough.  Literals are just that.  They are strings that can be inserted at the specific location.  These are perfect for letting the developer insert URLs or string defaults in declarations.  Objects on the other hand have a type specified for them.

    For all declarations you are allowed to add a tooltip so the the developer understand the usage of your snippet.  Below are examples of both kinds of declarations.

      <Declarations>
       <Literal>
        <ID>
         Var
        </ID>
        <ToolTip>
         Replace with your variable name
        </ToolTip>
        <Default>Var</Default>
       </Literal>
       <Object>
        <ID>
         Url
        </ID>
        <ToolTip>
         Replace with the Web URL
        </ToolTip>
        <Type>string</Type>
        <Default>URL</Default>
       </Object>
      </Declarations>

    Once you have the declarations defined you simply add you code as you would normally see it.  The only catch is that you will need to create a token in the code for each declaration offset by dollar characters ($).

    <Code Language="CSharp">
      <![CDATA[
                  using (SPSite $Var$ = new SPSite($Url$))
                     {
                     }
       ]]>
    </Code>

     

    Using The Snippet Manager

    The snippet manager allows you to import your files and make them available within the Visual Studio environment.  One thing it does not seem to allow you to do is delete individual snippet files.  It has the option to delete a directory which is great as long as you use the Add feature which allows you to bring in an entire folder of snippets at one time.  Otherwise all snippets added with the Import feature get put under the My Code Snippets folder.

    And that about covers the basics.  Good coding …



    Now how many people understand the reference in the title.  I don't know if it something that is still done today, but it was a big deal when we moved from Win16 to Win32.  I essentially allowed 16bit applications to run on a 32bit Windows machine. 

    Today I was reminded of this as I removed Windows 7 64bit from my machine because certain applications still do not work on that platform.  Event through 64bit processors and even operating systems have been around for a while they still haven't achieved critical mass.  This means that for a while yet we will still be playing Russian Roulette when we install Win7 64bit.

    For me, I spent the afternoon rebuilding my system on 32bit Windows 7 because of one incompatibility that was risking my project.  That doesn't mean that there is something wrong with the platform.  It is just ahead of its time.  I'm sure I'll be re-installing it soon enough.



    SharePoint has been around for quite some time.  I first worked with it in its original version in 2001.  And so began a love hate relationship that has lasted these many years. 

    Recently I have been spending a significant amount of time writing custom web parts.  Below are a number of notes I have accumulated while rediscovering what SharePoint can do.  I don’t claim that these are best practices, only that they have worked for me.

    Environment

    General

    Creating web parts for WSS 3.0 or MOSS 2007 requires Visual Studio 2005 or Visual Studio 2008. There is a downloadable package Visual Studio Extensions for Windows SharePoint Services 3.0. The problem with this particular tool is that it requires that you develop on a machine with Windows Server 2003 or Windows Server 2008 as an operating system. Developing on a stand alone desktop/laptop while referencing the main SharePoint assembly can be much simpler. It is a trade off between licenses issues and portability challenges versus a lack of productivity tools. For this discussion we will assume a stand alone, non-server environment.

     

    WSPBuilder

    WSPBuilder is a CodePlex project for creating SharePoint solution files. Besides packaging web parts it is also a tool for packaging features and workflows. The tool can be downloaded from the following location:

    http://wspbuilder.codeplex.com/

     

    Coding

    Starting A Web Part

    Web Parts are really just specialized web server control. That being said, creating a web server control is the perfect place to start and then modify it for SharePoint. Alternately you could start with an ASP.NET web part. The caution here is that they implement a different set of events.

    One of the first things you will need to do is to change the class that the control inherits from to Microsoft.SharePoint.WebPartPages.WebPart.

    Additionally you will need to add the following import statements:

    using System.Xml.Serialization;

    using Microsoft.SharePoint;

    using Microsoft.SharePoint.WebPartPages;

     

    Adding Web Part Properties

    Web Part Properties are the definition of the settings which allow you to configure a web part once you have placed it on a page. They start out the same as any C# property with a getter and setter. The main difference are the attributes that are applied to the property.

     

    [Browsable(true)]

    [Category("User Creation Settings")]

    [DefaultValue("")]

    [WebPartStorage(Storage.Shared)]

    [FriendlyName("Role Provider Name")]

    [Description("Name of the membership role provider")]

    [XmlElement(ElementName = "roleProvider")]

    public string ProviderName

    {

    get

    {

    return _ProviderName;

    }

    set

    {

    _ProviderName = value;

    }

     

    Adding controls to a web part

    There isn’t a designer for creating web parts. The process reminds me of C++ MFC development. You have to define, instantiate and position all of your controls through code. I have seen some possible short cuts be first creating user controls, but the process seemed a little hackish and I haven’t tested it yet.

    First you should define the controls globally in your class.

     

    TextBox _FirstName;

    TextBox _LastName;

    DropDownList _OptionType;

    Button _CreateUser;

    Label _Message;

     

    Once you have your controls defined you instantiate them in the CreateChildControls override method. This is also the point where you wire up any event handler methods. The code below is an example of the techniques that can be used.

     

    _FirstName= new TextBox();

    _FirstName.CssClass = "my-textbox";

    this.Controls.Add(_FirstName);

    _OptionType= new DropDownList();

    _OptionType.Items.Add(new ListItem("Yes"));

    _OptionType.Items.Add(new ListItem("No"));

    this.Controls.Add(_OptionType);

    _CreateUser = new Button();

    _CreateUser.CssClass = "my-button";

    _CreateUser.Text = "Create User";

    _CreateUser.Click += new EventHandler(_CreateUser_Click);

    this.Controls.Add(_CreateUser);

    _Message = new Label();

    _Message.CssClass = "my-errorMessage";

    this.Controls.Add(_Message);

     

    The last step in order to display controls for use in your web part is to implement the RenderContents override method. This method uses a HtmlTextWriter object to render the tags for the UI of your web part. The most straight forward, although not necessarily the simplest, way to do this is to write out the text of your layout tags and them pass the writer object to your controls so that they can render themselves. Alternately you can do your layout entirely through rendering controls which represent all of your resulting HTML tags. Below is an example of the first approach.

     

    output.WriteLine("<table>");

    output.WriteLine("<tr><td>");

    output.WriteLine("First Name");

    output.WriteLine("</td><td>");

    _FirstName.RenderControl(output);

    output.WriteLine("</td></tr>");

     

    Essential SharePoint Objects

    The most important classes within the SharePoint object model represent the hierarchy of the SharePoint. These are the SPWeb and SPSite classes. SPWeb represents a SharePoint web application as you would configure in Central Administration. SPSite represents a site collection.

    You do not always have to instantiate these classes explicitly, although there are some cases where that is a requirement.

     

    Adding users to security groups

    Managing SharePoint security for end users can be very confusing. One way to alleviate this burden is to create a web part that abstracts away the details. The main class used to facilitate this capability is SPGroup.

    There are two critical things to note in the code below. The first is the fact that it is written as an inline delegate to elevate the privileges of the current user.

    The second thing to note is the use of the AllowUnsafeUpdates property of the SPWeb object.

     

    SPSecurity.RunWithElevatedPrivileges(delegate()

    {

    SPSite newSite = new SPSite(_SiteUrl);

    SPWeb web = newSite.OpenWeb();

    web.AllowUnsafeUpdates = true;

    SPGroup candidateGroup = web.Groups[_SharepointGroup];

    candidateGroup.AddUser(fullyQualifiedUserID, _Email.Text, userName, string.Empty);

     

    Adding items to lists

    The topic of lists covers both SharePoint Lists and Document Libraries. They are both essentially list, except for one puts more emphasis on attachments than the other. Because of this they can be treated the same in many respects. The code below adds a file to a document library and then sets values for columns on that list.

     

    SPFolder folder = web.GetFolder(_Folder);

    SPFile sourceFile = web.GetFile(_TemplateUrl);

    string folderUrl = folder.ServerRelativeUrl + "/";

    string fileName = _BaseFileName + ".xml";

    sourceFile.CopyTo(folderUrl + fileName);

    SPFile newFile = folder.Files[fileName];

    newFile.Item["First Name"] = _FirstName.Text;

    newFile.Item["Last Name"] = _LastName.Text;

    newFile.Item["Full Name"] = _LastName.Text + ", " + _FirstName.Text;

    newFile.Item["Preferred Name"] = _PreferredName.Text;

    newFile.Item["Appointment Type"] = _OptionType.SelectedItem.Text;

    newFile.Item.Update();

     

    Notice that the last line calls the Update method on the item. If this call is not made then your changes will not be saved.

     

    Deploying

    Deploying SharePoint web parts can be tedious and problematic. While installing them by hand is possible solution files make the process somewhat easier to manage. At the beginning of the paper I mentioned WSPBuilder. The WSP stands for WSS Solution Project. What these boil down to are CAB files which include deployable objects and a manifest of the contents. WSPBuilder simplifies the creation of these files.

    There are two ways that this can be accomplished. Installing the WSPBuilder gives you Visual Studio extensions as well as new Visual Studio templates. The former simply packages the assembly of a project and creates safe control entries for your web.config file.

     

    Adding the solution to SharePoint using stsadm

    Once you have created a solution you need to copy it to the server that Central Admin resides on. There you will use the stsadm command line tool to install the solution. Execute the following command, making sure to modify the filename parameter value for the location you copied the wsp file to.

    C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN>stsadm -o addsolution -filename "d:\webparts\MyWebPart.wsp"

     

    Deploying solution through Central Admin

    The only time that I have found that I needed to access Central Admin for a web part solution is initial deployment or to remove a solution.

    In order to deploy the web part solution that was added during the previous section you need to navigate to Solution Management from the Operations tab in Central Admin. There you will see a list of solutions. From there click on the solution that you want to deploy and click the Deploy Solution button at the top of the screen that appears.

     

    Upgrading a solution to SharePoint using stsadm

    Interestingly, there are more parameters required to upgrade a solution then there are to install it in the first place. This is mostly due to the functions that are taken care of by the Central Admin deployment capabilities.

    C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN>stsadm -o upgradesolution -filename "d:\webparts\MyWebPart.wsp" -name " MyWebPart.wsp" -immediate –allowGacDeployment

    Note: If you do not keep the same version number for the assembly you will break any pages that already contain the web parts contained in that assembly.



    Ok.  So I am late to the scene on this one.  You would think that as long as I have been writing .NET code I would have tried Code Rush before now.  I am really finding to be an educational tool.  I figured I would spend some time going through the help file to find out what was there.  The Refactoring Catalog has animations which make understanding the features so much faster.  At the same time I am finding that it is showing me better ways to write more compact code.  Do yourself a favor and check it out.



    CAG

    The Chicago Architects Group will be holding its next meeting on July 30th.  Please come and join us and get involved in our architect community.

    Register

    Presenter: You
    Topic: Current Topics in Architecture Open Discussion
    Location: Illinois Technology Association
    200 S. Wacker Dr., Suite 1500
    Room A
    Chicago, IL 60606
    Time: 5:30 - Doors open at 5:15



    CAG

    The Chicago Architects Group will be holding its next meeting on May 28th.  Please come and join us and get involved in our architect community.

    Register

    Presenter: Sean Blanton
    Topic: Trends in Continuous Integration and Software Delivery
    Location: Microsoft - Downers Grove
    3025 Highland Pkwy
    Suite 300
    Downers Grove, IL 60515-5506
    Time: 6:00 - Doors open at 5:30



    This is a topic that we have been discussing around the water cooler lately.  And then this morning I found a blog entry which covered the same subject and I figured I would pile on.

    As architects we have to keep up with as much as possible.  The means reading incessantly.  With tomes that reach into the high hundreds of pages and articles and blogs spitting out new material daily this is a major challenge.  This is doubly true for me since I never developed speed reading skills.

    I really like Garry’s suggestions.  They aren’t anything new, but reminders always help.



    This is a subject I am just starting to understand.  I talked with Dave Bost the other day at the February CAG meeting about Azure.  This morning the subject came up again as I was listening to the Thirsty Developer podcast.  These got me thinking about where does cloud computing fit in?

    As I understand it the difference between ASP model and Azure is that an ASP is hosting their application for you to use and what Azure offers hosting your application.  Now this differs again from normal hosting companies since with Azure you are purchasing application resources instead of server resources.  I believe that as a term “Cloud Computing” can actually cover all of these scenarios.

    Where I see this as an opportunity is for smaller companies who can’t afford a staff to manage a set of servers.  I am sure that large companies will also leverage this technology, but proportionally this type of expense is a larger part of a small companies expenses.  Spend your money on developing applications that allow you to run your business, not on maintaining a server farm and all that goes with it.

    Of course all this is just initial thoughts based on very little information.  What I do think it deserves is a closer look.

    Technorati Tags: ,