Копировать атрибуты одного свойства в другое вместо того, чтобы записывать их снова - PullRequest
0 голосов
/ 13 апреля 2020

Я создал модель со всеми необходимыми атрибутами проверки и аннотациями данных, но столкнулся с проблемой, так как не могу использовать этот класс в качестве модели формы, так как он имеет дополнительные атрибуты, и мне нужен как можно меньший объект формы, потому что я отправляю его сериализованный json в API.

Я могу приблизиться к тому, «который уже сделал», скопировав только необходимые свойства и их атрибуты в другой класс, и я не должен беспокоиться о сохранении значений то же самое, потому что они будут иметь одни и те же константы, но это может иметь неприятные последствия, если я решу удалить или добавить атрибуты. Мне нужно go для каждой модели формы и добавить / удалить атрибуты

Есть ли какой-нибудь встроенный атрибут, который клонирует все атрибуты данного свойства? как в следующем примере?

Класс атрибута

[AttributeUsage(AttributeTargets.Property)]
public class ClonePropertyAttributesAttribute : Attribute
{
    public ClonePropertyAttributesFromAttribute(Type TargetType,String PropertyName)
    {
         //clone attributes logic here
    }
}

Модель формы

 public class SignUpFormModel
 {
    [ClonePropertyAttributesFrom(typeof(User),"Email")]
    public String Email { get; set; }
    [ClonePropertyAttributesFrom(typeof(User),"Username ")]
    public String Username { get; set; }
    [ClonePropertyAttributesFrom(typeof(User),"Password")]
    public String Password { get; set; }
    [ClonePropertyAttributesFrom(typeof(User),"First_Name ")]
    public String First_Name { get; set; }
    [ClonePropertyAttributesFrom(typeof(User),"Last_Name")]
    public String Last_Name { get; set; }
    [ClonePropertyAttributes(AttributeProvider(typeof(User).GetProperty("Profile_Picture")))]
    public String Profile_Picture { get; set; }
 }

Модель

public class User
{
    //### Constansts Definitions ###//
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long? Id { get; set; }
    [Display(Name = EMAIL_DISPLAY_NAME)]
    [Required(ErrorMessage = EMAIL_REQUIRED_ERROR_MESSAGE)]
    [StringLength(EMAIL_MAX_LENGTH, ErrorMessage = EMAIL_LENGTH_ERROR_MESSAGE)]
    [RegularExpression(EMAIL_REGEX, ErrorMessage = EMAIL_REGEX_ERROR_MESSAGE)]
    [Remote(EMAIL_REMOTE_DOES_EXIST_ACTION_NAME, EMAIL_REMOTE_EXIST_CONTROLLER_NAME, ErrorMessage = EMAIL_REMOTE_DOES_EXIST_ERROR_MESSAGE)]
    [JsonProperty(EMAIL_JSON_PROPERTY_NAME)]
    public String Email { get; set; }
    [Display(Name = USERNAME_DISPLAY_NAME)]
    [Required(ErrorMessage = USERNAME_REQUIRED_ERROR_MESSAGE)]
    [StringLength(USERNAME_MAX_LENGTH, MinimumLength = USERNAME_MIN_LENGTH, ErrorMessage = USERNAME_LENGTH_ERROR_MESSAGE)]
    [RegularExpression(USERNAME_REGEX, ErrorMessage = USERNAME_REGEX_ERROR_MESSAGE)]
    [Remote(USERNAME_REMOTE_DOES_EXIST_ACTION_NAME, USERNAME_REMOTE_EXIST_CONTROLLER_NAME, ErrorMessage = USERNAME_REMOTE_DOES_EXIST_ERROR_MESSAGE)]
    [JsonProperty(USERNAME_JSON_PROPERTY_NAME)]
    public String Username { get; set; }
    [Display(Name = PASSWORD_DISPLAY_NAME)]
    [Required(ErrorMessage = PASSWORD_REQUIRED_ERROR_MESSAGE)]
    [StringLength(PASSWORD_MAX_LENGTH, MinimumLength = PASSWORD_MIN_LENGTH, ErrorMessage = PASSWORD_LENGTH_ERROR_MESSAGE)]
    [RegularExpression(PASSWORD_REGEX,ErrorMessage = PASSWORD_REGEX_ERROR_MESSAGE)]
    [JsonProperty(PASSWORD_JSON_PROPERTY_NAME)]
    public String Password { get; set; }
    [Display(Name = FIRST_NAME_DISPLAY_NAME)]
    [Required(ErrorMessage = FIRST_NAME_REQUIRED_ERROR_MESSAGE)]
    [StringLength(FIRST_NAME_MAX_LENGTH, MinimumLength = FIRST_NAME_MIN_LENGTH, ErrorMessage = FIRST_NAME_LENGTH_ERROR_MESSAGE)]
    [RegularExpression(FIRST_NAME_REGEX, ErrorMessage = FIRST_NAME_REGEX_ERROR_MESSAGE)]
    [JsonProperty(FIRST_NAME_JSON_PROPERTY_NAME)]
    public String First_Name { get; set; }
    [Display(Name = LAST_NAME_DISPLAY_NAME)]
    [Required(ErrorMessage = LAST_NAME_REQUIRED_ERROR_MESSAGE)]
    [StringLength(LAST_NAME_MAX_LENGTH, MinimumLength = LAST_NAME_MIN_LENGTH, ErrorMessage = LAST_NAME_LENGTH_ERROR_MESSAGE)]
    [RegularExpression(LAST_NAME_REGEX, ErrorMessage = LAST_NAME_REGEX_ERROR_MESSAGE)]
    [JsonProperty(LAST_NAME_JSON_PROPERTY_NAME)]
    public String Last_Name { get; set; }
    [JsonProperty(PROFILE_PICTURE_JSON_PROPERTY_NAME)]
    public String Profile_Picture { get; set; }
    [JsonProperty(REGISTERATION_TIME_JSON_PROPERTY_NAME)]
    public long? RegisterationTime { get; set; }
    [JsonProperty(VERIFIED_JSON_PROPERTY_NAME)]
    public int? Verified { get; set; }
    [JsonProperty(INACCESSIBLE_JSON_PROPERTY_NAME)]
    public int? Inaccessible { get; set; }
}

Обновление # 1

Вот несколько возможных дубликатов:
stackoverflow.com / questions / 49701038
stackoverflow.com / questions / 14663763
Это кажется утомительным для кроме того, это не похоже на дорогую операцию при каждой регистрации, не так ли?

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

Вы можете использовать AutoMapper для отображения от User до SignUpFormModel.

AutoMapper полезен, когда вам нужно сопоставить классы модели (или объекты модели базы данных) с объектами DTO, используемыми в вызовах API и в обратном направлении.

var config = new MapperConfiguration(cfg => {
    cfg.CreateMap<User, SignUpFormModel>();
});

IMapper mapper = config.CreateMapper();
var user = new User() { First_Name = "tester" };
var formModel = mapper.Map<User, SignUpFormModel>(user);

Руководство по началу работы с AutoMapper

Обновление:

, если имя свойства не совпадает в источнике и месте назначения класс, для него можно создать собственное отображение, например:

cfg.CreateMap<SignUpFormModel, User>()
    .ForMember(x => x.EmailInDestination, o => o.MapFrom(s => s.EmailInSource))
0 голосов
/ 13 апреля 2020

Единственный способ, которым я мог придумать, это получить свойства во время выполнения с помощью отражения, а затем применить их к другому классу (ам).

см .: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/accessing-attributes-by-using-reflection

и установочные атрибуты:

https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.typedescriptor.addattributes?redirectedfrom=MSDN&view=netframework-4.8#System_ComponentModel_TypeDescriptor_AddAttributes_System_Object_System_Attribute___

Недостатки: - отражение медленное - не совсем безопасно для типов

Я не совсем фанат такого подхода, но я лично не вижу другого пути. Я думаю, что вместо этого вы должны попытаться пересмотреть свою архитектуру, чтобы обойти эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...