ASP.NET Core MVC - 模型绑定:使用属性[FromBody](BodyModelBinder)绑定接口模型

时间:2017-07-26 15:53:18

标签: asp.net-core asp.net-core-mvc model-binding

我想将我的action方法中的接口模型与content-type为application / json的请求绑定。我在我的操作方法中使用[FromBody]属性。

我尝试通过以下链接创建一个派生自ComplexTypeModelBinder的自定义modelBinder:Custom Model Binding in Asp.net Core, 3: Model Binding Interfaces,但它不起作用,我的模型始终为null。之后我了解到当你使用atribute [FromBody]时,会调用BodyModelBinder并在内部调用JsonInputFormatter并且它不会使用自定义的modelBinder。

我正在寻找一种绑定我的界面模型的方法。我可以使用MVC DI将每个接口映射到其实现。我的操作方法定义为:

public async Task<IActionResult> Create(IOperator user)
    {
        if (user == null)
        {
            return this.BadRequest("The user can't not be null");
        }

        if (!this.ModelState.IsValid)
        {
            return this.BadRequest(this.ModelState);
        }

            IOperator op = await this.AuthenticationFrontService.CreateOperatorAsync(user.Login, user.Password, user.FirstName, user.LastName, user.ValidUntil, user.Role, user.Comment);
        return new CreatedAtActionResult("Get", "operators", new { id = ((Operator)op).Id }, op);
    }

我在我的界面中使用MetadataType属性尝试了另一种解决方案,但它没有存在于命名空间System.ComponentModel.DataAnnotations中,我读到asp.net核心mvc没有使用此属性{{ 3}}。我不想在域模型项目中安装microsoft.aspnetcore.mvc.dataannotations包以使用ModelDataType属性。

我通过创建自定义JsonInputFormater尝试了另一种解决方案,换句话说,我派生了类JsonInputFormatter,并通过分析源代码,我发现JsonSerializer无法反序列化逻辑上的接口。所以我正在寻找一个解决方案,我可以通过使用旋转变压器或通用转换器来定制jsonserializer。

任何帮助都将非常感谢。

感谢。

2 个答案:

答案 0 :(得分:1)

使用接口适用于C#方法,但MVC需要知道在调用Action时它应该实例化的具体类型,因为它正在创建它。它不知道使用什么类型,因此它无法将Form / QueryString / etc中的输入绑定到。创建一个非常基本的模型,用于您的操作,除了实现您的界面IOperator之外什么都不做,如果您的目标是保持苗条,并将其设置为您的Action参数,它应该可以正常工作。

我也试过在一个动作上使用一个接口,并且通过我自己的搜索,我发现没有办法让它工作,除了使用类而不是接口来绑定。

public class Operator : IOperator
{
    //Implement interface
}

public async Task<IActionResult> Create(Operator user)
{
    if (user == null)
    {
        return this.BadRequest("The user can't not be null");
    }

    if (!this.ModelState.IsValid)
    {
        return this.BadRequest(this.ModelState);
    }

        IOperator op = await this.AuthenticationFrontService.CreateOperatorAsync(user.Login, user.Password, user.FirstName, user.LastName, user.ValidUntil, user.Role, user.Comment);
    return new CreatedAtActionResult("Get", "operators", new { id = ((Operator)op).Id }, op);
}

答案 1 :(得分:0)