+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

Taking advantage of the Virtual Path Provider in Sitefinity 4.1

by Slavo Ingilizov

We’ve done a lot to improve overall performance in the Sitefinity 4.1 release. Part of the performance comes from the upgrade of OpenAccess ORM. We also introduced a lot of caching improvements. The third major change that impacts performance a lot is the Sitefinity implementation of a Virtual Path Provider.

What is the virtual path provider?

I’m glad you asked. The virtual path provider is an ASP.NET extensibility point, which you can use to abstract how the framework reads the content of files in your web application. As Scott Guthrie put it in a blog post, it allows you to “Re-plumb the storage of a web-site from being the file-system to instead have all content stored in a database or some other store.”

This functionality has been available since ASP.NET 2.0, but we weren’t making use of it until now, because of some limitations in a medium trust environment. Those of you who have created custom controls with embedded templates in Sitefinity know, that we keep the templates inside assemblies. Before the virtual path provider, we had our own template parser, which had the job of reading the control template from the assembly, parsing it, creating an object model and passing it on to the page containing the particular control. This all happened in the shadow, without ASP.NET knowing about it. In short, we did what ASP.NET already did, but in our own way.

This was all done with the goal of making Sitefinity work in medium trust and shared hosting environments. Now that the virtual path provider supports medium trust natively, we switched to using the .NET way.

Why do you care?

Apart from bringing performance benefits, this also resolves issues you reported with the ViewState and control lifecycle. We recommend everyone to upgrade to 4.1. However, in some scenarios your site may break after an upgrade, and you need to update widget templates to fix the errors. These scenarios fall into two categories:

  • Custom controls you have implemented before Sitefinity 4.1
  • Customized templates you have for built-in Sitefinity controls

Typical errors that you may start seeing are:

"A required control was not found in the template for "path_to_template". The control must be assignable from type "control_type" and must have ID "control_id"."
"Parser Error. The ID 'Label1' is already used by another control."

The next section explains what you need to do in both of these cases.

What do you need to do?

Custom controls implemented before Sitefinity 4.1

Only a portion of custom controls created before Sitefinity 4.1 will break. However, we recommend doing these changes even if everything seems fine, because they would give you the benefits of using the virtual path provider.

Up until now, every custom control that you created either used an external template (ASCX file), or an embedded template.

The first option was used when your controls inherit from SimpleView and override the LayoutTemplatePath property, specifying the path to a native ASCX file. This will continue to work without problems.

The second option involved inheriting from SimpleView and overriding the LayoutTemplateName property, specifying the path to an embedded resource in your assembly. This now becomes obsolete. You should still override LayoutTemplateName, but return null instead. Also, you should override LayoutTemplatePath like this:

protected override string LayoutTemplateName
{
    get
    {
        return null;
    }
}
 
public override string LayoutTemplatePath
{
    get
    {
        var path = "~/SFJobs/Jobs.Resources.Views.JobApplicationUpload.ascx";
        return path;
    }
    set
    {
        base.LayoutTemplatePath = value;
    }
}

You can notice the weird “~/SFJobs/” prefix used in the path. This is the crucial part, telling the virtual path provider where to look for your template. We have registered such a prefix for all embedded templates of built-in Sitefinity controls, and you should do the same for all assemblies containing embedded templates. The above example does this for the assembly of the Jobs module. The prefix should be registered before the application is initialized in Global.asax:

protected void Application_Start(object sender, EventArgs e)
{
    Telerik.Sitefinity.Abstractions.Bootstrapper.Initializing += new EventHandler<Telerik.Sitefinity.Data.ExecutingEventArgs>(Bootstrapper_Initializing);
}
 
protected void Bootstrapper_Initializing(object sender, Telerik.Sitefinity.Data.ExecutingEventArgs args)
{
    if (args.CommandName == "RegisterRoutes")
    {
        var virtualPathConfig = Config.Get<VirtualPathSettingsConfig>();
        var jobsModuleVirtualPathConfig = new VirtualPathElement(virtualPathConfig.VirtualPaths)
        {
            VirtualPath = "~/SFJobs/*",
            ResolverName = "EmbeddedResourceResolver",
            ResourceLocation = "Jobs"
        };
        virtualPathConfig.VirtualPaths.Add(jobsModuleVirtualPathConfig);
    }
}

The code above creates an entry in the configuration, telling the virtual path provider that when it sees a template path beginning with “~/SFJobs/”, it should look for the template in the “Jobs” assembly. With this, all your controls will take advantage of the virtual path provider and all issues you may have will be resolved.

Customized templates of built-in controls

Some templates of built-in Sitefinity controls used to contain controls with repeating IDs. This worked with the Sitefinity parser, but it doesn’t work with the virtual path provider. In case you customized the template for such a control, you’ll get a yellow screen telling you there’s more than one control with the same ID. To fix it follow these steps:

  • Go to Design -> Widget Templates in the backend
  • Find your customized templates and back it up (by copying the content somewhere safe)
  • Open the template and reset it to the default (to get the fixes we introduced)
  • Manually copy your customized changes in the new template.

This should resolve the issue and you should be good to go.

We will be listening in the forums and support system for any other issues you may have, related to the changes in Sitefinity 4.1. We are also going to ship samples of modules and controls with the new changes in the Sitefinity SDK. Just let us know and we’ll support you as we’ve always done.

Leave a comment