Аннотации данных с помощью метода EntityFramework (Database First) - PullRequest
4 голосов
/ 23 августа 2011

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

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel;
using System.Runtime.Serialization; 

[DataContract]
[MetadataType(typeof(CustomerMetaData))]
public partial class Customer
{
}

public class CustomerMetaData
{
    [DataMember]
    public object CustomerID { get; set; }

    [Required]
    [StringLength(50)]
    [DataType(DataType.EmailAddress)]
    [DataMember]
    public object Email { get; set; }
}

Когда я нажимаю кнопку «Отправить» в форме, он пытается добавить запись и не выполняет никакой проверки. Произошла ошибка во время выполнения, сообщающая мне, что адрес электронной почты требуется. Я, очевидно, хочу, чтобы эта проверка выполнялась заранее с аннотациями данных.

Как мне это сделать?

Возвращается реальная ошибка времени выполнения, говорящая, что адрес электронной почты не должен быть НЕДЕЙСТВИТЕЛЕН, когда запись пытается быть добавлена. Это правильно. Столбец базы данных требует значения.

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

В Интернете есть статьи о том, как это сделать с CodeFirst , но я видел нет о том, как это сделать с DataBaseFirst . Как это можно сделать?

Еще раз мой класс Customer выглядит следующим образом.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace YeagerTechModel
{
    [Serializable]
    [DataContract]
    //[MetadataType(typeof(CustomerMetaData))]
    public partial class Customer
    {
        public Customer()
        {
            this.Projects = new HashSet<Project>();
        }

        [DataMember]
        public short CustomerID { get; set; }

        [Required]
        [StringLength(50)]
        [DataType(DataType.EmailAddress)]
        [DataMember]
        public string Email { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string Company { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string FirstName { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string LastName { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string Address1 { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string Address2 { get; set; }

        [StringLength(50)]
        [DataType(DataType.Text)]
        [DataMember]
        public string City { get; set; }

        [StringLength(2)]
        [DataType(DataType.Text)]
        [DataMember]
        public string State { get; set; }

        [StringLength(10)]
        [DataType(DataType.Text)]
        [RegularExpression(@"^\d{5}(-\d{4})?$")]
        [DataMember]
        public string Zip { get; set; }

        [StringLength(12)]
        [DataType(DataType.PhoneNumber)]
        [DataMember]
        public string HomePhone { get; set; }

        [StringLength(12)]
        [DataType(DataType.PhoneNumber)]
        [DataMember]
        public string CellPhone { get; set; }

        [StringLength(100)]
        [DataType(DataType.Url)]
        [DataMember]
        public string Website { get; set; }

        [StringLength(50)]
        [DataType(DataType.EmailAddress)]
        [DataMember]
        public string IMAddress { get; set; }

        [DataMember]
        public System.DateTime CreatedDate { get; set; }

        [DataMember]
        public Nullable<System.DateTime> UpdatedDate { get; set; }

        public virtual ICollection<Project> Projects { get; set; }
    }
}

Когда я отлаживаю "if (ModelState.IsValid)" в моем клиенте, свойство всегда возвращает true. Как будто DataAnnotations даже не распознаются. При отладке я проверяю объект ModelState, и у него есть все значения свойств (пустая строка во всех случаях, так как я пытаюсь вызвать ошибку). Я должен получить ошибку isRequired на адрес электронной почты, который я намеренно оставляю пустым.

[HttpPost]
        public ActionResult Create(YeagerTechWcfService.Customer cust)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    db.AddCustomer(cust);
                    TempData["ErrCode"] = "Customer successfully added.";
                    return RedirectToAction("Index", "Home");
                }
                catch (Exception ex)
                {
                    ViewData["ErrCode"] = "CustErr";
                    ViewBag.Error = ex.Message;
                    return View();
                }
            }
            else
                return View();
        }

Ответы [ 2 ]

1 голос
/ 08 ноября 2011

К сожалению, эта аннотация влияет только на визуализацию, а не на проверку. У меня только что была такая же проблема с DataType.Url, и она также обсуждалась в вопросе Работает ли проверка данных DataTypeAttribute в MVC2? (хотя и для MVC 2 - но проблема кажется такой же в 3).

Просто добавьте на него аннотацию данных регулярного выражения:

[RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Email was invalid.")]
0 голосов
/ 05 ноября 2012

Просто, чтобы немного расширить это, в MVC 3 вы можете пойти другим путем, чтобы использовать валидацию.Сначала я использую базу данных MVC 3 + EF, и я могу использовать такой код в классе расширений / частичных моделей:

[MetadataType(typeof(Foobar.Metadata))]
[Serializable]
public partial class Foobar
{
    private sealed class Metadata
    {
        [Required]
        [MinLength(10)]
        public object Name { get; set; }
    }

    // Other stuff here
}

Затем, когда я могу передать своему маленькому Foobar недопустимое имя в действии контроллера, я могуполучить ошибки проверки, используя TryValidateModel вместо ModelState.IsValid (Ужас ужасов, я не привязываю данные).

        Foobar c = new Foobar();
        c.Name = "ponies";

        var y = TryValidateModel(c);
        if (!y)
        {
            foreach (var item in ModelState.Values)
            {
                foreach (var err in item.Errors)
                {
                    DoxLog.Error(err.ErrorMessage, err.Exception);
                }
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...