更新时间:2023-02-15 22:50:32
You might be able to achieve what you're looking for with a custom IActionConstraint
:
从概念上讲,IActionConstraint是一种重载形式,但它是在具有相同URL的操作之间重载,而不是重载具有相同名称的方法.
Conceptually, IActionConstraint is a form of overloading, but instead of overloading methods with the same name, it's overloading between actions that match the same URL.
我对此做了一些尝试,并提出了以下IActionConstraint
实现:
I've had a bit of a play with this and have come up with the following IActionConstraint
implementation:
public class FormContentTypeAttribute : Attribute, IActionConstraint
{
public int Order => 0;
public bool Accept(ActionConstraintContext ctx) =>
ctx.RouteContext.HttpContext.Request.HasFormContentType;
}
如您所见,这非常简单-它只是检查传入的HTTP请求是否为内容类型形式.为了使用此功能,您可以为相关操作指定属性.这是一个完整的示例,其中还包括此 answer ,但使用您的操作:
As you can see, it's very simple - it's just checking whether or not the incoming HTTP request is of a form content-type. In order to use this, you can attribute the relevant action. Here's a complete example that also includes the idea suggested in this answer, but using your action:
[HttpPost]
[FormContentType]
public ActionResult<Data> PostFromForm([FromForm] Data data) =>
DoPost(data);
[HttpPost]
public ActionResult<Data> PostFromBody([FromBody] Data data) =>
DoPost(data);
private ActionResult<Data> DoPost(Data data) =>
new ActionResult<Data>(data);
由于使用了[ApiController]
,因此
[FromBody]
在上面是可选的,但在示例中我将其包含为明确内容.
[FromBody]
is optional above, due to the use of [ApiController]
, but I've included it to be explicit in the example.
也来自文档:
...带有IActionConstraint的动作总是比不带有IActionConstraint的动作好.
...an action with an IActionConstraint is always considered better than an action without.
这意味着当传入的请求不是内容类型的形式时,我显示的FormContentType
属性将排除该特定操作,因此使用PostFromBody
.否则,如果是表单内容类型,则PostFromForm
动作将因其被认为更好"而获胜.
This means that when the incoming request is not of a form content-type, the FormContentType
attribute I've shown will exclude that particular action and therefore use the PostFromBody
. Otherwise, if it is of a form content-type, the PostFromForm
action will win due to it being "considered better".
我已经在相当基本的水平上进行了测试,它确实可以满足您的需求.在某些情况下,它可能不太适合,所以我鼓励您尝试一下它,看看可以在哪里使用.我完全希望您会发现它完全崩溃的情况,但是仍然值得探索.
I've tested this at a fairly basic level and it does appear to do what you're looking for. There may be cases where it doesn't quite fit so I'd encourage you to have a play with it and see where you can go with it. I fully expect that you may find a case where it falls over completely, but it's an interesting idea to explore nonetheless.
最后,如果您不想使用某个属性,则可以配置一个约定,例如使用反射来查找具有[FromForm]
属性的动作并自动添加约束.这篇出色的帖子关于该主题.
Finally, if you don't like having to use an attribute, it is possible to configure a convention that could e.g. use reflection to find actions with a [FromForm]
attribute and automatically add the constraint. There are more details in this excellent post on the topic.