Former-commit-id: 78221869d31957ce965c6e0495f56cb576c05c94
Former-commit-id: 48264889ca4be62fa521d6371da863af3ad65afc
TSXN
wanggang 5 years ago
parent ca07c9ac11
commit 9a3f38e2ef

@ -1,5 +1,4 @@
using Infrastructure.Resources; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
@ -56,7 +55,7 @@ namespace Infrastructure.Extensions
return new SelectList(values, "Id", "Name", selectedValue); return new SelectList(values, "Id", "Name", selectedValue);
} }
public static object CreateJson(this ControllerBase controller, DefaultModelMetadata metadata) public static object CreateJson(this ControllerBase controller, DefaultModelMetadata metadata, DefaultModelMetadata parent = null)
{ {
if (metadata is null) if (metadata is null)
{ {
@ -69,6 +68,7 @@ namespace Infrastructure.Extensions
dynamic json = new ExpandoObject(); dynamic json = new ExpandoObject();
var dictionary = (IDictionary<string, object>)json; var dictionary = (IDictionary<string, object>)json;
//type //type
if (metadata.IsComplexType && metadata.IsCollectionType) if (metadata.IsComplexType && metadata.IsCollectionType)
{ {
json.type = "array"; json.type = "array";
@ -112,13 +112,6 @@ namespace Infrastructure.Extensions
{ {
json.title = metadata.DisplayName; json.title = metadata.DisplayName;
} }
//if (metadata.IsRequired)
//{
// if (metadata.ModelType != typeof(bool))
// {
// json.required = true;
// }
//}
foreach (var attribute in metadata.Attributes.Attributes) foreach (var attribute in metadata.Attributes.Attributes)
{ {
if (attribute is DescriptionAttribute descriptionAttribute) if (attribute is DescriptionAttribute descriptionAttribute)
@ -127,15 +120,9 @@ namespace Infrastructure.Extensions
} }
else if (attribute is RequiredAttribute requiredAttribute) else if (attribute is RequiredAttribute requiredAttribute)
{ {
var localizedString = localizer.GetString(nameof(RequiredAttribute));
var message = requiredAttribute.ErrorMessage;
if (!localizedString.ResourceNotFound)
{
message = string.Format(localizedString.Value, metadata.DisplayName);
}
json.required = new json.required = new
{ {
message = localizedString.ResourceNotFound ? requiredAttribute.FormatErrorMessage(metadata.DisplayName) : string.Format(localizedString.Value, metadata.DisplayName) message = requiredAttribute.GetErrorMessage(localizer, metadata.DisplayName)
}; };
} }
else if (attribute is RegularExpressionAttribute regularExpressionAttribute) else if (attribute is RegularExpressionAttribute regularExpressionAttribute)
@ -143,7 +130,7 @@ namespace Infrastructure.Extensions
json.pattern = new json.pattern = new
{ {
regex = regularExpressionAttribute.Pattern, regex = regularExpressionAttribute.Pattern,
message = regularExpressionAttribute.ErrorMessage message = regularExpressionAttribute.GetErrorMessage(localizer, metadata.DisplayName)
}; };
} }
else if (attribute is DataTypeAttribute dataTypeAttribute) else if (attribute is DataTypeAttribute dataTypeAttribute)
@ -179,37 +166,50 @@ namespace Infrastructure.Extensions
} }
else if (attribute is MinLengthAttribute minLengthAttribute) else if (attribute is MinLengthAttribute minLengthAttribute)
{//minLength {//minLength
json.minLength = minLengthAttribute.Length; json.minLength = new
{
min = minLengthAttribute.Length,
message = minLengthAttribute.GetErrorMessage(localizer, metadata.DisplayName)
};
} }
else if (attribute is MaxLengthAttribute maxLengthAttribute) else if (attribute is MaxLengthAttribute maxLengthAttribute)
{//maxLength {//maxLength
json.maxLength = maxLengthAttribute.Length; json.maxLength = new
{
max = maxLengthAttribute.Length,
message = maxLengthAttribute.GetErrorMessage(localizer, metadata.DisplayName)
};
} }
else if (attribute is StringLengthAttribute stringLengthAttribute) else if (attribute is StringLengthAttribute stringLengthAttribute)
{//minLength,maxLength {//minLength,maxLength
json.minLength = stringLengthAttribute.MinimumLength; json.length = new
json.maxLength = stringLengthAttribute.MaximumLength; {
min = stringLengthAttribute.MinimumLength,
max = stringLengthAttribute.MaximumLength,
message = stringLengthAttribute.GetErrorMessage(localizer, metadata.DisplayName,
stringLengthAttribute.MinimumLength.ToString(),
stringLengthAttribute.MaximumLength.ToString())
};
} }
else if (attribute is RangeAttribute rangeAttribute) else if (attribute is RangeAttribute rangeAttribute)
{//minimum,maximum {//minimum,maximum
json.minimum = rangeAttribute.Minimum; json.range = new
json.maximum = rangeAttribute.Maximum; {
} minimum = rangeAttribute.Minimum,
else if (attribute is ScaffoldColumnAttribute scaffoldColumnAttribute) maximum = rangeAttribute.Maximum,
{//scaffold 自定义 message = rangeAttribute.GetErrorMessage(localizer, metadata.DisplayName,
json.scaffold = scaffoldColumnAttribute.Scaffold; rangeAttribute.Minimum.ToString(),
} rangeAttribute.Minimum.ToString())
else if (attribute is HiddenInputAttribute hiddenInputAttribute) };
{//hidden 自定义
json.hidden = hiddenInputAttribute.DisplayValue;
}
else if (attribute is UIHintAttribute uIHintAttribute)
{//ui 自定义
json.ui = uIHintAttribute.UIHint.ToLower();
} }
else if (attribute is CompareAttribute compareAttribute) else if (attribute is CompareAttribute compareAttribute)
{//compare 自定义 {//compare 自定义
json.compare = compareAttribute.OtherProperty; var compareName = parent.Properties.FirstOrDefault(o => o.PropertyName == compareAttribute.OtherProperty)?.DisplayName;
json.compare = new
{
other = compareAttribute.OtherProperty,
message = compareAttribute.GetErrorMessage(localizer, metadata.DisplayName, compareName)
};
} }
else if (attribute is RemoteAttribute remoteAttribute) else if (attribute is RemoteAttribute remoteAttribute)
{//remote 自定义 {//remote 自定义
@ -218,36 +218,67 @@ namespace Infrastructure.Extensions
{ {
url = controller.Url.Action(routeData["action"].ToString(), routeData["controller"].ToString(), new { Area = routeData["area"].ToString() }), url = controller.Url.Action(routeData["action"].ToString(), routeData["controller"].ToString(), new { Area = routeData["area"].ToString() }),
remoteAttribute.AdditionalFields, remoteAttribute.AdditionalFields,
//remoteAttribute. message = remoteAttribute.GetErrorMessage(localizer, metadata.DisplayName)
}; };
} }
else if (attribute is ScaffoldColumnAttribute scaffoldColumnAttribute)
{//scaffold 自定义
json.scaffold = scaffoldColumnAttribute.Scaffold;
}
else if (attribute is HiddenInputAttribute hiddenInputAttribute)
{//hidden 自定义
json.hidden = hiddenInputAttribute.DisplayValue;
}
else if (attribute is UIHintAttribute uIHintAttribute)
{//ui 自定义
json.ui = uIHintAttribute.UIHint.ToLower();
}
} }
dynamic properties = new ExpandoObject(); dynamic properties = new ExpandoObject();
var propertiesDictionary = (IDictionary<string, object>)properties; var propertiesDictionary = (IDictionary<string, object>)properties;
//var requiredList = new List<string>();
if (metadata.IsComplexType && !metadata.IsCollectionType && metadata.Properties.Any()) if (metadata.IsComplexType && !metadata.IsCollectionType && metadata.Properties.Any())
{ {
foreach (var item in metadata.Properties) foreach (var item in metadata.Properties)
{ {
var modelMetadataItem = item as DefaultModelMetadata; var modelMetadataItem = item as DefaultModelMetadata;
propertiesDictionary[item.PropertyName] = CreateJson(controller, modelMetadataItem); propertiesDictionary[item.PropertyName] = CreateJson(controller, modelMetadataItem, metadata);
//if (modelMetadataItem.IsRequired)
//{
// requiredList.Add(item.PropertyName);
//}
} }
json.properties = properties; json.properties = properties;
// if (requiredList.Any())
// {
// json.required = requiredList;
// }
} }
return json; return json;
} }
catch (Exception ex) catch (Exception ex)
{ {
ex.PrintStack();
return null; return null;
} }
} }
public static string GetErrorMessage(this ValidationAttribute attribute, IStringLocalizer localizer, params string[] args)
{
var localizedString = localizer.GetString(attribute.GetType().Name);
//return localizedString.ResourceNotFound ? attribute.FormatErrorMessage(args[0]) : string.Format(localizedString.Value, args);
var format = attribute.ErrorMessage;
if (localizedString.ResourceNotFound)
{
if (string.IsNullOrEmpty(format))
{
format = attribute.GetType().GetProperty("ErrorMessageString", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(attribute) as string;
}
}
else
{
format = localizedString.Value;
}
try
{
return string.Format(format, args);
}
catch (Exception ex)
{
ex.PrintStack();
}
return format;
}
} }
} }

@ -1,8 +1,7 @@
using Infrastructure.Application; using Infrastructure.Application;
using Infrastructure.Resources; using Microsoft.AspNetCore.Mvc;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Security.AccessControl;
namespace Application.Models namespace Application.Models
{ {
@ -31,6 +30,9 @@ namespace Application.Models
[Display(Name = "节点名称")] [Display(Name = "节点名称")]
[MaxLength(64, ErrorMessage = "{0}最大长度为{1}")] [MaxLength(64, ErrorMessage = "{0}最大长度为{1}")]
[Required(ErrorMessage = nameof(RequiredAttribute))] [Required(ErrorMessage = nameof(RequiredAttribute))]
//for temp test start
//[Remote("Valid", "Ajax", "Admin", AdditionalFields = "CategoryNumber", ErrorMessage = "test ajax valid")]
//for temp test end
public string Name { get; set; } public string Name { get; set; }
[Display(Name = "节点编号")] [Display(Name = "节点编号")]

@ -80,22 +80,6 @@
mounted: function () { mounted: function () {
this.load(); this.load();
}, },
//watch: {
// 'data.model': {
// handler: function (newModel, oldModel) {
// if (oldModel === null) {
// return;
// }
// _.forIn(this.data.schema.properties, function (value, key) {
// //console.log(newModel[key] + ':' + oldModel[key]);
// if (newModel[key] !== oldModel[key]) {
// }
// });
// },
// deep: true
// }
//},
methods: { methods: {
load: function () { load: function () {
var vm = this; var vm = this;
@ -104,20 +88,67 @@
vm.data = response.data; vm.data = response.data;
}); });
}, },
change: function (e) { change: function (name) {
var name = e.target.name; var vm = this;
var value = e.target.value; var value = this.data.model[name];
var property = this.data.schema.properties[name];
this.validInternal(property.required, name, o => value);
this.validInternal(property.pattern, name, o => new RegExp(property.pattern.regex).test(value));
this.validInternal(property.minLength, name, o => value.length >= property.minLength.min);
this.validInternal(property.maxLength, name, o => value.length <= property.maxLength.max);
this.validInternal(property.length, name, o => value.length >= property.length.min && value.length <= property.length.max);
this.validInternal(property.range, name, o => parseFloat(value) >= property.range.minimum && parseFloat(value) <= property.range.maximum);
this.validInternal(property.compare, name, o => o === vm.data.model[vm.camelCased(name)]);
this.validInternal(property.remote, name, o => {
var url = property.remote.url + '?' + name + '=' + value;
if (property.remote.additionalFields) {
var keys = property.remote.additionalFields.split(',');
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
url = url + '&' + key + '=' + vm.data.model[vm.camelCased(key)];
}
}
axios.get(url).then(function (response) {
if (response.data === true) {
vm.removeError(name);
}
else {
var message = response.data === false ? property.remote.message : response.data;
vm.updateError(name, message);
}
}).catch(function (error) {
vm.removeError(name);
vm.updateError(name, 'network error');
});
return false;
}, 'loading');
console.log(this.data.errors);
},
validInternal: function (validator, name, valid, message) {
if (!validator) {
return;
}
var property = this.data.schema.properties[name]; var property = this.data.schema.properties[name];
if (property.required) { if (valid()) {
this.removeError(name);
}
else {
message = message || validator.message;
this.updateError(name, message);
}
},
camelCased: function (name) {
return name[0].toLowerCase() + name.substr(1);
},
removeError: function (name, message) {
var error = Enumerable.from(this.data.errors).firstOrDefault(o => o.key.toLowerCase() === name.toLowerCase()); var error = Enumerable.from(this.data.errors).firstOrDefault(o => o.key.toLowerCase() === name.toLowerCase());
if (value) {
if (error) { if (error) {
var index = _.findIndex(this.data.errors, o => o.key.toLowerCase() === name.toLowerCase()); var index = _.findIndex(this.data.errors, o => o.key.toLowerCase() === name.toLowerCase());
this.data.errors.splice(index, 1); this.data.errors.splice(index, 1);
} }
} },
else { updateError: function (name, message) {
var message = property.required.message; var error = Enumerable.from(this.data.errors).firstOrDefault(o => o.key.toLowerCase() === name.toLowerCase());
if (!error) { if (!error) {
error = { error = {
key: name, key: name,
@ -128,15 +159,17 @@
this.data.errors.push(error); this.data.errors.push(error);
} }
else { else {
if (!Enumable.from(error.value.errors).any(o => o === message)) { if (!Enumerable.from(error.value.errors).any(o => o === message)) {
error.value.errors.push(property.required); error.value.errors.push({ errorMessage: message });
}
}
} }
} }
}, },
valid: function () { valid: function () {
return true; var vm = this
_.forIn(this.data.schema.properties, function (value, key) {
vm.change(key);
});
return this.data.errors.length === 0;
}, },
getValidationSummary: function (excludePropertyErrors) { getValidationSummary: function (excludePropertyErrors) {
var query = Enumerable.from(this.data.errors); var query = Enumerable.from(this.data.errors);

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<input type="text" :name="name" class="form-control" v-model="currentValue" v-on:change="$emit('change',$event)" /> <input type="text" :name="name" class="form-control" v-model="currentValue" v-on:change="$emit('change',name)" />
</div> </div>
</template> </template>
<script> <script>

Loading…
Cancel
Save