forked from ServiceStack/ServiceStack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathValidationFeature.cs
More file actions
90 lines (80 loc) · 3.3 KB
/
ValidationFeature.cs
File metadata and controls
90 lines (80 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using System;
using System.Linq;
using System.Reflection;
using Funq;
using ServiceStack.FluentValidation;
using ServiceStack.FluentValidation.Results;
using ServiceStack.Logging;
using ServiceStack.ServiceHost;
using ServiceStack.WebHost.Endpoints;
using ServiceStack.Text;
namespace ServiceStack.ServiceInterface.Validation
{
public class ValidationFeature : IPlugin
{
private static readonly ILog Log = LogManager.GetLogger(typeof(ValidationFeature));
public Func<ValidationResult, object, object> ErrorResponseFilter { get; set; }
/// <summary>
/// Activate the validation mechanism, so every request DTO with an existing validator
/// will be validated.
/// </summary>
/// <param name="appHost">The app host</param>
public void Register(IAppHost appHost)
{
if(!appHost.RequestFilters.Contains(ValidationFilters.RequestFilter))
appHost.RequestFilters.Add(ValidationFilters.RequestFilter);
}
/// <summary>
/// Override to provide additional/less context about the Service Exception.
/// By default the request is serialized and appended to the ResponseStatus StackTrace.
/// </summary>
public virtual string GetRequestErrorBody(object request)
{
var requestString = "";
try
{
requestString = TypeSerializer.SerializeToString(request);
}
catch /*(Exception ignoreSerializationException)*/
{
//Serializing request successfully is not critical and only provides added error info
}
return string.Format("[{0}: {1}]:\n[REQUEST: {2}]", GetType().Name, DateTime.UtcNow, requestString);
}
}
public static class ValidationExtensions
{
/// <summary>
/// Auto-scans the provided assemblies for a <see cref="IValidator"/>
/// and registers it in the provided IoC container.
/// </summary>
/// <param name="container">The IoC container</param>
/// <param name="assemblies">The assemblies to scan for a validator</param>
public static void RegisterValidators(this Container container, params Assembly[] assemblies)
{
RegisterValidators(container, ReuseScope.None, assemblies);
}
public static void RegisterValidators(this Container container, ReuseScope scope, params Assembly[] assemblies)
{
foreach (var assembly in assemblies)
{
foreach (var validator in assembly.GetTypes()
.Where(t => t.IsOrHasGenericInterfaceTypeOf(typeof(IValidator<>))))
{
RegisterValidator(container, validator, scope);
}
}
}
public static void RegisterValidator(this Container container, Type validator, ReuseScope scope=ReuseScope.None)
{
var baseType = validator.BaseType;
while (!baseType.IsGenericType)
{
baseType = baseType.BaseType;
}
var dtoType = baseType.GetGenericArguments()[0];
var validatorType = typeof(IValidator<>).MakeGenericType(dtoType);
container.RegisterAutoWiredType(validator, validatorType, scope);
}
}
}