Saturday, 30 January 2016

PerformUpgrade method for custom SSIS Task is missing

Case
I have an existing custom task that I want to expend with a couple of properties/features. But when I add an extra property I get an error in the LoadFromXML method in packages that where created with the old version. For a custom Component (Source/Transformation/Destination) you can use the PerformUpgrade method, but that is not available for tasks. How do I solve this?

 "Object reference not set to an instance of an object."
 occurred during "LoadFromXML" for task "myTask"















Solution
The LoadFromXML method gets the property values from the package XML.When it tries to get the value of your new property it fails because it doesn't exists in packages that where created with the old version of your task.

The solution is simple. Before getting the value from the attribute you must first check if it exists and if it doesn't you can give it a default value.
// C# code
void IDTSComponentPersist.LoadFromXML(System.Xml.XmlElement node, IDTSInfoEvents infoEvents)
{
    // This might occur if the task's XML has been modified outside of the Business Intelligence
    if (node.Name != "MyTask")
    {
        throw new Exception(string.Format("Unexpected task element when loading task - {0}.", "MyTask"));
    }
    else
    {
        // Populate the private property variables with values from the DTS node.
        this._hasConnectionmanagerSource = Convert.ToBoolean(node.Attributes.GetNamedItem("HasConnectionmanagerSource").Value);
        this._selectedConnectionManagerIDSource = node.Attributes.GetNamedItem("SelectedConnectionManagerIDSource").Value;
        this._selectedVariableIDSource = node.Attributes.GetNamedItem("SelectedVariableIDSource").Value;

        // Check if the new property exists in the package XML before getting it
        if (node.HasAttribute("MyNewProperty"))
        { 
            // Get it if it does exist and store its value in the private property variable
            this._myNewProperty = node.Attributes.GetNamedItem("MyNewProperty").Value;
        }
        else
        {
            // Give the private property variable a default value if it doesn't exist
            this._myNewProperty = "123";
        }
    }
}


The new version of the task with the extra property and its default value