Skip to content

Showing WebAPI Validation Errors with ExtJS 6

Updated: at 02:12 PM

Let’s say you use model validation with ASP.NET WebAPI and you are serving a client side application written in Sencha’s ExtJS.  To show those errors like this:

image

You need to add a ValidationActionFilter to your startup code as follows:

using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using CodeCampSV;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;

namespace WebAPI.App_Start { public class SenchaError { public bool success { get; set; } public string message { get; set; } }

public class ErrorObject
{
    public string PropertyName { get; set; }
    public string Message { get; set; }
}


public class ValidationActionFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext context)
    {
        var errorList = new List();
        string errorString = "";
        var modelState = context.ModelState;
        if (!modelState.IsValid)
        {
            var errors = new JObject();
            foreach (var key in modelState.Keys)
            {
                var state = modelState[key];
                if (state.Errors.Any())
                {
                    errors[key] = state.Errors.First().ErrorMessage;
                    errorString = state.Errors.First().ErrorMessage;
                    errorList.Add(new ErrorObject()
                    {
                        Message = errorString,
                        PropertyName = key
                    });
                }
            }
            context.Response =
                context.Request.CreateResponse(
                    HttpStatusCode.NotAcceptable, new SenchaError()
                    {
                        message = JsonConvert.SerializeObject(errorList),
                        success = false
                    });

        }
    } 
}

}

// POST: api/RegSvcc
        public HttpResponseMessage Post(RegistrationData registrationData)
        {
            // do work
            return Request.CreateResponse
                (HttpStatusCode.OK);
        }

    public class RegistrationData
    {
        [MaxLength(20)]
        [MinLength(5)]
        [DisplayName("Confirm Password")]
        [Required]
        public string FirstName{ get; set; }

        [MaxLength(20)]
        [MinLength(5)]
        [DisplayName("Confirm Password")]
        [Required]
        public string LastName{ get; set; }
    }


And then, you can have your ExtJS code do something like the following to display the error:

        Ext.Ajax.request({
            method: 'POST',
            url: '/api/RegSvcc',
            params: 
                City: 'hartsdale',
                State: 'ny',
                UserZipCode: '10530'
            },
        success: function (data) {
            // do something good
        },

        failure: function (result,aa,bb) {
            var errorList = Ext.decode(Ext.decode(result.responseText).message);
            var errorTpl = new Ext.XTemplate(
                '<tpl for=".">',
                '<ul class="thumb-wrap">',
                '<li><b>{Message}</b></li>',
                '</ul>',
                '</tpl>'
            );
            var htmlError = errorTpl.apply(errorList);
            Ext.Msg.alert('Problems Found (Please Correct)',htmlError);
        }
    });
Ext.application({
    name: 'Fiddle',
    launch: function() {
    data = [{
        Message: 'The Company field is required'
    }, {
        Message: 'Occupation required'
    }, {
        Message: 'Password Does Not Match Confirmation'
    }];
    var errorTpl = new Ext.XTemplate('<tpl for=".">', '<ul class="thumb-wrap">', '<li><b>{Message}</b></li>', '</ul>', '</tpl>');
    var htmlError = errorTpl.apply(data);
    Ext.Msg.alert('Problems Found (please fix)', htmlError);
}

});

And you can run it yourself at the Sencha Fiddle:

HTH's

Check out the ORM (Object Relational Mapper) PRISMA. The database access method I use in all my projects