Response.Redirect vs. Response.AddHeader vs. Server.Transfer

All these three are used to redirect the user from one location to another, but there are subtle differences.


  • Creates a whole new HTTP request to a new Url.
  • Produces a 302 http status code
  • Equivalent to ‘Temporary Redirect’ and the old Url is retained in search indexes. There won’t be any transfer of metrics.


Response.AddHeader on Location

  • Creates a whole new HTTP request to a new Url. (Common with Response.Redirect)
  • Produces a 301 http status code
  • The new Url is indexed instead by searchbot. There will be some loss of page rank / traffic value, but the stats will get transferred over.



  • This doesn’t change the current Url
  • An internal transfer is done on the server during execution path without creating a new HttpRequest.
  • FYI, the ‘rewrite’ option in the IIS urlrewrite module does a Server.Transfer.



Saving data to the Sitecore WFFM database programmatically

I am sure I am not the first to think that the Sitecore WFFM forms are not really as robust as we might like.
But because of the ready made form reports and marketing advantages, we might still want to leverage the wffm backend database for storing the form information, with an independent form front end.

This post is to show how we can save the form information to the wffm database without using the actions provided on submit.
Say you have your list of fields populated in a list of this class:

    public class WffmField
            public string FieldName { get; set; }
            public string FieldGuid { get; set; }
            public string FieldValue { get; set; }

The field guid would be the guid from sitecore:

You can then save to the WFFM database:

    // This should be populated with the data you want to send to the WFFM database
    var fields = new List<WffmField>(); 
    var wffmDatabaseFields = fields.Select(GetWFFMDatabaseField).ToList();
    	formId: new Sitecore.Data.ID("<Form guid here>"),
    	fields: new AdaptedResultList(wffmDatabaseFields),
    	sessionID: AnalyticsTracker.SessionId,
    	data: null);

This data will be available in the form reports now as expected.


Please note, you will need to add a reference to Sitecore.Forms.Core dll and following are the included namespaces:

using Sitecore.Form.Core.Analytics;
using Sitecore.Form.Core.Client.Data.Submit;
using Sitecore.Form.Core.Controls.Data;

Script to shrink t-sql logs for all databases on a server

Often on servers we have way too many databases to shrink logs individually when the server seems to be running low on space.
Here is a script which will in turn generate a script to do this for you.

SELECT name INTO #tempDBs FROM master..sysdatabases
where name not in ('master','tempdb','model','msdb')

DECLARE @CurrentDBName varchar(100)
DECLARE @CurrentDBLog varchar(100)
DECLARE @query varchar(1000)


SELECT DB_NAME(database_id), name FROM sys.master_files WHERE DB_NAME(database_id) in
(select name from #tempDBs) and physical_name like '%ldf'
-- and DB_NAME(database_id) like '%joyce%'

OPEN @AllDBsCursor
INTO @CurrentDBName, @CurrentDBLog

set @query = 'USE ['+@CurrentDBName+']
ALTER DATABASE ['+ @CurrentDBName +']
DBCC SHRINKFILE('''+@CurrentDBLog+''', 1) 
ALTER DATABASE ['+@CurrentDBName+']

PRINT @query

INTO @CurrentDBName, @CurrentDBLog
CLOSE @AllDBsCursor


Notify sitecore user on account enable

Often when a new user is created (especially if created from the sitecore site – as an extranet user), we might find the need to have an approval process in place to ensure access to credible users only.

You can see more details on creating extranet users for your site at Creating an extended Sitecore user for your site

When the user is being created, you can automatically disable the user initially by adding this before user save:

user.IsApproved = false;

This would disable the user id:

Now when a user admin of your site, goes and enables the user after review, you might want to intimate the user that their account has been enabled and they now have the privileges that it comes with!

The enable user command which is executed when a user is enabled resides in the App_Config\Commands.config file:

  <command name="usermanager:enable" type="Sitecore.Shell.Framework.Commands.UserManager.Enable,Sitecore.Kernel"/>

You can override this command and add your own functionality to the existing needed functionality for enable which you can bring over from the reflected code of Sitecore.Kernel.dll.

Here’s a sample of getting this done:

  <command name="usermanager:enable" type="Sitecore72.Classes.EnableUserNotify, Sitecore72"/>

Code (This is reflected code from sitecore.kernel.dll with an additional method call for the notification. You could sure choose to write the code yourself for enable – after all you only need to toggle a user property at the end of the day, but this code will also handle the confirm messages and all error handling for you)

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Net.Mail;
using System.Text;
using System.Web.Security;
using Sitecore.ApplicationCenter.Applications;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Shell.Framework.Commands;
using Sitecore.Shell.Framework.Commands.UserManager;
using Sitecore.Text;
using Sitecore.Web.UI.Sheer;
using Sitecore.Web.UI.WebControls;
using Sitecore.Web.UI.XamlSharp.Continuations;

namespace Sitecore72.Classes
    public class EnableUserNotify : Command, ISupportsContinuation
        /// <summary>
        /// Executes the command in the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public override void Execute(CommandContext context)
            Assert.ArgumentNotNull((object)context, "context");
            var userName = context.Parameters["username"];
            if (!ValidationHelper.ValidateUserWithMessage(userName))
            var parameters = new NameValueCollection();
            parameters["username"] = userName;
            ContinuationManager.Current.Start((ISupportsContinuation)this, "Run", new ClientPipelineArgs(parameters));

        /// <summary>
        /// Runs the pipeline.
        /// </summary>
        /// <param name="args">The args.</param>
        protected void Run(ClientPipelineArgs args)
            Assert.ArgumentNotNull((object)args, "args");
            ListString listString = new ListString(args.Parameters["username"]);
            if (args.IsPostBack)
                if (!(args.Result == "yes"))
                List<string> list = new List<string>();
                string key = string.Empty;
                foreach (string username in listString)
                    MembershipUser user = Membership.GetUser(username);
                    Assert.IsNotNull((object)user, typeof(MembershipUser));
                        user.IsApproved = true;


                        Log.Audit((object)this, "Enable user: {0}", new string[1]
                    catch (NotImplementedException ex)
                        key = "Sorry, this feature is not supported by the underlying provider implementation. Please contact the system administration for more details";
                    catch (NotSupportedException ex)
                        key = "Sorry, this feature is not supported by the underlying provider implementation. Please contact the system administration for more details";
                    catch (Exception ex)
                        key = ex.Message;
                        Log.Error("User can not be enabled", ex, (object)this);
                if (list.Count > 0)
                    StringBuilder stringBuilder = new StringBuilder();
                    foreach (string str in list)
                    SheerResponse.Alert(Translate.Text("The following users could not be enabled:\n{0}\nException:\n{1}", (object)((object)stringBuilder).ToString(), (object)Translate.Text(key)), new string[0]);
                if (listString.Count == 1)
                    SheerResponse.Confirm(Translate.Text("Are you sure you want to enable {0}?", new object[1]
            (object) listString[0]
                    SheerResponse.Confirm(Translate.Text("Are you sure you want to enable these {0} users?", new object[1]
            (object) listString.Count

        private void NotifyUser(User user)
            var emailMessage = new MailMessage
                From = new MailAddress(ConfigurationSettings.AppSettings["CompanyFromAddress"]),
                Subject = "You are a privileged member!",
                Body = user.FullName + ", you are now a privileged member of our club!"


            using (var client = new SmtpClient())

The corresponding smtp settings can be as usual found in the config:

        <network host="" port="25" userName="" password="" defaultCredentials="true" />

Creating an extended Sitecore user for your site

You might want to use the sitecore ASP.NET membership provider Core database to manage users for your sitecore site.

In that case, at some point during your site development, you will come across the need to create a new sitecore user from your site front end.
You might also want to have additional fields as is relevant to your application.
In this example, we are adding user address as additional custom fields.

The user template is available in the Core database of your sitecore instance.
The template is available at: /sitecore/templates/System/Security/User


You might also want to add a custom status field to be used by a site administrator – for user profile approval.

This field could point to a list of options also available in the core database:
Sample Template: /sitecore/templates/System/Security/User Profile Data/Profile Status Type

Options: /sitecore/content/Home/Data/Profile Status Types

Following is the code you could use to create the user:

Please note the code for default selection of the drop down field in the user template, and also the default ProfileItemId – which will determine which view the user will open in when you access the user from the User Manager console.

public bool CreateUpdateAccount(string firstName, string lastName, string emailAddress, string password,
            string addressLine1, string addressLine2, string city,
			string ddlCountriesText, string ddlStateText, string postalCode)
	var formData = new NameValueCollection();
	Sitecore.Security.Accounts.User user = null;

	formData["Name"] = firstName + " " + lastName;
	formData["Email"] = emailAddress;
	formData["Password"] = password;

	user = SecurityHelper.SitecoreSecurity.CreateSitecoreUser(formData);

	if (user != null)

		user.Profile.SetCustomProperty(Constants.UserCustomProperty.AddressLine1, addressLine1);
		user.Profile.SetCustomProperty(Constants.UserCustomProperty.AddressLine2, addressLine2);
		user.Profile.SetCustomProperty(Constants.UserCustomProperty.City, city);
		user.Profile.SetCustomProperty(Constants.UserCustomProperty.Country, ddlCountriesText);
		user.Profile.SetCustomProperty(Constants.UserCustomProperty.Region, ddlStateText);
		user.Profile.SetCustomProperty(Constants.UserCustomProperty.PostalCode, postalCode);

		// Constants.CoreDb.ItemGuid.PendingApproval - contains the GUID of the Pending Approval item in Core DB
		// in the folder: /sitecore/content/Home/Data/Profile Status Types
		user.Profile.SetCustomProperty(Constants.UserCustomProperty.ProfileStatus, Constants.CoreDb.ItemGuid.PendingApproval);

		// Constants.CoreDb.ItemGuid.PendingApproval has the guid of the item in Core at: /sitecore/system/Settings/Security/Profiles/User
		// This is to ensure that the default mode of the site created user has these custom properties.
		user.Profile.ProfileItemId = Constants.CoreDb.ItemGuid.SecurityProfileUser;

		return true;
	return false;

Security Helper method:

public static User CreateSitecoreUser(NameValueCollection formData)
	var fullUsername = Sitecore.Context.Domain.GetFullName(Guid.NewGuid().ToString());
	var user = User.Create(fullUsername, formData["Password"]);

	using (new SecurityDisabler())
		// Constants.CoreDb.ItemGuid.PendingApproval has the guid of the item in Core at: /sitecore/system/Settings/Security/Profiles/User
		user.Profile.ProfileItemId = Constants.CoreDb.ItemGuid.SecurityProfileUser;
		user.Profile.FullName = formData["Name"];
		user.Profile.Email = formData["Email"];
	return user;

Following is a user as seen from the user manager which was created from a site (note the ‘extranet’ domain)


Here is the populated droplink field:

For user login, the following code can be used:

Sitecore.Security.Authentication.AuthenticationManager.Login(domainName + @"\" + userName, password, false);

To validate user:

System.Web.Security.Membership.ValidateUser(domainName + @"\" + userName, password));

To access the custom fields:

var address1= currentUser.Profile.GetCustomProperty(Constants.UserCustomProperty.AddressLine1);

You can also get the list of users pending approval (if you wanted to for a custom User Admin page):

    public static List<User> GetUsersPendingApproval()
		IFilterable<User> allUsers = UserManager.GetUsers();

		// Constants.CoreDb.ItemGuid.PendingApproval - contains the GUID of the Pending Approval item in Core DB
		// in the folder: /sitecore/content/Home/Data/Profile Status Types
		return allUsers.Where(user => user.Profile.GetCustomProperty("Profile Status") == Constants.CoreDb.ItemGuid.PendingApproval).ToList();

Wrapping Rich Text Value in paragraph tag in Sitecore

Often we find the situation where the front end requires all text coming in from rich text fields in sitecore to be wrapped in say a <p> tag, for styling purposes.
In most cases, it is a better option to achieve this through code, than leave it up to the content authors.

You could go with one of the following 2 approaches:

You could create a new pipeline event in the

  • <saveRichTextContent> pipeline – This could enable you to append the <p> tag when you hit save on the rich text editor in sitecore
  • <renderField> pipeline – This could on the fly wrap your text into <p></p> tag while rendering the page, if the <p> tag was not there in the original rtf text.

If you go for method 1: <saveRichTextContent>
You could add to the pipeline in web.config:

<processor type="Sitecore72.Classes.WrapRichTextInParagraphOnSave, Sitecore72" />

And you could use the following corresponding code:

    namespace Sitecore72.Classes
        public class WrapRichTextInParagraphOnSave
            public void Process(SaveRichTextContentArgs args)
                if (!(args.Content.Trim().StartsWith("<p>") && args.Content.Trim().EndsWith("</p>")))
                    args.Content = "<p>" + args.Content + "</p>";

Please note, that this pipeline gets triggered only when you use the Show Editor buttong of a rich text field:

If you go for method 2: <renderField>

To append to this pipeline you would use this config:

<processor type="Sitecore72.Classes.WrapRichTextInParagraphOnRender, Sitecore72" />

And you could use the following corresponding code:

    namespace Sitecore72.Classes
        public class WrapRichTextInParagraphOnRender
            public void Process(RenderFieldArgs args)
                if (args.FieldTypeKey == "rich text" && !(args.Result.FirstPart.Trim().StartsWith("<p>") && args.Result.FirstPart.Trim().EndsWith("</p>")))
                    args.Result.FirstPart = "<p>" + args.Result.FirstPart + "<//p>";

For both these, ensure you add reference to Sitecore.Kernel.dll.