【问题标题】:Problems with Model binding and validation attributes with asp.net Web API使用 asp.net Web API 的模型绑定和验证属性问题
【发布时间】:2013-01-24 10:36:33
【问题描述】:

我正在使用 ASP.NET Web API 编写 Web API,并使用以下视图模型。 当特定属性上有两个验证属性(即 [Required] 和 [StringLength(10)])时,我似乎遇到了数据绑定问题。

将 JSON 值从客户端发送到表单的控制器操作时:

// POST api/列表

public void Post([FromBody] TaskViewModel taskVM)

我观察到以下几点:

  • 如果我删除多个属性中的一个,则一切正常;
  • 如果我保留多个属性,客户端会收到 500 内部服务器错误,并且永远无法到达 Post 方法的主体。

任何想法为什么会发生这种情况? 干杯

public class TaskViewModel
{

    //Default Constructor
    public TaskViewModel() { }


    public static TaskViewModel MakeTaskViewModel(Task task) 
    {
        return new TaskViewModel(task);
    }

    //Constructor
    private TaskViewModel(Task task)
    {
        this.TaskId = task.TaskID;
        this.Description = task.Description;
        this.StartDate = task.StartDate;
        this.Status = task.Status;
        this.ListID = task.ListID;
    }

    public Guid TaskId { get; set; }

    [Required]
    [StringLength(10)]
    public string Description { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    public System.DateTime StartDate { get; set; }

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

    public System.Guid ListID { get; set; }       
}

【问题讨论】:

    标签: validation asp.net-web-api model-binding


    【解决方案1】:

    您需要检查 500 内部服务器中的内容

    • 确保在 web.config 中关闭 customerror
    • 如果你自己托管 web.API 你需要设置GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
    • 使用浏览器开发控制台的网络选项卡(在 IE、Chrome 中,您可以使用 F12 获取控制台),或者如果您使用的是 FireFox,则使用 FireBug 或第三方工具,如 Fiddler

    然后你就可以看到服务器出了什么问题,进一步解决你的问题。

    在您的情况下,这是在响应中:

    "Message":"发生错误。","ExceptionMessage":"属性 'MvcApplication3.Controllers.TaskViewModel' 类型上的 'StartDate' 是 无效的。 标记为 [必需] 的值类型属性也必须是 标有 [DataMember(IsRequired=true)] 被识别为 必需。考虑使用 [DataContract] 赋予声明类型 和财产 [DataMember(IsRequired=true)].","ExceptionType":"System.InvalidOperationException"

    所以你的问题不是你有两个属性,而是你用[Required]标记你的属性来解决这个异常告诉你该怎么做。

    您需要将[DataMember(IsRequired=true)]添加到您需要的属性中,其中属性类型是值类型(例如int、datatime等):

    因此,将您的 TaskViewModel 更改为:

    [DataContract]
    public class TaskViewModel
    {
    
        //Default Constructor
        public TaskViewModel() { }
    
        [DataMember]
        public Guid TaskId { get; set; }
    
        [Required]
        [DataMember]
        [StringLength(10)]
        public string Description { get; set; }
    
        [Required]
        [DataMember(IsRequired = true)]
        [DataType(DataType.DateTime)]
        public System.DateTime StartDate { get; set; }
    
        [Required]
        [DataMember]
        public string Status { get; set; }
    
        [DataMember]
        public System.Guid ListID { get; set; }
    }
    

    一些旁注:

    • 您需要引用 System.Runtime.Serialization dll 才能使用DataMemberAttribute
    • 您需要用[DataContract] 标记您的类,并且您需要用[DataMember] 标记它的所有属性,而不仅仅是必需的。

    【讨论】:

    • 很好,问题已解决。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 2016-12-21
    相关资源
    最近更新 更多