2016-06-01 18 views
7

Tôi đã cố gắng thực hiện công việc này và thực hiện nhiều tìm kiếm trên google/stackoverflow mà không có may mắn chút nào.ModelState.IsValid luôn đúng khi kiểm tra Trình điều khiển trong Asp.Net MVC Web Api

Tôi có một mô hình đơn giản:

public class MovieModel 
{ 
    public string Id { get; set; } 

    [Required] 
    [StringLength(100)] 
    public string Name { get; set; } 
} 

Một phương pháp trong điều khiển:

// POST: api/Movies 
public IHttpActionResult Post([FromBody]MovieModel movieModel) 
{ 
    if (ModelState.IsValid) 
    { 
     //Code 
    } 
} 

Và một phương pháp thử nghiệm (là một thử nghiệm hội nhập, nhưng cùng sẽ xảy ra trong các thử nghiệm đơn vị):

[TestMethod] 
public void MoviesController_Post_Without_Name() 
{ 
    // Arrange 
    var model = new MovieModel(); 
    model.Name = ""; 

    // Act 
    var result = controller.Post(model); 

    // Assert 
    Assert.IsInstanceOfType(result, typeof(InvalidModelStateResult)); 
    Assert.AreEqual(6, controller.Get().Count()); 
} 

Mặc dù mô hình rõ ràng là không hợp lệ nhưng nó luôn đánh giá thuộc tính IsValid là đúng.

Tôi đã thử nhiều cách tiếp cận cho đến nay mà không thành công.

Trả lời

5

Giải pháp của bạn có thể hoạt động, nhưng cách tốt hơn là sử dụng phương pháp ApiController.Validate.

public void MoviesController_Post_Without_Name() 
{ 
    // Arrange 
    var model = new MovieModel(); 
    model.Name = ""; 

    // Act 
    controller.Validate(model); //<---- use the built-in method 
    var result = controller.Post(model); 

    // Assert 
    Assert.IsInstanceOfType(result, typeof(InvalidModelStateResult)); 
    Assert.AreEqual(6, controller.Get().Count()); 
} 
+0

Tôi đã thử phương pháp này .Validate trước đây, nhưng nó không tồn tại. Tôi đang sử dụng MVC 5. –

+0

Tham chiếu microsoft hiển thị phương thức Validate, cho phiên bản 5 của MVC, nhưng nó đơn giản là không hoạt động, không phải Intellisense cũng không xây dựng các công trình. –

+0

@ AndréBaptista Tại sao bạn lại nói về MVC? 'ApiController' là một lớp Web API, và được tìm thấy trong' System.Web.Http'. Đảm bảo bạn đã thêm đúng gói NuGet vào dự án thử nghiệm. –

4

Nhờ this trang web, tôi phát hiện ra các giải pháp:

private void SimulateValidation(object model) 
{ 
    // mimic the behaviour of the model binder which is responsible for Validating the Model 
    var validationContext = new ValidationContext(model, null, null); 
    var validationResults = new List<ValidationResult>(); 
    Validator.TryValidateObject(model, validationContext, validationResults, true); 
    foreach (var validationResult in validationResults) 
    { 
     this.controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage); 
    } 
} 

Và trong đó có một dòng trong phương pháp thử nghiệm như thế này:

public void MoviesController_Post_Without_Name() 
{ 
    // Arrange 
    var model = new MovieModel(); 
    model.Name = ""; 

    // Act 
    SimulateValidation(model); 
    var result = controller.Post(model); 

    // Assert 
    Assert.IsInstanceOfType(result, typeof(InvalidModelStateResult)); 
    Assert.AreEqual(6, controller.Get().Count()); 
} 

Hy vọng rằng sẽ giúp ai đó, nó sẽ có lưu tôi một số giờ truy cập web.

+0

điều này phù hợp với tôi nhưng không phải với mô hình lồng nhau – MattjeS

+1

Đã làm việc cho Core 2.0, cho lồng nhau chỉ cần 'SimulateValidation (model); SimulateValidation (model.child); ' – ono2012

+0

Cảm ơn bạn rất nhiều @Andre Baptista, điều này làm việc cho tôi –

Các vấn đề liên quan