Table of Contents

Create User

For visitors to create a user and activate it by email

The Users - Create user app renders a frontend account‑creation form and sends a confirmation email with a link to complete activation (typically on a Set password page). It supports both anonymous self‑sign‑up and authenticated administrators creating users on behalf of others.

When the app runs it will render a create account form. On submit, the module either renders a result in the same template or redirects to the configured Redirect after submission page.

The app has two distinct user creation flows:

  1. Anonymous self‑sign‑up: No one is logged in. The new user’s CustomerNumber defaults to empty. The user is redirected (if configured) and receives an approval email with a link to the Set password page to complete activation.
  2. Authenticated administrator creates a user: A user is logged in (including impersonation). If a CustomerNumber is not posted explicitly, the new user inherits the current user’s CustomerNumber. If a CustomerNumber is posted, it must be one the current user is allowed to impersonate; otherwise the result is InvalidCustomerNumber. The admin stays logged in; the new user completes activation via the email link.

Paragraph app settings

Add this app to a paragraph to access the app settings - they allow you to configure how the app behaves.

Create user

From the paragraph app you have the following settings:

  • Email
    • Sender name, Sender email, Email subject
  • Pages
    • Page to login (builds Model.LoginLink).
    • Page to set password (builds Model.CreatePasswordLink used in the email)
  • Redirects
    • Redirect after submission: where to send the browser after a successful post
    • Redirect after approval: where to send anonymous users after completing activation (from the email)
  • Templates
    • Create user template: choose a Razor template from /Templates/Users/UserCreate/Create
    • Email template: choose a Razor template from /Templates/Users/UserCreate/ConfirmationEmail
  • User groups
    • Auto-assign customer number: Controls how the customer number is assigned to a user.
      • Do not auto-assign customer number: no automatic customer number assignment is performed
      • Get customer number from input field: customer number is taken from a field in the user creation form
      • Get customer number from group with same email domain: the system finds an existing group with the same email domain and uses its customer number
      • Inherit customer number from the logged in user: the invited user inherits the customer number of the currently logged-in user
    • Add user to group based on customer number: Automatically adds the created user to user groups / accounts based on customer number.
    • Groups for new users (always added)
    • Groups the new user can be added to (optional, you render the selection UI)

Templates

This app uses two templates which should be located in the following locations:

  • Create template: /Templates/Users/UserCreate/Create
  • Confirmation email: /Templates/Users/UserCreate/ConfirmationEmail

Both templates should inherit the ViewModelTemplate<UserCreateViewModel> and import the Dynamicweb.Users.Frontend.UserCreate namespace. You can see examples for both templates below.

Example: Create User

@inherits ViewModelTemplate<Dynamicweb.Users.Frontend.UserCreate.UserCreateViewModel>
@using Dynamicweb
@using Dynamicweb.Rendering
@using Dynamicweb.Users.Frontend.UserCreate

@{
    var action = Model.GetCreateUserLink(Pageview.Page.ID);
    var customers = Model.GetImpersonatableCustomerNumbers(); // only non-empty when an authenticated creator can impersonate
}

<form method="post" action="@action">
  <div class="form-control">
    <label for="Email">Email</label>
    <input type="email" id="Email" name="Email" value="@Model.Email" required />
  </div>

  <div class="form-control">
    <label for="UserName">Username</label>
    <input type="text" id="UserName" name="UserName" value="@Model.UserName" placeholder="(defaults to your email)" />
  </div>

  <!-- Optional: let admins choose a customer number for the new user -->
  @if (customers?.Any() == true) {
    <div class="form-control">
      <label for="CustomerNumber">Customer</label>
      <select id="CustomerNumber" name="CustomerNumber">
        <option value="">(Same as my account)</option>
        @foreach (var c in customers) { <option>@c</option> }
      </select>
    </div>
  }

  <!-- Optional: render selectable groups -->
  @if (Model.SelectableUserGroups?.Any() == true) {
    <fieldset>
      <legend>Groups</legend>
      @foreach (var g in Model.SelectableUserGroups) {
        <label><input type="checkbox" name="UserGroupIds" value="@g.Id" /> @g.Name</label>
      }
    </fieldset>
  }

  <button type="submit">Create account</button>

  <!-- Show a result if present -->
  @if (Model.Result != Dynamicweb.Users.Frontend.UserCreate.UserCreateResultType.None) {
    <p class="form-message">@Translate(Model.Result.ToString())</p>
  }
</form>

<p class="mt-4">Already have an account? <a href="@Model.LoginLink">Sign in</a></p>

Example: Email Confirmation

Place a .cshtml file in /Templates/Users/UserCreate/ConfirmationEmail and inherit the ViewModelTemplate<UserCreateViewModel>. It exposes an ApprovalLink property, which points to your Set password page and includes a recovery token.

@inherits ViewModelTemplate<Dynamicweb.Users.Frontend.UserCreate.UserCreateViewModel>
@using Dynamicweb.Rendering
@using Dynamicweb.Users.Frontend.UserCreate

<!doctype html>
<html>
  <body>
    <h1>Welcome@(!string.IsNullOrWhiteSpace(Model.UserName) ? $", {Model.UserName}" : "")</h1>
    <p>Please confirm your email address to activate your account.</p>
    <p>
      <a href="@Model.ApprovalLink" style="display:inline-block;padding:12px 18px;text-decoration:none;">Confirm &amp; Set Password</a>
    </p>
    <p>If the button doesn’t work, copy and paste this link into your browser:</p>
    <p>@Model.ApprovalLink</p>
  </body>
</html>

Handling results in your template

UserCreateResultType covers all outcomes you may want to translate or customize, including success and typical errors. You can switch on Model.Result:

@switch (Model.Result)
{
    case Dynamicweb.Users.Frontend.UserCreate.UserCreateResultType.None:
    // no message
    break;

    case Dynamicweb.Users.Frontend.UserCreate.UserCreateResultType.EmailAlreadyExists:
    <div class="error">An account with this email already exists.</div>
    break;

    case Dynamicweb.Users.Frontend.UserCreate.UserCreateResultType.InvalidEmail:
    <div class="error">Please enter a valid email address.</div>
    break;

    case Dynamicweb.Users.Frontend.UserCreate.UserCreateResultType.InvalidPasswordComplexity:
    <div class="error">Password does not meet the required complexity.</div>
    break;

    case Dynamicweb.Users.Frontend.UserCreate.UserCreateResultType.InvalidPasswordLength:
    <div class="error">Password length is invalid.</div>
    break;

    case Dynamicweb.Users.Frontend.UserCreate.UserCreateResultType.MismatchedPasswords:
    <div class="error">Passwords do not match.</div>
    break;

    case Dynamicweb.Users.Frontend.UserCreate.UserCreateResultType.UserNameAlreadyExists:
    <div class="error">This username is taken.</div>
    break;

    case Dynamicweb.Users.Frontend.UserCreate.UserCreateResultType.UserNameIsEmpty:
    <div class="error">Please choose a username.</div>
    break;

    case Dynamicweb.Users.Frontend.UserCreate.UserCreateResultType.InvalidCustomerNumber:
    <div class="error">You can’t assign that customer number.</div>
    break;
}
To top