Features

Unobtrusive Validation

Unobtrusive Validation

This view shows the unobtrusive validation in Razor Pages.

Features

Description

Steps for implementing unobtrusive validation in Razor Pages:

  1. Add handler OnPostGridUpdateUserInfo to page model for editing.
  2. Add token @Html.AntiForgeryToken() in Razor page view.
  3. Add a partial view with an IEnumerable model. This is required as a workaround because currently, our MVC Controls support IEnumerable model only and Razor Pages model is a PageModel.
  4. Initialize the FlexGrid control in the partial view using <c1-flex-grid></c1-flex-grid> tag.
  5. Render partial view in this page and pass an IEnumerable model to partial view.

The columns have the following validations:

  • Name: Required. Alphanumeric and contains 4 to 10 characters.
  • Industry: Required.
  • Country: Required.
  • Phone: Required. 8 to 11 characters.
  • Email: Required. Valid e-mail address.
  • Birthdate: Required.

@page
@model UnobtrusiveValidationModel
@{

}

@section Scripts{
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
}

@Html.AntiForgeryToken()

@Html.Partial("UnobtrusiveValidationPartial", UnobtrusiveValidationModel.Users)

@section Summary{
    This view shows the unobtrusive validation in Razor Pages.
}

@section Description{
    <p>
        Steps for implementing unobtrusive validation in Razor Pages:
    </p>
    <ol>
        <li>Add handler <b>OnPostGridUpdateUserInfo</b> to page model for editing.</li>
        <li>Add token <b>@@Html.AntiForgeryToken()</b> in Razor page view.</li>
        <li>
            Add a partial view with an IEnumerable model. This is required as a workaround because currently, our MVC Controls 
            support IEnumerable model only and Razor Pages model is a PageModel. 
        </li>
        <li>Initialize the FlexGrid control in the partial view using <b>&lt;c1-flex-grid&gt;&lt;/c1-flex-grid&gt;</b> tag.</li>
        <li>Render partial view in this page and pass an IEnumerable model to partial view.</li>
    </ol>
    <p>
        The columns have the following validations:
        <ul>
            <li><b>Name:</b> Required. Alphanumeric and contains 4 to 10 characters.</li>
            <li><b>Industry:</b> Required.</li>
            <li><b>Country:</b> Required.</li>
            <li><b>Phone:</b> Required. 8 to 11 characters.</li>
            <li><b>Email:</b> Required. Valid e-mail address.</li>
            <li><b>Birthdate:</b> Required.</li>
        </ul>
    </p>
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesExplorer.Models;
using C1.Web.Mvc;
using C1.Web.Mvc.Serialization;

namespace RazorPagesExplorer.Pages
{
    public class UnobtrusiveValidationModel : PageModel
    {
        public static readonly List<UserInfo> Users = UsersData.Users;

        public void OnGet()
        {
        }

        public ActionResult OnPostGridUpdateUserInfo([C1JsonRequest]CollectionViewEditRequest<UserInfo> requestData)
        {
            return JsonConvertHelper.C1Json(CollectionViewHelper.Edit<UserInfo>(requestData, item =>
            {
                string error = string.Empty;
                bool success = true;
                try
                {
                    var resultItem = Users.Find(u => u.Id == item.Id);
                    var index = Users.IndexOf(resultItem);
                    Users.Remove(resultItem);
                    Users.Insert(index, item);
                }
                catch (Exception e)
                {
                    error = e.Message;
                    success = false;
                }
                return new CollectionViewItemResult<UserInfo>
                {
                    Error = error,
                    Success = success,
                    Data = item
                };
            }, () => Users));
        }

        public ActionResult OnPostGridCreateUserInfo([C1JsonRequest]CollectionViewEditRequest<UserInfo> requestData)
        {
            return JsonConvertHelper.C1Json(CollectionViewHelper.Edit<UserInfo>(requestData, item =>
            {
                string error = string.Empty;
                bool success = true;
                try
                {
                    Users.Add(item);
                    item.Id = Users.Max(u => u.Id) + 1;
                }
                catch (Exception e)
                {
                    error = e.Message;
                    success = false;
                }
                return new CollectionViewItemResult<UserInfo>
                {
                    Error = error,
                    Success = success,
                    Data = item
                };
            }, () => Users));
        }

        public ActionResult OnPostGridDeleteUserInfo([C1JsonRequest]CollectionViewEditRequest<UserInfo> requestData)
        {
            return JsonConvertHelper.C1Json(CollectionViewHelper.Edit<UserInfo>(requestData, item =>
            {
                string error = string.Empty;
                bool success = true;
                try
                {
                    var resultItem = Users.Find(u => u.Id == item.Id);
                    Users.Remove(resultItem);
                }
                catch (Exception e)
                {
                    error = e.Message;
                    success = false;
                }
                return new CollectionViewItemResult<UserInfo>
                {
                    Error = error,
                    Success = success,
                    Data = item
                };
            }, () => Users));
        }
    }
}
using System;
using System.ComponentModel.DataAnnotations;

namespace RazorPagesExplorer.Models
{
    public class UserInfo
    {
        public UserInfo()
        {
            Birthdate = DateTime.Now;
        }
        public int Id { get; set; }

        [Required]
        [RegularExpression(pattern: "^[a-zA-Z0-9]{4,10}$", ErrorMessage = "The username must be alphanumeric and contains 4 to 10 characters.")]
        public string Name { get; set; }

        [Required]
        [EmailAddress]
        public string Email { get; set; }

        [Required]
        [MinLength(8)]
        [MaxLength(11)]
        public string Phone { get; set; }

        [Required]
        public string Country { get; set; }

        [Required]
        public string Industry { get; set; }

        [Required]
        public DateTime Birthdate { get; set; }
    }
}
@model List<UserInfo>

<c1-flex-grid id="flexGrid" auto-generate-columns="false" allow-add-new="true" allow-delete="true" height="400px">
    <c1-flex-grid-column binding="Id" is-read-only="true"></c1-flex-grid-column>
    <c1-flex-grid-column binding="Name"></c1-flex-grid-column>
    <c1-flex-grid-column binding="Email"></c1-flex-grid-column>
    <c1-flex-grid-column binding="Phone"></c1-flex-grid-column>
    <c1-flex-grid-column binding="Country"></c1-flex-grid-column>
    <c1-flex-grid-column binding="Industry"></c1-flex-grid-column>
    <c1-flex-grid-column binding="Birthdate" format="M/d/yyyy"></c1-flex-grid-column>
    <c1-items-source source-collection="@Model"
                     create-action-url="@Url.Page("UnobtrusiveValidation", "GridCreateUserInfo")"
                     delete-action-url="@Url.Page("UnobtrusiveValidation", "GridDeleteUserInfo")"
                     update-action-url="@Url.Page("UnobtrusiveValidation", "GridUpdateUserInfo")">
    </c1-items-source>
</c1-flex-grid>