You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iot/projects/Infrastructure/Web/DataAnnotations/MustBeTrueAttribute.cs

88 lines
3.0 KiB

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using Microsoft.AspNetCore.Mvc.DataAnnotations;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
namespace Infrastructure.Web.DataAnnotations
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class MustBeTrueAttribute : ValidationAttribute, IClientModelValidator
{
private IStringLocalizer _stringLocalizer;
private bool _checkedForLocalizer;
public override bool IsValid(object value)
{
return value != null && (bool)value;
}
public void AddValidation(ClientModelValidationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
MergeAttribute(context.Attributes, "data-val", "true");
CheckForLocalizer(context);
var errorMessage = GetErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-mustbetrue", errorMessage);
}
private string GetErrorMessage(string displayName)
{
if (_stringLocalizer != null &&
!string.IsNullOrEmpty(ErrorMessage) &&
string.IsNullOrEmpty(ErrorMessageResourceName) &&
ErrorMessageResourceType == null)
{
return _stringLocalizer[ErrorMessage, displayName];
}
return FormatErrorMessage(displayName);
}
private void CheckForLocalizer(ClientModelValidationContext context)
{
if (!_checkedForLocalizer)
{
_checkedForLocalizer = true;
var services = context.ActionContext.HttpContext.RequestServices;
var options = services.GetRequiredService<IOptions<MvcDataAnnotationsLocalizationOptions>>();
var factory = services.GetService<IStringLocalizerFactory>();
var provider = options.Value.DataAnnotationLocalizerProvider;
if (factory != null && provider != null)
{
_stringLocalizer = provider(
context.ModelMetadata.ContainerType ?? context.ModelMetadata.ModelType,
factory);
}
}
}
private bool MergeAttribute(
IDictionary<string, string> attributes,
string key,
string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
public override string FormatErrorMessage(string name)
{
return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name);
}
}
}