Проверка сложных типов с помощью DataAnnotations

Я решил использовать Entity Framework для O/R Mapping и DataAnnotations для проверки в моем проекте, и теперь я столкнулся со странной проблемой при попытке реализовать это.

Вот что я сделал:

У меня есть следующий тип сущности

Contact
*******
Int32 Id (not null, Entity Key)
Name Name (not null) 
Address Address (not null)
String Phone
String Email

где Name и Address — сложные типы, определяемые следующим образом:

Name                                  Address
****                                  *******
String First (not null)               String Street (not null)
String Last (not null)                String ZipCode (not null)
                                      String City (not null)

И следующие классы находятся в том же пространстве имен, что и мои сущности:

public class ContactMetadata
{
    [Required]
    public Name Name { get; set; }
}

[MetadataType(typeof(ContactMetadata))]
partial class Contact { }

Однако, когда я создаю новый элемент Contact, типы Name и Address заполняются экземплярами Name и Address, где все значения равны null, вместо того, чтобы Name и Address сами имели значения null. Таким образом, атрибут Required не выдает никаких ошибок, хотя все значения равны null. Как мне обойти это?


person Tomas Aschan    schedule 30.06.2009    source источник


Ответы (4)


Таким образом, он создает экземпляры объектов Name и Address, свойства которых равны нулю? Интересно.

Можете ли вы просто добавить атрибут [Required] к дочерним элементам?

РЕДАКТИРОВАТЬ: я знаю, что это может считаться вонючим способом сделать это, но для ясности я редактирую ваш ответ в сообщении, чтобы его было легче найти следующему человеку, у которого проблемы с этим...

Предлагаемое (и принятое, но еще не проверенное) решение:

Напишите собственный атрибут проверки, который проверяет значения null.

person blu    schedule 30.06.2009
comment
Точно. Я создал новый класс с именем NameMetadata, используя ту же структуру, что и выше, и установил требуемые имена First и Last, но это не имело значения. - person Tomas Aschan; 01.07.2009
comment
Теперь за этот вопрос назначена награда - и вы ближе всего к чему-то... ;) - person Tomas Aschan; 07.07.2009
comment
О, как грустно, я понятия не имею. Возможно, вы пытались создать собственный атрибут и проверить его на нулевое значение? - person blu; 07.07.2009
comment
Нет, я не видел. Но, учитывая, что это сделано правильно, это, вероятно, сработает... спасибо! знак равно - person Tomas Aschan; 09.07.2009

Убедитесь, что имена, которые заканчиваются в полях HTML, совпадают с именами свойств класса.

Например, если у вас есть это:

public class Contact {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Address Address { get; set; }
}

public class Address {
    public string Street { get; set; }
    public string City { get; set; }
    [...]
}

Ваши вызовы помощников HTML должны выглядеть так:

<%= Html.TextBox("FirstName") %>
<%= Html.TextBox("LastName") %>
<%= Html.TextBox("Address.Street") %>
<%= Html.TextBox("Address.City") %>
[...]
person Brad Wilson    schedule 30.06.2009
comment
Я еще не добрался до части представления, но я это сделаю, и когда я это сделаю, это будет полезная информация. Спасибо! - person Tomas Aschan; 30.06.2009
comment
Спасибо, это помогло мне с чем-то подобным! - person JustinP8; 19.04.2011

Ознакомьтесь с этим сообщением в блоге complex-dataannotations-validation. Я думаю, что атрибут RequiredAssociation - это то, что вам нужно. Возможно, вам придется немного настроить его для Entity Framework вместо LINQ to SQL.

person Community    schedule 30.07.2009

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

public class Contact{

[Required]
public int? AddressIDForValidation{
get{return this.Address.AdressID;}
}

public Address Address{get;set;}
}



public class Address{
public int? AddressID{get;set;}
public string Street{get;set;}
}
person BlackjacketMack    schedule 28.05.2011