使用正确的密钥名称

时间:2017-06-01 13:50:03

标签: c# asp.net-mvc validation asp.net-web-api modelstate

我有一个简单的模型:

public class Employer 
{
    [Required(ErrorMessage = "Please specify id")]
    public int Id { get; set; }

    [MaxLength(256, ErrorMessage = "Max lenght should be less than 256")]
    [Required(ErrorMessage = "Please specify Name")]
    public string Name { get; set; }

    [Required(ErrorMessage = "Please specify id of organization")]
    public int OrganizationId { get; set; }
}

然后控制器是:

public IHttpActionResult Post(Employer employer)
{
    if(!IsActiveOrganization(employer.OrganizationId))
    {
        ModelState.AddModelError(nameof(employer.OrganizationId), "The organization is not active!");
    }
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
}

正如您所看到的,我在创建新雇主之前尝试验证模型。因此,当我传递带有无效id的模型时,响应会像:

{
  "message": "The request is invalid.",
  "modelState": {
    "employer.Id": [
      "Please specify id."
    ]
  }
}

我想检查OrganizationId是否有效。为此,我有一个方法IsActiveOrganization,它检查并返回true/false。如果false那么我需要添加模型错误并向客户端返回400 Bad Request。一切正常但我实施的方式我会得到如下回应:

{
  "message": "The request is invalid.",
  "modelState": {
    "employer.Id": [
      "Please specify id"
    ],
    "OrganizationId": [
      "The organization is not active!"
    ]
  }
}

如何为我自己的错误employer.Id添加像OrganizationId这样的ModelState错误键的前缀?我应该有硬编码employer.OrganizationId还是有更好的方法?如果我需要添加模式详细信息,请告诉我。感谢。

3 个答案:

答案 0 :(得分:2)

虽然nameof非常适合避免硬编码属性名称,但它并非没有缺陷,而且您偶然发现了一个主要的:它只返回引用属性的名称,而不是完整的对象图你曾经访问它。如果你想避免硬编码,你必须做类似的事情:

ModelState.AddModelError($"{nameof(employer)}.{nameof(employer.OrganizationId)}", "Error message here");

它不是很漂亮,但它是你能做的最好的。

答案 1 :(得分:0)

尝试使用远程验证

    [Remote("Action", "controller" ErrorMessage = "ErrorMsg")]
    [Required(ErrorMessage = "Please specify id of organization")]
    public int OrganizationId { get; set; }

在你的行动中看起来像这样

public JsonResult Post(int OrganizationId )
{
    if(!IsActiveOrganization(OrganizationId ))
    {
        return Json(false, JsonRequestBehavior.AllowGet);
    }
    if (!ModelState.IsValid)
    {
        return Json(false, JsonRequestBehavior.AllowGet);
    }
}

答案 2 :(得分:0)

你可以为此创建自己的data attribute,如果你想要一些自定义名称,但你真的不需要这个,你可以写出你想要的名称AddModelError, 2个字符串,(string key, string Message)因此我认为它确实有所作为