.Net Core API 控制器接受表单或正文数据 [英] .Net Core API Controller Accept Form or Body Data

查看:139
本文介绍了.Net Core API 控制器接受表单或正文数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 API 操作,我希望它接受表单数据或原始 JSON.

I have an API action and I want it to accept either Form Data or raw JSON.

这是我的功能

    [HttpPost]
    public async Task<IActionResult> ExternalLogin([FromForm]ExternalLoginModel formModel, [FromBody]ExternalLoginModel bodyModel)
    {

所以我希望他们能够以两种不同的方式发送相同的数据,当我使用 form-data 尝试这种方法时,我收到了 415 错误.当我尝试使用原始 JSON 时,它工作正常.

So I want them to be able to send the same data in two different ways, when I try this method with form-data I get a 415 error. When I try it with raw JSON it works fine.

我希望能够将其保留在一个函数中,但如果我必须将其拆分为两个函数,那就这样吧.

I would like to be able to keep it in one function but if I have to break it out into two so be it.

推荐答案

不幸的是,如果主体模型绑定器无法解析请求主体,它会将请求短路,而不是简单地跳过与操作参数的绑定.

Unfortunately, if the body model binder can't parse the request body, it short circuits the request instead of simply skipping the binding to the action parameter.

>

如果您真的想在一个操作中处理两种内容类型,您可以为身体模型绑定器实现一个输入格式化程序来绕过此行为.如果请求具有表单内容类型,它可以通过假装绑定成功来实现.

If you really wanted to handle both content types in one action, you could implement an input formatter for the body model binder that bypasses this behavior. It can do so by pretending the binding was successful, if the request has a form content type.

格式化程序本身很简单:

The formatter itself is simple:

/// <summary>
/// This input formatter bypasses the <see cref="BodyModelBinder"/> by returning a null result, when the request has a form content type.
/// When registered, both <see cref="FromBodyAttribute"/> and <see cref="FromFormAttribute"/> can be used in the same method.
/// </summary>
public class BypassFormDataInputFormatter : IInputFormatter
{
    public bool CanRead(InputFormatterContext context)
    {
        return context.HttpContext.Request.HasFormContentType;
    }

    public Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
    {
        return InputFormatterResult.SuccessAsync(null);
    }
}

在你的启动类中,需要添加格式化程序:

In your startup class, the formatter needs to be added:

services.AddMvc(options =>
{
    options.InputFormatters.Add(new BypassFormDataInputFormatter());
});

在您的操作中,您仍然需要检查实际填充了两个参数中的哪一个:

In your action you would still need to check which of the two parameters actually have been populated:

[HttpPost]    
public async Task<IActionResult> ExternalLogin([FromForm] ExternalLoginModel formModel, [FromBody] ExternalLoginModel bodyModel)
{
    ExternalLoginModel model;

    // need to check if it is actually a form content type, as formModel may be bound to an empty instance
    if (Request.HasFormContentType && formModel != null)
    {
        model = formModel;
    }
    else if (bodyModel != null)
    {
        model = bodyModel;
    }

    ...

这篇关于.Net Core API 控制器接受表单或正文数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆