14

モデルクラスとビューモデルクラスが別々にあります。viewmodelクラスがUIレベルの検証のみを行う場合(検証:ModelまたはViewModelを参照)。

コントローラのアクション後、モデル(vewmodel)が有効であることを確認できます。

質問:モデル(データ注釈付きの主要エンティティ)を検証するにはどうすればよいですか。

モデルオブジェクトを使用してビューモデルを開発していません。プロパティを複製し、その特定のビューで必要になる可能性のあるすべてのプロパティを追加するだけです。

//Model Class
public class User
{
    [Required]
    public string Email {get; set;}

    [Required]
    public DateTime Created {get; set;}
}

//ViewModel Class
public class UserViewModel
{
    [Required]
    public string Email {get; set;}

    [Required]
    public string LivesIn {get; set;}
}

//Post action
public ActionResult(UserViewModel uvm)
{
    if( ModelState.IsValid)
        //means user entered data correctly and is validated

    User u = new User() {Email = uvm.Email, Created = DateTime.Now};
    //How do I validate "u"?

    return View();
}

このようなことをする必要があります:

var results = new List<ValidationResult>();
var context = new ValidationContext(u, null, null);
var r = Validator.TryValidateObject(u, context, results);

私が考えているのは、この検証手法を(ビジネスエンティティの)基本クラスに追加し、viewmodelクラスからビジネスエンティティにマッピングするときに検証することです。

助言がありますか?

4

2 に答える 2

10

1)ユーザーから情報を取得するモデルで流暢な検証を使用します。データ注釈よりも柔軟性があり、テストが簡単です。

2)automapperを使用することで、を書く必要がないので、automapperを調べたいと思うかもしれませんx.name = y.name

3)あなたのデータベースモデルについては、データ注釈に固執します。

以下のすべては、新しい情報に基づいています

まず、実際のモデル検証で行ったように、両方の場所に検証を配置する必要があります。これが私が行う方法です。免責事項:これは完璧な方法ではありません

まず、すべてをに更新UserViewModelします

public class UserViewModel
    {
        [Required()]
        [RegularExpression(@"^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$")]
        public String Email { get; set; }
    }

次に、アクションメソッドをに更新します

        // Post action
        [HttpPost]
        public ActionResult register (UserViewModel uvm)
        {
            // This validates the UserViewModel
            if (ModelState.IsValid)
            {

                try
                {
                    // You should delegate this task to a service but to keep it simple we do it here
                    User u = new User() { Email = uvm.Email, Created = DateTime.Now };
                    RedirectToAction("Index"); // On success you go to other page right?
                }
                catch (Exception x)
                {
                    ModelState.AddModelError("RegistrationError", x); // Replace x with your error message
                }

            }       

            // Return your UserViewModel to the view if something happened               
            return View(uvm);
        }

今、ユーザーモデルの場合、それはトリッキーになり、多くの可能な解決策があります。私が思いついた解決策(おそらく最善ではない)は次のとおりです。

public class User
    {
        private string email;
        private DateTime created;

        public string Email
        {
            get
            {
                return email;
            }
            set
            {
                email = ValidateEmail(value);
            }
        }

        private string ValidateEmail(string value)
        {
            if (!validEmail(value))
                throw new NotSupportedException("Not a valid email address");     

            return value;
        }

        private bool validEmail(string value)
        {
            return Regex.IsMatch(value, @"^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$");
        }

私自身のコードをチェックするための最後のいくつかのユニットテスト:

   [TestClass()]
    public class UserTest
    {

        /// <summary>
        /// If the email is valid it is stored in the private container
        /// </summary>
        [TestMethod()]
        public void UserEmailGetsValidated()
        {
            User x = new User();
            x.Email = "test@test.com";
            Assert.AreEqual("test@test.com", x.Email);
        }

        /// <summary>
        /// If the email is invalid it is not stored and an error is thrown in this application
        /// </summary>
        [TestMethod()]
        [ExpectedException(typeof(NotSupportedException))]
        public void UserEmailPropertyThrowsErrorWhenInvalidEmail()    
       {
           User x = new User();
           x.Email = "blah blah blah";
           Assert.AreNotEqual("blah blah blah", x.Email);
       }


        /// <summary>
        /// Clears an assumption that on object creation the email is validated when its set
        /// </summary>
        [TestMethod()]
        public void UserGetsValidatedOnConstructionOfObject()
        {
            User x = new User() { Email = "test@test.com" };
            x.Email = "test@test.com";
            Assert.AreEqual("test@test.com", x.Email);
        }
    }
于 2011-06-24T15:03:58.677 に答える
3

データ注釈を使用する方が良いと思いますこれを見てください

ASP.NETMVC評価

サーバー側の検証には、流暢な検証を使用できます

そしてこの質問を見てください

于 2011-06-24T14:54:01.417 に答える