我在尝试使自定义模型绑定程序作为查询参数时遇到问题,就像我以前在.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}");
}
}
答案 0 :(得分:2)
我认为,如果设置模型绑定操作结果的语句缺失了,正如您在文档this section中的AuthorEntityBinder
代码示例中看到的那样:
bindingContext.Result = ModelBindingResult.Success(model);
您对模型绑定器的实现确实创建了SearchModel
的实例,但是没有将其反馈回模型绑定上下文。
另外,我不认为您需要添加自定义模型绑定程序,因为查询字符串段与您要绑定的模型的属性名称匹配。