mirror of https://github.com/abpframework/abp.git
6 changed files with 179 additions and 15 deletions
@ -0,0 +1,37 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.ModelBinding |
||||
|
{ |
||||
|
public static class ExtraPropertyBindingHelper |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// modelName is a string like "UserInfo.ExtraProperties[SocialSecurityNumber]"
|
||||
|
/// This method returns "SocialSecurityNumber" for this example. */
|
||||
|
/// </summary>
|
||||
|
public static string ExtractExtraPropertyName(string modelName) |
||||
|
{ |
||||
|
var index = modelName.IndexOf(".ExtraProperties[", StringComparison.Ordinal); |
||||
|
if (index < 0) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return modelName.Substring(index + 17, modelName.Length - index - 18); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// modelName is a string like "UserInfo.ExtraProperties[SocialSecurityNumber]"
|
||||
|
/// This method returns "UserInfo" for this example.
|
||||
|
/// </summary>
|
||||
|
public static string ExtractContainerName(string modelName) |
||||
|
{ |
||||
|
var index = modelName.IndexOf(".ExtraProperties[", StringComparison.Ordinal); |
||||
|
if (index < 0) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return modelName.Left(index); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; |
||||
|
using Volo.Abp.ObjectExtending; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.ModelBinding.Metadata |
||||
|
{ |
||||
|
public class AbpExtraPropertyValidationMetadataProvider : IValidationMetadataProvider |
||||
|
{ |
||||
|
public static AsyncLocal<ExtraPropertyModelInfo> CurrentModeInfo { get; } = new AsyncLocal<ExtraPropertyModelInfo>(); |
||||
|
|
||||
|
public void CreateValidationMetadata(ValidationMetadataProviderContext context) |
||||
|
{ |
||||
|
if (CurrentModeInfo.Value == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var currentModel = CurrentModeInfo.Value; |
||||
|
|
||||
|
CurrentModeInfo.Value = null; |
||||
|
|
||||
|
var propertyInfo = ObjectExtensionManager.Instance.GetPropertyOrNull( |
||||
|
currentModel.ExtensibleObjectType, |
||||
|
currentModel.PropertyName |
||||
|
); |
||||
|
|
||||
|
if (propertyInfo == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
foreach (var validationAttribute in propertyInfo.ValidationAttributes) |
||||
|
{ |
||||
|
context.ValidationMetadata.ValidatorMetadata.Add(validationAttribute); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class ExtraPropertyModelInfo |
||||
|
{ |
||||
|
public Type ExtensibleObjectType { get; } |
||||
|
public string PropertyName { get; } |
||||
|
|
||||
|
public ExtraPropertyModelInfo( |
||||
|
Type extensibleObjectType, |
||||
|
string propertyName) |
||||
|
{ |
||||
|
ExtensibleObjectType = extensibleObjectType; |
||||
|
PropertyName = propertyName; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,72 @@ |
|||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using System.Linq.Expressions; |
||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures; |
||||
|
using Volo.Abp.AspNetCore.Mvc.ModelBinding.Metadata; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.ModelBinding |
||||
|
{ |
||||
|
[Dependency(ReplaceServices = true)] |
||||
|
public class AbpModelExpressionProvider : IModelExpressionProvider, ITransientDependency |
||||
|
{ |
||||
|
private readonly ModelExpressionProvider _modelExpressionProvider; |
||||
|
|
||||
|
public AbpModelExpressionProvider(ModelExpressionProvider modelExpressionProvider) |
||||
|
{ |
||||
|
_modelExpressionProvider = modelExpressionProvider; |
||||
|
} |
||||
|
|
||||
|
public ModelExpression CreateModelExpression<TModel, TValue>( |
||||
|
ViewDataDictionary<TModel> viewData, |
||||
|
Expression<Func<TModel, TValue>> expression) |
||||
|
{ |
||||
|
var result = _modelExpressionProvider.CreateModelExpression( |
||||
|
viewData, |
||||
|
expression |
||||
|
); |
||||
|
|
||||
|
if (result.ModelExplorer.Container == null) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
var extraPropertyName = ExtraPropertyBindingHelper.ExtractExtraPropertyName(result.Name); |
||||
|
if (extraPropertyName == null) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
var containerName = ExtraPropertyBindingHelper.ExtractContainerName(result.Name); |
||||
|
if (containerName == null) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
var containerModelExpolorer = result |
||||
|
.ModelExplorer |
||||
|
.Container |
||||
|
.Properties |
||||
|
.FirstOrDefault(p => p.Metadata.Name == containerName); |
||||
|
|
||||
|
if (containerModelExpolorer == null) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
if (!containerModelExpolorer.ModelType.IsAssignableTo<IHasExtraProperties>()) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
AbpExtraPropertyValidationMetadataProvider.CurrentModeInfo.Value |
||||
|
= new AbpExtraPropertyValidationMetadataProvider.ExtraPropertyModelInfo( |
||||
|
containerModelExpolorer.ModelType, |
||||
|
extraPropertyName |
||||
|
); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue