自定义模型绑定程序提供程序始终为.net核心为空

时间:2018-07-29 22:24:40

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

我在尝试使自定义模型绑定程序作为查询参数时遇到问题,就像我以前在.net Framework 4.7中工作一样。

为确保这不是我的对象过于复杂的情况,我将模型简化为一个简单的字符串,但即使这样我也无法使它正常工作。

我有一个简单的模型,希望与查询参数绑定。

public class SearchModel {
    public string SearchTerms { get; set; }
}

我已经像here所示配置了ModelBinder和ModelBinderProvider。

public class TestModelBinder : IModelBinder {
    public Task BindModelAsync(ModelBindingContext bindingContext) {
        if (bindingContext.ModelType != typeof(SearchModel)) {
            throw new ArgumentException($"Invalid binding context supplied {bindingContext.ModelType}");
        }

        var model = (SearchModel)bindingContext.Model ?? new SearchModel();

        var properties = model.GetType().GetProperties();
        foreach(var p in properties) {
            var value = this.GetValue(bindingContext, p.Name);
            p.SetValue(model, Convert.ChangeType(value, p.PropertyType), null);
        }

        return Task.CompletedTask;
    }

    protected string GetValue(ModelBindingContext context, string key) {
        var result = context.ValueProvider.GetValue(key);

        return result.FirstValue;
    }
}

public class TestModelBinderProvider : IModelBinderProvider {
    public IModelBinder GetBinder(ModelBinderProviderContext context) {
        if (context == null) {
            throw new ArgumentNullException(nameof(context));
        }

        if (context.Metadata.ModelType == typeof(SearchModel)) {
            var returnType = new BinderTypeModelBinder(typeof(TestModelBinder));
            return returnType;
        }

        return null;
    }
}

如Microsoft文档的最后一步所述,我在Startup.cs中更新了ConfigureServices方法以包括BinderProvider。

services.AddMvc(options => {
            options.ModelBinderProviders.Insert(0, new TestModelBinderProvider());
        })
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

但是,当我使用诸如“ https://localhost:44387/api/testbinding?searchTerms=newSearch”之类的网址调用Search端点时,尽管我看到它正确地击中了自定义绑定并正确绑定,但我总是看到返回“ request == null True”我会逐步调试,有人能指出我做错了什么吗?

[Route("api/[controller]")]
[ApiController]
public class TestBindingController : ControllerBase {

    [HttpGet()]
    public IActionResult GetResult([FromQuery] SearchModel request) {
        return Ok($"request == null {request == null}");
    }

}

1 个答案:

答案 0 :(得分:2)

我认为,如果设置模型绑定操作结果的语句缺失了,正如您在文档this section中的AuthorEntityBinder代码示例中看到的那样:

bindingContext.Result = ModelBindingResult.Success(model);

您对模型绑定器的实现确实创建了SearchModel的实例,但是没有将其反馈回模型绑定上下文。


另外,我不认为您需要添加自定义模型绑定程序,因为查询字符串段与您要绑定的模型的属性名称匹配。