Docs / Tutorials / How to create a custom Action

How to create a custom Action

sensenet has a powerful feature for defining and accessing content operations called the Smart Application Model. The basic building blocks of this model are actions and applications. The previous articles contain information for portal builders on how to create actions and applications using the built-in method. This article describes the way for developers to create a custom action that is able to execute custom initialization code or behave differently than the built-in ones.

Applications can be viewed as the code that executes when the page renders the appropriate content (e.g. an Edit page for an Article). However this article is about actions that are also classes, but the execution of an action takes place well before the application. An action code is executed when an action control (e.g. an ActionLinkButton or ActionMenu) displays the action (clicking on the link will navigate to the application). The initialization code may set the action Forbidden (grey and unclickable) or even hide it. This is the place for executing custom permission checks or parameter handling.

Why create a custom action? ASP.NET or JavaScript provide a lots of different ways to achieve these kind of scenarios. What we offer with our action framework is a whole architecture for handling and displaying actions. You will not have to worry about generating the action URL (e.g. adding the back url), and you will be able to manage and display your custom actions alongside with the common built-in actions (check the ActionLinkButton or ActionMenu controls for more details).

Upgrade from previous versions

- Before sensenet version 6.1.2, there was a possibility to configure the actions in the web.config. 
- During the upgrade from previous versions you may remove all the action and scenario type registrations 
- from the unity section of the web.config and application configuration files, they are not needed anymore.

Action types

Default action type

If the developer did not provide a custom action type name for an application, the default action will be instantiated. In sensenet the built-in default action type is UrlAction. This can be changed using a Web.config setting.

<add key="DefaultActionType" value="MyCustomDefaultAction" />
- Please note that this setting changes all action instantiation where there is no specific action name specified on the application. 
- Use this feature only if you want to make a global change in the action framework behavior, e.g. how URLs are generated.

Steps for creating a URL action

In this section we create a custom action for the Edit application of the Article content type.

1. Create a new class

When you create a simple custom action, it should inherit the UrlAction class.

public class ArticleEditAction : UrlAction

2. Implement initialization

If you want to attach custom initialization logic to the action, override the Initialize method (but do not forget to call the base Initialize method). In our case we will check that the user is browsing the site from the localhost URL. If that is the case, we disable the Edit action.

- Please note that this check mechanism is related only to the action. 
- You still need to perform this check on the application page in case of somebody tries to execute the app by writing the action name manually into the url.
public class ArticleEditAction : UrlAction
    public override void Initialize(
        Content context, 
        string backUri, 
        Application application, 
        object parameters)
        base.Initialize(context, backUri, application, parameters);
        //if we browse the site from 'localhost', disable the action
        //(only allow editing from the admin site)
        if (PortalContext.Current.RequestedUri.Host == "localhost")
            this.Forbidden = true;

3. Display the action

To use this newly created action codebehind you need to do the following:

Now check the http://localhost/NewsDemo. The Manage Content action menus will contain the Edit action but it will be disabled because of our initialization logic.

Custom Edit action

Steps for creating a Client action

In this section we create a simple Hello world client action.

1. Create a new class

When developing a custom Client action you need to inherit the ClientAction class.

public class HelloClientAction : ClientAction

2. Set JavaScript code

In more advanced scenarios you may implement the JavaScript logic in a separate js file and just provide the name of the method to call in the Methodname property of your client action class. But for now we will provide the whole javascript code in our sample class by overriding the Callback property. This is responsible for providing the whole javascript for the GUI.

public class HelloClientAction : ClientAction
    public override string Callback
            return "alert('Hello!');return false;";
            base.Callback = value;
Redirecting after a client-side operation - from version 6.3

In case you need to redirect a user to another page after the operation is complete - e.g. because you need to refresh the page, or because the content in question no longer exists - you have to develop a custom JavaScript code for achieving that (e.g. you can use the usual ‘location = targetUr;’ approach). For example the Delete or Move actions redirect to the parent after their operation completes. There are cases however when the parent is not sufficient - e.g. because the action was executed from a custom view that was bound to a different content than the current context. In these cases you can provide the following parameter to the client action that states that the action should redirect the user to the originally given back url.

Inline code:

var action = ActionFramework.GetAction("MoveTo", content, new { RedirectToBackUrl = true });

Declarative style:

<sn:ActionLinkButton runat='server' NodePath='<%# Eval("Path") %>' ActionName='Delete' ParameterString="RedirectToBackUrl=true" >Delete content</sn:ActionLinkButton>

The JavaScript code for the action should take this value into account and redirect the user to the appropriate back url, as you can see in the source code of the MoveTo action.

"location=" + (this.RedirectToBackUrl 
    ? string.Concat("\'", HttpUtility.UrlDecode(this.BackUri), "\'") 
    : "SN.Util.GetParentUrlForPath(path)") + ";"

3. Display the action

In this sample we do not use any predefined application as in the previous section. To provide a simple client action you need to create a content of the type Application. Please follow the steps below:

Now check the http://localhost/NewsDemo This link works only if you have a live demo install on your localhost! (Don’t forget! Some feature needs authentication and/or admin rights!) page. The Manage Content action menus will contain the newly created Hello action that displays a client-side message box.

Steps for creating a custom Open Picker action

In this section we modify the behavior of the Move to… action to open the Content Picker at the current workspace root.

1. Create a new class

When developing a custom Open Picker action you need to inherit the OpenPickerAction class. In our case we want to customize the Move to… action, so we inherit the MoveToAction class that is a picker action itself.

public class MoveToWorkspaceAction : MoveToAction

2. Set Open Picker JavaScript code

We only want to customize the way the Content Picker opens when the user clicks on the Move to action. To achieve this you only have to override the GetOpenContentPickerScript method of the base class.

The source code below is only the extension of the base class behavior. We added only the lines for providing the tree roots, everything else is copied from the base class.

public class MoveToWorkspaceAction : MoveToAction
    protected override string GetOpenContentPickerScript()
        if (Content == null || this.Forbidden)
            return string.Empty;
        var openParams = string.Format(
            "MultiSelectMode: '{0}', callBack: {1}",
        if (!string.IsNullOrEmpty(this.DefaultPath))
            openParams += string.Format(", DefaultPath: '{0}'", this.DefaultPath);
        //find the workspace of the current content and add it as a tree root
        var gen = Content.ContentHandler as GenericContent;
        if (gen != null && gen.Workspace != null)
            openParams += string.Format(", TreeRoots: ['{0}', '/Root']", gen.WorkspacePath);
        return string.Format(
            "if ($(this).hasClass('sn-disabled')) return false; SN.PickerApplication.open({0});", 

You may freely change the code above to customize the DefaultPath or any other property of the open picker Javascript method too.

3. Display the action

In this sample we want to change the behavior of the Move to action. To achieve this, you need to set your custom class name as the Action type name of the MoveTo application. Please follow the steps below:

Now check one of the document libraries on the portal. The Move to action (on any document) will be opened with the workspace root. If you want to move the document elsewhere,you may select the Root option from the dropdown at the top of the Content Picker.

Open picker

Is something missing? See something that needs fixing? Propose a change here.