【发布时间】:2019-01-22 09:24:11
【问题描述】:
我有一个 web api,其中包含一些应该同时接收数据和文件的操作。为此,我接受 multipart/form-data 而不是 JSON 并使用 [FromForm] 绑定到模型:
[Authorize(Policy = "MyCustomPolicy")]
public async Task<IActionResult> Create([FromForm]MyCustomDto myDto)
{
// Do some stuff here
}
public class MyCustomDto
{
public int Id { get; set; }
public string Title { get; set; }
public IEnumerable<IFormFile> Attachments { get; set; }
}
这工作正常并且正确绑定到 DTO。
使用 AuthorizationHandler 检查和执行该策略,该处理程序也可以正常工作。
在上述 AuthorizationHandler 中,我需要访问传递给控制器的一些内容,例如路由中的 ID 或 DTO。
使用authContext.RouteData.Values["nameOfIdField"] 访问路线数据非常简单。
然而,对于正文,我创建了一个辅助扩展方法,用于读取正文流并对其进行反序列化:
public static async Task<T> DeserializeBody<T>(this AuthorizationFilterContext context, string name)
{
var content = string.Empty;
using(var reader = new StreamReader(context.HttpContext.Request.Body, System.Text.Encoding.UTF8, true, 1024, true))
{
content = await reader.ReadToEndAsync();
reader.BaseStream.Seek(0, SeekOrigin.Begin);
}
if (string.IsNullOrWhiteSpace(content))
{
return default(T);
}
return JsonConvert.DeserializeObject<T>(content);
}
同样,这也很好用。但是,现在我遇到了不作为 JSON 传递而是作为表单数据传递的 DTO(如开头所述)的问题。
正文的内容不是可以轻松序列化的 JSON:
-----------------------------7e2b13b820d4a
Content-Disposition: form-data; name="id"
232
-----------------------------7e2b13b820d4a
Content-Disposition: form-data; name="title"
test
-----------------------------7e2b13b820d4a
Content-Disposition: form-data; name="attachments"; filename="C:\Temp\Test.jpg"
Content-Type: image/jpeg
有什么方法可以轻松地将它绑定到我的 DTO,而无需手动解析它?
【问题讨论】:
-
也许在为你解析并创建数据之后,基于消息数据进行授权会更好?
-
@nvoigt 你有任何链接或资源吗?因为当我查找如何进行授权时,上面的解决方案(某种)是我发现的,没有其他方法。
-
我没有任何参考资料,但这似乎是常识......解析中间件中的所有不同消息并了解它们的语义将是一个巨大的泥球。只有实际的控制器才能知道您传递的 ItemId 是否需要检查读取访问或写入访问权限,因为这取决于它将如何处理它。
-
此外,在您的授权方法中复制所有用于数据传输的逻辑意味着您将所有这些作为一个大冗余。您不能只交换
[FromQuery]和[FromRoute],因为虽然看起来很简单,但您已经在隐藏的地方复制了该逻辑,它会失败。
标签: c# asp.net-web-api asp.net-core asp.net-authorization