Массив в параметре Get запроса
Допустим есть javascript get запрос на стороне клиента, где параметром передается массив значений типа integer:
// Используем jquery
var ids = [2,3,4,5];
$.getJSON("@Url.Content("api/Values")", { ids: ids })
.done(function (result) {
$(".result").text(result);
});
Этот код формирует такой запрос:
GET /api/Values?ids[]=2&ids[]=3&ids[]=4&ids[]=5
Если просто прописать нужные типы данных в действие контроллера (массив):
public string Get(int[] ids)
{
return "Success: " + string.Concat(ids);
}
То на стороне сервера вы получите ids = null;
Принцип работы Web API
- Для простых типов данных, Web API пытается получить значение из URI. Простые типы - это .NET примитивные типы (int, bool, double и так далее), а также TimeSpan, DateTime, Guid, и любые типы имеющие реализацию преобразования из строки.
- Сложные типы данных, в том числе коллекции простых типов Web API пытается прочитать из тела сообщения. (что не актуально для GET запроса)
Настройка привязки сложных типов в GET запросе
Вообще для сложных типов данных, не рекомендуется использоваться GET запросы. Ключевым принципом HTTP является то, что ресурсы направляются в теле сообщения, используя согласование содержимого для указания представления ресурса. Именно с этой целью были разработаны media-type formatters.
Но все же в .net есть реализация привязки из URI. Для этого к требуемому параметру со сложным типом данных нужно подставить атрибут [FromUri] или [ModelBinder]:
public string Get([FromUri]int[] ids)
{
return "Success: " + string.Concat(ids);
}
Теперь в ids будет ожидаемый массив значений.
Привязки [FromUri] и [ModelBinder]
FromUriAttribute просто является наследником от ModelBinderAttribute, предоставляя более короткую (и более понятную для разработчика) команду для Web API, чтобы брать определенные параметры из URI, используя ValueProviders, определенные в IUriValueProviderFactory. Сам атрибут не может иметь наследников.
[ModelBinder] предоставляет вам возможность реализации собственной логики преобразования входящих значений запроса в типы данных CLR (тема для отдельной статьи).
Другие примеры использования атрибута привязки [FromUri]
Сложный тип:
public class TableFilter
{
public int Page { get; set; }
public int PageSize { get; set; }
public IList<SortType> Sort {get; set;}
}
public HttpResponseMessage Get([FromUri]TableFilter filter) {}
GET /table?page=1&pagesize=60&sort=field|asc
Коллекции типа List:
Коллекции типа ключ-значение:
GET /Values?items=first&items=second&items=third
public string Get([FromUri]List items) {}
Коллекции типа ключ-значение:
GET /values?key=stringkey&value=stringvalue
public string Get([FromUri]KeyValuePair id) {}
Привязка параметров из URI по умолчанию
Можно настроить Web API на обработку параметров GET запросов c помощью [FromUri] по умолчанию, для этого следует создать наследника от DefaultActionValueBinder:
public class MyActionValueBinder : DefaultActionValueBinder
{
protected override HttpParameterBinding GetParameterBinding(HttpParameterDescriptor parameter)
{
if(parameter.ActionDescriptor.SupportedHttpMethods.Contains(HttpMethod.Get)){
return parameter.BindWithAttribute(new FromUriAttribute());
}
return base.GetParameterBinding(parameter);
}
}
И заменить обработчик привязок по умолчанию в конфигурации Web API:
config.Services.Replace(typeof(IActionValueBinder), new MyActionValueBinder());
Теперь в примере с массивом из начала статьи мы можем опустить явное назначение атрибута [FromUri]:
public string Get(int[] ids)
{
return "Success: " + string.Concat(ids);
}
Комментариев нет:
Отправить комментарий