Yah*_*hya 13 c# model viewmodel asp.net-mvc-2-validation asp.net-mvc-2
我有单独的模型和视图模型类.其中viewmodel类仅进行UI级别验证(请参阅:验证:模型或ViewModel).
我可以在控制器中验证模型(vewmodel)是否有效.
问:我如何验证模型(带有数据注释的主要实体).
我没有使用模型对象开发viewmodel.只需复制属性并添加该特定视图中可能需要的所有属性.
//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();
}
Run Code Online (Sandbox Code Playgroud)
应该做这样的事情:
var results = new List<ValidationResult>();
var context = new ValidationContext(u, null, null);
var r = Validator.TryValidateObject(u, context, results);
Run Code Online (Sandbox Code Playgroud)
我在想的是在基类(业务实体)中添加这种验证技术,并在我从viewmodel类映射到业务实体时验证它.
有什么建议?
Dav*_*vid 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; }
}
Run Code Online (Sandbox Code Playgroud)
然后将动作方法更新为
// 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);
}
Run Code Online (Sandbox Code Playgroud)
现在对于用户模型来说,它变得棘手,你有很多可能的解决方案.我想出的解决方案(可能不是最好的)如下:
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}$");
}
Run Code Online (Sandbox Code Playgroud)
最后一些单元测试来检查我自己的代码:
[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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21559 次 |
| 最近记录: |