SharePoint DateTimeField control and the order of its properties

by Christoph Herold 19. November 2008 17:37

Today, I was building a nice little page layout for SharePoint and wanted to use SharePoint DateTimeField control. Since the field I wanted to edit was DateOnly, I set the corresponding property, leaving me with this code:

<SharePointWebControls:DateTimeField runat="server" id="dtfArticleStartDate"
    DateOnly="true" FieldName="ArticleStartDate" />

Seems fine to me, but ASP.NET did not like it. Or rather, the control did not like it. I got an ArgumentException with the following StackTrace:

[ArgumentException: FieldName value is not specified.]
Microsoft.SharePoint.WebControls.FieldMetadata.get_Field() +150
Microsoft.SharePoint.WebControls.DateTimeField.CreateChildControls() +310
System.Web.UI.Control.EnsureChildControls() +87
Microsoft.SharePoint.WebControls.DateTimeField.set_DateOnly(Boolean value) +29
ASP.MYNEWSPAGE_ASPX__2072755151.__BuildControldtfArticleStartDate()

FieldName value is not specified?! As you can see in my code above, it is indeed specified. But the stack trace gives us more information: The exception occurs in the compiled ASPX file.

  • ASP.MYNEWSPAGE_ASPX__2072755151.__BuildControldtfArticleStartDate():
    - We are building my DateTimeField control.
  • DateTimeField.set_DateOnly:
    - We are setting the DateOnly property.
  • FieldMetadata.get_Field:
    - Getting the field is where the exception occurs.

Note my ASPX-code again: I first set DateOnly="true" and then FieldName="ArticleStartDate". Oh my god, this can't be true... The solution is very simple: change the order of the attributes/properties:

<SharePointWebControls:DateTimeField runat="server" id="dtfArticleStartDate"
    FieldName="ArticleStartDate" DateOnly="true" />

Against all good practices, the SharePoint team actually created a direct dependency between two properties. At least the stack trace directly tells you where things go wrong, so the solution is obvious. Nonetheless, I thought, this was worth noting. It actually made me laugh, when I encountered it. Another one of those nice little pitfalls when working with SharePoint :-)

Tags: , , ,

Development

News concerning TransactionScope and Timeouts

by Christoph Herold 28. März 2008 11:33

We finally got a useful response concerning the TransactionScope Timeout problem. Someone else had a similar issue and started a new thread in the Microsoft forums: http://forums.microsoft.com/forums/ShowPost.aspx?PostID=3069149&SiteID=1. The issue has been resolved, but only as of the .NET Framework 3.5. There is a new connection string parameter named "Transaction binding". This is set to "Implicit unbind", which by default causes the described (mis-)behavior. Instead, you must set it to "explicit unbind", so that queries issued after the transaction times out are still considered to be INSIDE the transaction and not in auto-commit mode. You can read the details in the forum post.

Alas, this only solves the problem when using the SqlClient ADO.NET provider. For all other transactive repositories, the issue still exists.

Tags: , ,

Development

Outlook 2007 HTML-Mail Guidance

by Christoph Herold 25. Juli 2007 11:12

Microsoft changed the rendering engine in Outlook 2007 to Word's HTML-engine, and it really sucks concerning modern design habits (css-positioning, etc.). So you have to look out for some pitfalls. I found a nice guide for designing HTML-Mails for use in Outlook 2007, which can be found at http://www.duoconsulting.com/downloads/contribute/SevenDesignTipsforOutlook2007.pdf.

Also, Microsoft offers tools to validate HTML files for the Word rendering engine. These can be found at http://www.microsoft.com/downloads/details.aspx?familyid=0b764c08-0f86-431e-8bd5-ef0e9ce26a3a.

So, good luck with your e-mail marketing ;-)

Tags: ,

Development | Design

Connecting to a SqlExpress User Instance

by Christoph Herold 25. April 2007 16:41

If you've ever built an ASP.NET application using a User Instance database, you may have come across the problem, that you would have liked to access the database using the Management Studio or similar programs, but just couldn't find the database, because it is in the user instance and not in the database server itself.

I'd like to issue my thanks to Mike of the Sql Server Express Weblog for publishing how it's done. I looked for hours trying to get the database attached to the regular server, but all that is not neccessary. You can directly connect to the user instance by using a named pipe. The original explanation can be found here: http://blogs.msdn.com/sqlexpress/archive/2006/11/22/connecting-to-sql-express-user-instances-in-management-studio.aspx. Below are the required steps in short.

  • Connect to the server normally.
  • Issue a new query:
    SELECT owning_principal_name, instance_pipe_name, heart_beat FROM sys.dm_os_child_instances
  • Locate the user instance you wish to connect to and copy the instance_pipe_name column's value.
  • Open a new server connection and use the copied value as the server name.

And presto, you can access everything as you would in the regular server.

Note: The pipe name is generated, when the user instance is first created. After that, it will always remain the same, so you can store it for later use. Access is only possible, when the user instance is active (see the heart_beat column). If it is not, you must first launch the application that uses it (i.e. the web site).

Tags: ,

Development | Administration

PersistenceMode.InnerDefaultProperty

by Christoph Herold 21. Dezember 2006 11:34

While I was building an ASP.NET user control, I ran across the problem, how to serialize a property as the inner text of the Control in the ASPX-Code. I found a nice attribute named PersistenceModeAttribute, that allows you to specify, how a property is supposed to be persisted. Setting it to InnerDefaultProperty or EncodedInnerDefaultProperty should do the trick, I thought.

But, as I had to find out, this is only part of what needs to be done. There are two more Attributes, that control the parsing of a control: ParseChildrenAttribute and PersistChildrenAttribute. When you use InnerDefaultProperty to persist a property, you must add [ParseChildren(true, "")] and [PersistChildren(false)] to your control's class declaration. Otherwise things won't persist.

It took me a while to find this solution, and I found a nice explanation of things here: http://alvinzc.blogspot.com/2006/10/aspnet-basic-of-custom-server-control_25.html.

Alvin did a really nice job of explaining, what the attributes do. So if you want the details, just visit his blog.

Tags: , ,

Development

TransactionHelper

by Christoph Herold 27. November 2006 11:28

For the time being, I have built myself a helper class, that tries to fix the "timeout-bug" when using TransactionScope. And since I'm such a nice guy, I decided to let everyone have it ;-)

So here goes, completely commented including a usage example:

using System;
using System.Threading;
using System.Transactions;

namespace HeroldIT.Framework.Utils
{
    /// <summary>
    /// This class is used to abort transactions when the timeout occurs.
    /// </summary>
    /// <remarks>
    /// <para>This class is required, because TransactionScopes do not abort processing, when they expire. Instead
    /// all actions done after the timeout occurs are not included in the transaction, but instead carried out
    /// normally. This can lead to inconsistencies in your data, when processing large amounts.</para>
    /// 
    /// <para>This class can be used nestedly, i.e. methods called in the supplied working delegate can safely
    /// create instances of this class.</para>
    /// </remarks>
    /// <example><code>
    /// try
    /// {
    ///     using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 2)))
    ///     {
    ///         new TransactionHelper(delegate() {
    ///                 // do transactive work here
    ///             });
    ///         ts.Complete();
    ///     }
    /// }
    /// catch (TransactionAbortedException tae)
    /// {
    ///     // handle aborted transaction
    /// }
    /// </code>
    /// </example>
    public sealed class TransactionHelper
    {
        /// <summary>
        /// A tagging object to determine, whether the thread is aborted due to a transaction timeout
        /// </summary>
        private object _abortObject;
        
        /// <summary>
        /// The current thread executing the transactive work
        /// </summary>
        private Thread _currentThread;

        /// <summary>
        /// Creates a new TransactionHelper that executes transactive statements and aborts the process
        /// if a timeout occurs.
        /// </summary>
        /// <param name="toExecute">The delegate to call for processing</param>
        public TransactionHelper(ThreadStart toExecute)
        {
            if (null == toExecute)
                throw new ArgumentNullException("toExecute");
            
            // get current transaction
            Transaction tx = Transaction.Current;

            if (null == tx)
                throw new InvalidOperationException(Resources.ExcNoAmbientTransaction);

            // Don't execute, if the transaction is already aborted
            if (tx.TransactionInformation.Status != TransactionStatus.Aborted)
            {
                // keep handle to current thread for aborting
                _currentThread = Thread.CurrentThread;

                // register completion handler
                tx.TransactionCompleted += new TransactionCompletedEventHandler(Current_TransactionCompleted);
                
                // execute transactive code
                try
                {
                    toExecute();
                }
                catch (ThreadAbortException tae)
                {
                    // was the thread aborted by our TransactionCompleted handler?
                    if (null != _abortObject && tae.ExceptionState == _abortObject)
                    {
                        Thread.ResetAbort();
                    }
                }
                // unregister completion handler (required when using multiple TxHelpers in one transaction,
                // otherwise multiple ThreadAbortExceptions are thrown on timeout)
                tx.TransactionCompleted -= new TransactionCompletedEventHandler(Current_TransactionCompleted);
            }
        }

        /// <summary>
        /// Transaction completion event handler, that checks, whether a timeout occured
        /// and, if so, causes the registered executing thread to abort
        /// </summary>
        /// <param name="sender">The originating transaction</param>
        /// <param name="e">The event args for this event</param>
        void Current_TransactionCompleted(object sender, TransactionEventArgs e)
        {
            // Is the transaction aborted (possibly due to timeout)?
            if (e.Transaction.TransactionInformation.Status == TransactionStatus.Aborted)
            {
                // Is the executing thread registered?
                if (null != _currentThread)
                {
                    // generate a new abortion tagging object
                    _abortObject = new object();
                    
                    // abort the executing thread
                    _currentThread.Abort(_abortObject);
                }
            }
        }
    }
}

I hope, this helps some of you. Of course, I'll be updating my blog, as soon as some notice of how TransactionScope is supposed to be used reaches me. I know, that ThreadAbortExceptions aren't something to use lightly, but currently I see no other way.

Tags: ,

Development

Installing multiple versions of IE

by Christoph Herold 20. November 2006 11:12

One of the biggest pains for web developers is probably the fact, that Microsoft does not support installing multiple versions of IE in one Windows. But there is hope: The folks at tredosoft came up with a nice installer, that allows you to install most versions of IE. There are some small drawbacks, but it should suffice for most tests. You can get it here: http://tredosoft.com/Multiple_IE.

Tags:

Development

TransactionScope, ADO.NET, and Timeouts (revisited)

by Christoph Herold 18. November 2006 11:10

Someone has finally found a dirty, yet working solution to the TransactionScope problem. You can register an event on the transaction, that fires, when the transaction finishes, which also happens on a timeout. You can then abort the main thread, to keep further commands from executing.

%lt;p>And this is also the dirty part: ThreadAbortExceptions are a little dangerous and can cause unexpected behavior. But for now it works for me, and as long as Microsoft does not come up with a better solution, I'll have to use this.

You can find more details here: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=876150&SiteID=1

Tags: ,

Development

TransactionScope, ADO.NET, and Timeouts

by Christoph Herold 31. Oktober 2006 10:58

Happy Halloween everyone!

Today I'll tell you about some problems I've been having with the TransactionScope class. Namely, I've had timeouts running out, but the application still running the nested queries until they were finished. Amazingly, the data seemed to be in the tables, although the TimeoutException was thrown.

This has now happened to me in multiple applications. But today I read an article on the System.Transactions namespace (http://msdn.microsoft.com/msdnmag/issues/06/11/DataPoints/default.aspx). There the author states, that you should open the database connection INSIDE the TransactionScope. This becomes logical, when you know that there is also a parameter you can add to the connection string named "auto-enlist" defaulting to true, that tells ADO.NET to look for an ambient transaction when connecting. So, if you open the database connection and then open a TransactionScope, the database does not seem to care about the ambient transaction.

I haven't tried yet, if this solves my problems. But since this is quite an important matter, I wonder why Microsoft does not point this out clearly. The TransactionScope may be a really great invention, but if you don't know how to use it, it causes damage instead of making things safer.

[Update]: This did not fix the problem. Instead, I built a test-app containing both a method, which first opens the database, then the TransactionScope, and a method doing it the other way around. Both methods have the same result. And that is VERY disappointing: The changes to the database made during the Transaction's non-timeout-ed period are rolled back, all changes AFTER the transaction times out are committed. I've written a post in the MSDN-Forum concerning Transactions Programming (http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=876150&SiteID=1). Let's see what they come up with.

Tags: ,

Development

Service Factory with WCF

by Christoph Herold 24. September 2006 10:53

The Microsoft Patterns and Practices team published a Service Factory Add-On recently, that enables the Service Factory to also create WCF services. Sorrily, just after the release of the Add-On, the .NET Team released .NET 3.0 RC1, which is not supported by the Add-On.

If you still wish to install it, you can install the Orca tool located in the bin/ directory of the Windows Vista SDK, open the Service Factory WCF installer package, and change the value of the LaunchCondition variable FRAMEWORK30 to the Version of RC1 (3.0.04324.17). Save it and then you can install it.

You can find more information at http://www.gotdotnet.com/codegallery/messageBoard/Thread.aspx?id=6fde9247-53a8-4879-853d-500cd2d97a83&mbid=fc07ebfb-4369-48e1-ab74-d6098ed220fe&threadid=99894479-0335-4a1b-bf91-bf771237cdfb.

Tags: , , ,

Development

Month List

Impressum (for the Germans)

Christoph Herold

Dieses Weblog wird bereitgestellt und verwaltet durch

Christoph Herold
Ignaz-Semmelweis-Str. 37
41540 Dormagen
Deutschland

Sie erreichen mich unter christoph.herold@coeamyd.net.