2010-05-08 22 views
6

Tôi có một mô hình như thế này:ASPNET MVC - Tại sao ModelState.IsValid sai "Trường x là bắt buộc" khi trường đó có giá trị?

public PurchaseOrder 
{ 
    [Required] [StringLength(15)] 
    public virtual string OrderNumber {get;set;} 
    // etc.   
} 

Khi tôi gửi một đơn đặt từ màn hình (sử dụng $ .post, không input type = nộp) nó đi đến lớp điều khiển của tôi:

public class PurchaseOrderController 
{ 
    public JsonResult Save(PurchaseOrder order) 
    { 
     // TryUpdateModel(order); // commented out since modelstate.isvalid remains false anyway 
     if (ModelState.IsValid) 
     { 
      // its never valid 
     } 
    } 
} 

ModelState.IsValid luôn trả về false, với lỗi: "Trường Số thứ tự là bắt buộc". Nhưng có một giá trị trong trường này (?? lý do)

Tại sao giá trị "được yêu cầu" khi giá trị đó có giá trị? Tôi đã bỏ lỡ một cái gì đó? Có phải vì $ .post thay vì gửi không? Tôi có thể làm gì?

Đây là những gì debugger trông giống như:

alt text http://www.freeimagehosting.net/uploads/f734f3d95d.png

EDIT: info tắm ....

Tôi thực sự nghĩ rằng đối với một số lý do mô hình ràng buộc không xảy ra. Khi tôi thử mã này được tìm thấy tại đây:)

if (!ModelState.IsValid) 
{ 
    ModelState.Clear(); 
    ModelMetadata modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => order, order.GetType()); 
    ModelValidator compositeValidator = ModelValidator.GetModelValidator(modelMetadata, base.ControllerContext); 

    foreach (ModelValidationResult result in compositeValidator.Validate(null)) 
    { 
     this.ModelState.AddModelError(result.MemberName, result.Message); 
    } 
} 

Sau đó, ModelState.IsValid = true. Hàm compositeValidator.Validate() trả về 0 lỗi. Tôi nghĩ điều này cho thấy mô hình không bị ràng buộc, nhưng tôi vẫn không biết tại sao.

Phương pháp điều khiển thực sự trông như thế này (tôi bỏ lỡ các bộ lọc khi ban đầu viết câu hỏi này)

[JsonFilter(Param = "order", JsonDataType = typeof(PurchaseOrder))] 
public JsonResult Save(PurchaseOrder order) { // etc ... } 

Và JsonFilter thực hiện điều này để trích xuất các POCO từ json dữ liệu nộp:

filterContext.ActionParameters[Param] 
    = jsSerializer.Deserialize(inputContent, JsonDataType); 

Tôi đặt điểm ngắt trên dòng này và thứ tự hợp lệ, cộng với đơn đặt hàng.OrderNumber có giá trị chính xác.

Vì vậy, vẫn chưa được giải quyết, nhưng hy vọng thông tin thêm này sẽ giúp việc tìm kiếm một giải pháp

+2

tại sao thuộc tính được đánh dấu ảo? Bạn đang sử dụng theo dõi thay đổi POCO? –

+0

Giá trị là gì? Bạn đang sử dụng '$ .post' như thế nào? Nó có hoạt động bình thường không? –

+0

Tôi không biết tại sao nó là ảo, nó đã được như thế khi tôi bắt đầu làm việc trên các ứng dụng hiện có. –

Trả lời

1

Vâng tôi đã "giải quyết" nó, nhưng tôi không thực sự hiểu tại sao những thay đổi tôi đã thực hiện đã giúp.

tôi phải làm ba điều:

  1. Tháo bộ lọc json (bộ lọc không ràng buộc)

  2. Thay đổi contentType để application/json

    $ .ajaxSetup ({ contentType: "application/json; charset = utf-8" });

  3. Sử dụng MVC tương lai tải xuống Microsoft.Mvc.dll như được mô tả tại đây: http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx. Nói ở đâu để thêm điều này vào Application_Start() trong Global.asax.cs:

    ValueProviderFactories.Factories.Add (new JsonValueProviderFactory());

Bây giờ tôi không biết chính xác lý do tại sao đã hoạt động, nhưng nó có.

Thật không may là nó có tác dụng phụ tiêu cực: kiểu nội dung được áp dụng cho tất cả các phương thức $ .get() và $ .post() và chia tất cả jqgrids của tôi - chúng dường như chỉ hoạt động nếu loại nội dung là mặc định của application/x-www-form-urlencoded

Vì vậy, tôi đã hỏi 2 sau về các vấn đề:

  1. có thể thiết lập các kiểu nội dung trong một $ .post() gọi? Sau đó, tôi sẽ không cần đặt nó trên toàn cầu Jquery - How to make $.post() use contentType=application/json?

  2. Có thể thực hiện công việc jqrid nếu kiểu nội dung là ứng dụng/json không? Jquery - How to make $.post() use contentType=application/json?

+0

Có vẻ như tôi cần thay đổi $ .post() s của mình gọi phương thức điều khiển thành $ .ajax(). Nhưng nó chỉ cảm thấy như tôi đang làm một cái gì đó sai và nó chỉ nên làm việc nếu contentType là mặc định của ứng dụng/x-www-form-urlencoded. –

+0

JK, hai liên kết câu hỏi của bạn trỏ đến cùng một câu hỏi. –

1

Bạn có chắc chắn rằng lỗi là đến từ các lĩnh vực ORDERNUMBER?

Có vẻ lạ khi thông báo lỗi có Số đơn đặt hàng bằng 2 từ.

Hãy thử thay đổi tên của trường hoặc xóa thẻ bắt buộc để đảm bảo rằng đây là nơi xảy ra lỗi.

+1

Tôi tin rằng khung MVC xử lý điều đó cho bạn một cách tự động. Nó giống như khi bạn đi Html.LabelFor (model.OrderNumber). Nhãn cho biết "Số thứ tự" với khoảng cách giữa các từ. –

+0

Nếu tôi xóa chú thích [Bắt buộc], thì hãy chọn ModelState.IsValid == true. Nó cũng là trường duy nhất có chú thích này. –

1

Có khả năng là bài đăng trên jQuery của bạn không được đăng đúng cách trở lại bộ điều khiển. Bạn có thể chỉ đăng số đơn hàng thay vì một đối tượng đại diện chính xác cho mô hình. Tôi phải xem javascript của bạn là hoàn toàn chắc chắn.

Các cách chính xác để gửi tới phương pháp mà sẽ được (giả sử số đặt hàng của bạn được lưu trữ trong một biến javascript gọi là "ORDERNUMBER":

$.post([url to method], 
     { order: { OrderNumber: orderNumber } }, 
     function(json) { 
     //Insert code for actions to take after AJAX post returns. 
     }, 
     'json'); 

Nếu đây là trường hợp, sau đó bước tiếp theo tôi muốn hãy kiểm tra xem javascript có thực sự chiếm được giá trị của số đơn đặt hàng của bạn không và đăng nó như một phần của yêu cầu.Một kiểm tra nhanh chóng thông qua Firebug sẽ có thể cho bạn biết nếu điều đó xảy ra hay không.

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