目标:我正在设计一个REST API,允许用户在查询字符串上传递HTTP GET请求的参数。像
这样的东西http://fake.api.com/search?param1=123¶m2=car&pageSize=10
实现:在服务器端,我有一个自定义模型绑定器,它从请求查询字符串中获取参数并将它们转换为C#对象,这样我的控制器操作方法就不必解析查询字符串。 所以控制器动作方法签名看起来像
public async Task<HttpResponseMessage> Get([ModelBinder]RequestObject request)
当我从Fiddler测试api并传递查询字符串值时,自定义模型绑定器工作,我在控制器操作中获得了具有正确值的c#对象。
但是当我使用Swagger进行测试时,不会调用modelbinder并且action参数中的值为null。模型参数单独显示,而不是显示模型。
我该如何解决这个问题?
我的自定义模型绑定器:
public class RequestObjectModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(RequestObject))
{
return false;
}
var searchCriteria = new RequestObject();
var type = searchCriteria.GetType();
var querystringVals = actionContext.Request.GetQueryNameValuePairs();
var keyValuePairs = querystringVals as IList<KeyValuePair<string, string>> ?? querystringVals.ToList();
if (!keyValuePairs.Any())
{
bindingContext.Model = searchCriteria;
return true;
}
foreach (var value in keyValuePairs)
{
var key = value.Key;
var prop = type.GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if (prop == null)
{
continue;
}
prop.SetValue(searchCriteria, Convert.ChangeType(value.Value,prop.PropertyType), null);
}
var validationResults = new Collection<ValidationResult>();
var isValid = Validator.TryValidateObject(searchCriteria, new ValidationContext(searchCriteria, null, null), validationResults, true);
if (!isValid)
{
foreach (var result in validationResults)
{
bindingContext.ModelState.AddModelError("", result.ErrorMessage);
}
}
bindingContext.Model = searchCriteria;
return true;
}
答案 0 :(得分:0)
[HttpGet]
public async Task<HttpResponseMessage> Get([FromUri]RequestObject request)
给定RequestObject
的工作是否具有以下签名:
public class RequestObject
{
public string param1 { get; set; }
public string param2 { get; set; }
public int pageSize { get; set; }
}
如果你只有这三个参数并且很少使用它们,你也可以这样做:
public async Task<HttpResponseMessage> Get(
[FromUri(Name="param1")] string parameterOne,
[FromUri(Name="param2")] string parameterTwo,
[FromUri(Name="pageSize")] int pageSize)
请注意查询字符串名称与方法参数名称的不同之处。
<强>更新强>
您似乎缺少使用自定义模型绑定器标记方法或类,例如
public async Task<HttpResponseMessage> Get([ModelBinder(typeof(RequestObjectModelBinder)]RequestObject request)
如果你使用一次以上的课程,你也可以标记实际的课程,例如
[ModelBinder(typeof(RequestObjectModelBinder)
public class RequestObject {}
答案 1 :(得分:-2)
试试这个: -
public async Task<HttpResponseMessage> Get([FromUri][ModelBinder]RequestObject request)