Last active
January 4, 2016 02:39
-
-
Save scottmcarthur/8557022 to your computer and use it in GitHub Desktop.
Deferred Validation Example. This example uses a custom validator plugin that is a substitute for the ServiceStack standard ValidationFeature plugin. When a custom attribute of `MyRoleAttribute` is applied to the request DTO, then the validation will not be run, allowing the MyRoleAttribute to run the validation checks once it has completed. Req…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using ServiceStack.ServiceInterface; | |
using ServiceStack.ServiceHost; | |
using ServiceStack.WebHost.Endpoints; | |
using ServiceStack.Common.Web; | |
using ServiceStack.Logging; | |
using ServiceStack.FluentValidation.Results; | |
using ServiceStack.Text; | |
using ServiceStack.ServiceInterface.Validation; | |
namespace Testv3 | |
{ | |
class MainClass | |
{ | |
public static void Main() | |
{ | |
// Very basic console host | |
var appHost = new AppHost(); | |
appHost.Init(); | |
appHost.Start("http://*:8082/"); | |
Console.ReadKey(); | |
} | |
} | |
public class AppHost : AppHostHttpListenerBase | |
{ | |
public AppHost() : base("Test Service", typeof(TestApp).Assembly) {} | |
public override void Configure(Funq.Container container) | |
{ | |
// Configure to use our custom Validation Feature (MyValidationFeature) | |
Plugins.Add(new MyValidationFeature()); | |
} | |
} | |
public static class TestApp | |
{ | |
#region DTOs | |
[Route("/HaveChristmas", "GET")] | |
[MyRole("Santa","Rudolph","MrsClaus")] | |
public class HaveChristmasRequest {} | |
[Route("/EasterEgg", "GET")] | |
[MyRole("Easterbunny")] | |
public class GetEasterEggRequest {} | |
[Route("/EinsteinsBirthday", "GET")] | |
public class EinsteinsBirthdayRequest {} | |
#endregion | |
#region Service | |
public class TestController : Service | |
{ | |
// Roles: Santa, Rudolph, MrsClaus | |
public object Get(HaveChristmasRequest request) | |
{ | |
return new { Presents = "Toy Car, Teddy Bear, Xbox" }; | |
} | |
// Roles: Easterbunny | |
public object Get(GetEasterEggRequest request) | |
{ | |
return new { EasterEgg = "Chocolate" }; | |
} | |
// No roles required | |
public object Get(EinsteinsBirthdayRequest request) | |
{ | |
return new { Birthdate = new DateTime(1879, 3, 14) }; | |
} | |
} | |
#endregion | |
} | |
public class MyRoleAttribute : RequestFilterAttribute | |
{ | |
readonly string[] _roles; | |
public MyRoleAttribute(params string[] roles) | |
{ | |
_roles = roles; | |
} | |
#region implemented abstract members of RequestFilterAttribute | |
public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto) | |
{ | |
Console.WriteLine("Checking for required role"); | |
// Replace with your actual role checking code | |
var role = req.GetParam("role"); | |
if(role == null || !_roles.Contains(role)) | |
throw HttpError.Unauthorized("You don't have the correct role"); | |
Console.WriteLine("Has required role"); | |
// Perform the deferred validation | |
Console.WriteLine("Running Validation"); | |
ValidationFilters.RequestFilter(req, res, requestDto); | |
} | |
#endregion | |
} | |
public class MyValidationFeature : IPlugin | |
{ | |
static readonly ILog Log = LogManager.GetLogger(typeof(MyValidationFeature)); | |
public Func<ValidationResult, object, object> ErrorResponseFilter { get; set; } | |
public void Register(IAppHost appHost) | |
{ | |
// Registers to use your custom validation filter instead of the standard one. | |
if(!appHost.RequestFilters.Contains(MyValidationFilters.RequestFilter)) | |
appHost.RequestFilters.Add(MyValidationFilters.RequestFilter); | |
} | |
} | |
public static class MyValidationFilters | |
{ | |
public static void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto) | |
{ | |
// Determine if the Request DTO type has a MyRoleAttribute. | |
// If it does not, run the validation normally. Otherwise defer doing that, it will happen after MyRoleAttribute. | |
if(!requestDto.GetType().HasAttribute<MyRoleAttribute>()){ | |
Console.WriteLine("Running Validation"); | |
ValidationFilters.RequestFilter(req, res, requestDto); | |
return; | |
} | |
Console.WriteLine("Deferring Validation until Roles are checked"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment