如果有效负载包含意外字段,如何返回错误请求



我正在尝试进行 PATCH 操作,如果请求正文包含合同中未指定的字段,则应失败。例如,如果我调用此方法:

[HttpPatch("{id}")]
public async Task<ActionResult> PatchResource(
[FromRoute][Required] Guid id,
[FromBody][Required] PatchRequest request) {/* whatever */}

PatchRequest在哪里

public class PatchRequest
{
public string Name { get; }
public string Address { get; }
public PatchRequest(string name, string address) { Name = name; Address = address; }
}

我想返回400 (Bad Request),如果我得到这样的请求正文,可能会有解释

{
"name": "Adam",
"address" "NY City",
"additional": true
}

我想回来

400(错误要求( - 没想到物业"额外">

我知道,如果我在PatchRequest上设置自定义序列化程序并将MissingMemberHandling设置为Error在这种情况下,我可以通过抛出异常轻松获得500 (Internal Server Error),但这没有意义,因为这里是请求,而不是服务器。

PatchRequest模型中,添加一个 JsonExtensionsData 属性

public class PatchRequest
{
public string Name { get; }
public string Address { get; }
public PatchRequest(string name, string address) { Name = name; Address = address; }
// extra fields
[JsonExtensionData]
private IDictionary<string, JToken> _extraStuff;
}

然后在控制器中,如果_extraStuff不为空,则会收到其他字段。

以下功能将准确返回哪些属性与FromBody中定义的对象不同

创建一个类,例如ValidationBase

在类中,创建一个方法来验证您的对象,例如ValidateModel()

ValidateModel()- 包含验证的整个逻辑

控制器:(终结点(

[HttpPatch("{id}")]
public async Task<ActionResult> PatchResource([FromRoute][Required] Guid id, 
[FromBody][Required] PatchRequest request)
{
string body;
using (var reader = new StreamReader(Request.Body))
{
body = reader.ReadToEnd();
}
validator = new ValidationBase();
string resultValidation = validator.ValidateObject(body, new PatchRequest());
if (resultValidation.Length != 0)
{
return BadRequest(new { error_message = resultValidation });
}
// Content endpoint
return Json(response);
}

验证库:

public class ValidationBase
{
public string ValidateObject(string json, object obj)
{
var dictJSON = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
var listParameterInJSON = dictJSON.Keys.ToHashSet<string>();
listParameterInJSON.ToList().ForEach(x => x = x.ToLower());
var jsonObj = JsonConvert.SerializeObject(obj);
var dictObj = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonObj);
var listParameterInObj = dictObj.Keys.ToList();
listParameterInObj = listParameterInObj.ConvertAll(d => d.ToLower());
listParameterInObj.ToHashSet<string>();
var fields = listParameterInJSON.Except(listParameterInObj);
if (fields.ToList().Count == 0) return "";
var result = "Didn't expect property ";
foreach (var item in fields)
{
result += "'" + item + "'" + " ";
}
return result;
}
}

最新更新