2012-11-29 8 views
21

Tôi nhận VM sau trên một Web API bài hành độngWeb API nullable cần đòi hỏi DataMember thuộc tính

public class ViewModel 
{ 
    public string Name { get; set; } 

    [Required] 
    public int? Street { get; set; } 
} 

Khi tôi thực hiện một bài tôi nhận được lỗi sau:

Property 'Street' on type 'ViewModel' is invalid. Value-typed properties marked as [Required] must also be marked with [DataMember(IsRequired=true)] to be recognized as required. Consider attributing the declaring type with [DataContract] and the property with [DataMember(IsRequired=true)].

Dường lỗi là rõ ràng vì vậy tôi chỉ muốn hoàn toàn chắc chắn rằng nó là cần thiết để sử dụng [DataContract] và [DataMember] thuộc tính khi bạn có một lớp học với các thuộc tính nullable yêu cầu.

Có cách nào để tránh sử dụng các thuộc tính này trong API Web không?

Trả lời

20

Tôi đang phải đối mặt với vấn đề tương tự như bạn, và tôi nghĩ đó là hoàn toàn vô nghĩa. Với các loại giá trị tôi có thể thấy rằng [Required] không hoạt động vì thuộc tính có giá trị được nhập không thể là rỗng, nhưng khi bạn có loại giá trị có thể có giá trị không, thì không được là là bất kỳ vấn đề nào. Tuy nhiên, logic hợp lệ của mô hình API Web dường như đối xử với các kiểu giá trị không nullable và nullable theo cùng một cách, vì vậy bạn phải làm việc xung quanh nó. Tôi tìm thấy một công việc xung quanh trong Web API forum và có thể xác nhận rằng nó hoạt động: Tạo một lớp con ValidationAttribute và áp dụng nó thay vì RequiredAttribute về tài sản giá trị, đánh máy nullable:

using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Web.Mvc; 

public class NullableRequiredAttribute : ValidationAttribute, IClientValidatable 
{ 
    public bool AllowEmptyStrings { get; set; } 

    public NullableRequiredAttribute() 
     : base("The {0} field is required.") 
    { 
     AllowEmptyStrings = false; 
    } 

    public override bool IsValid(object value) 
    { 
     if (value == null) 
      return false; 

     if (value is string && !this.AllowEmptyStrings) 
     { 
      return !string.IsNullOrWhiteSpace(value as string); 
     } 

     return true; 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var modelClientValidationRule = new ModelClientValidationRequiredRule(FormatErrorMessage(metadata.DisplayName)); 
     yield return modelClientValidationRule; 
    } 
} 

NullableRequiredAttribute sử dụng:

public class Model 
{ 
    [NullableRequired] 
    public int? Id { get; set; } 
} 
+0

Đã một thời gian kể từ khi tôi đăng câu hỏi này và thực sự tôi đã làm những gì bạn đề xuất, tôi vẫn không hiểu tại sao trang web api hoạt động theo cách này – jorgehmv

+3

@jorgehmv Tôi coi đó là lỗi, cho đến khi ai đó thuyết phục tôi. – aknuds1

+0

Đây không phải là vấn đề nữa trong bản phát hành WebApi 2. Lỗi này dường như đã được sửa. Nếu bất cứ điều gì tôi đang bực mình rằng tôi đã làm cho các thuộc tính ViewModel vô hiệu hóa khi tôi đang gửi bài giá trị cho yêu cầu để trả lại thông báo lỗi chính xác. –

2

Tôi nghĩ rằng bạn đang chạy vào cùng một vấn đề như đã thảo luận ở đây:

DataAnnotation for Required property

+0

Vâng tôi đã tìm thấy giải pháp tương tự sau này. Theo tôi, đó là một cách thanh lịch hơn: Bạn vẫn có thể sử dụng trình xác thực yêu cầu mặc định ngay bây giờ. –

0

Điều này được khắc phục trong Web Api 2. Tuy nhiên, thú vị chỉ hoạt động nếu các trường là thuộc tính với get/set.