我正在尝试绑定一些由字符串键索引的查询字符串参数,但是我似乎无法使其工作
这是我尝试绑定的值
search[value]: Exception happ...
search[regex]: false
这是我要与之绑定的模型
getLogsAjax(DataTableAjaxPostModel model)
public class DataTableAjaxPostModel
{
public int draw { get; set; }
public int start { get; set; }
public int length { get; set; }
public List<Column> columns { get; set; }
public search search { get; set; }
public List<Order> order { get; set; }
}
public class search
{
public string value { get; set; }
public string regex { get; set; }
}
除搜索类对象外,其余模型均已正确绑定,我对请求中包含该对象的值进行了三倍检查,我在这里遗漏了什么? ps。相同的代码据说可以在.net核心之前运行
答案 0 :(得分:3)
更多的代码背景将对您有所帮助,例如实际上正在执行绑定的代码部分,但这是一个带查询参数绑定的dotnetcore控制器示例。在C#中,类名和字段都是大写FYI。
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
[Route("api/[controller]")]
public class SampleController : Controller
{
[HttpGet]
[Route("")]
public IActionResult ExampleGet([FromQuery] DataTableAjaxPostModel dataTableAjaxPostModel)
{
// You should be able to debug and see the value here
var result = dataTableAjaxPostModel.search;
return Ok();
}
public class DataTableAjaxPostModel
{
public int draw { get; set; }
public int start { get; set; }
public int length { get; set; }
public List<Column> columns { get; set; }
public search search { get; set; }
public List<Order> order { get; set; }
}
public class search
{
public string value { get; set; }
public string regex { get; set; }
}
}
答案 1 :(得分:0)
似乎没有人对此有一个答案,所以我走了一条不同的路线,写了我自己的自定义活页夹,如果有更好的答案,我会接受它而不是这个,那么以后可能会重构它(哈哈哈IKR!)
public class DTModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException(nameof(bindingContext));
try
{
var result = new DataTableAjaxPostModel();
if (bindingContext.HttpContext.Request.Query.Keys.Contains("draw"))
result.draw = int.Parse(bindingContext.ValueProvider.GetValue("draw").FirstValue);
if (bindingContext.HttpContext.Request.Query.Keys.Contains("search[value]") &&
bindingContext.HttpContext.Request.Query.Keys.Contains("search[regex]"))
result.search = new search()
{
regex = bindingContext.ValueProvider.GetValue("search[regex]").FirstValue,
value = bindingContext.ValueProvider.GetValue("search[value]").FirstValue
};
//...
bindingContext.Result = ModelBindingResult.Success(result);
}
catch
{
bindingContext.Result = ModelBindingResult.Failed();
}
return Task.CompletedTask;
}
}
答案 2 :(得分:0)
DataTableAjaxPostModel
的属性)。这是因为它们将由内置模型绑定程序完成。实施
创建自定义资料夹QueryStringDictSyntaxBinder<TModel>
:
internal class QueryStringDictSyntaxBinder<TModel> : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException(nameof(bindingContext));
try
{
var result = Activator.CreateInstance<TModel>();
foreach(var pi in typeof(TModel).GetProperties())
{
var modelName = bindingContext.ModelName;
var qsFieldName = $"{modelName}[{pi.Name}]";
var field= bindingContext.HttpContext.Request.Query[qsFieldName].FirstOrDefault();
if(field != null){
pi.SetValue(result,field);
}
// do nothing if null , or add model binding failure messages if you like
}
bindingContext.Result = ModelBindingResult.Success(result);
}
catch
{
bindingContext.Result = ModelBindingResult.Failed();
}
return Task.CompletedTask;
}
}
然后用search
装饰[ModelBinder(typeof(QueryStringDictSyntaxBinder<search>))]
属性:
public class DataTableAjaxPostModel { public int draw { get; set; } public int start { get; set; } public int length { get; set; } public List columns { get; set; } [ModelBinder(typeof(QueryStringDictSyntaxBinder<search>))] public search search { get; set; } public List order { get; set; } }
测试用例:
我通过以下请求对其进行了测试,并且对我来说效果很好:
?draw=1&search[value]=abc&search[regex]=(.*)&
?draw=1&sEarCh[value]=opq&Search[regex]=([^123]*)&
?draw=1&seaRch[value]=rst&Search[regex]=(.*)&
?draw=1&Search[value]=abc&
?draw=1&