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