Эта проблема сводит меня с ума.
У меня есть метод получения, который принимает массив идентификаторов с пользовательским ModelBinder (я могу вызвать http://xckvjl.com/api/results/1,23,34,)
Я хочу представить Gets по действиям. (чтобы я мог вызывать как http://alskjdfasl.com/api/results/latest)
У меня есть следующая маршрутизация веб-API.
config.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional });
config.Routes.MapHttpRoute("ApiWithAction", "{controller}/{action}");
Я пробовал с (Обратите внимание, что я использую свою собственную модель связывателя)
config.Routes.MapHttpRoute("DefaultApi", "{controller}/{id}", new { id = RouteParameter.Optional }, new {id = @"\d+" });
Вы можете воспроизвести эту ошибку с помощью этого примера:
public class TestController: ApiController {
[HttpGet]
public virtual IHttpActionResult Get([ModelBinder(typeof(CommaDelimitedCollectionModelBinder))]IEnumerable<int> id = null )
{ }
[HttpGet]
public virtual IHttpActionResult Latest( )
{ }
}
public class CommaDelimitedCollectionModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext,
ModelBindingContext bindingContext)
{
var key = bindingContext.ModelName;
var val = bindingContext.ValueProvider.GetValue(key);
if (val == null)
{
return false;
}
var s = val.AttemptedValue;
if (s != null && s.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Length > 0)
{
var array = s.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select( n=>Convert.ToInt32(n)).ToArray();
Type type = bindingContext.ModelType.GetGenericArguments().First();
var typeValue = Array.CreateInstance(type, array.Length);
array.CopyTo(typeValue, 0);
bindingContext.Model = array;
}
else
{
bindingContext.Model = new[] { s };
}
return true;
}
}
Если я напишу как:
[HttpGet]
[Route("Tests/latest")]
public virtual IHttpActionResult Latest( )
{ }
Оно работает. Однако я хочу маршрутизацию на глобальном уровне. Иначе для каждого действия мне придется писать одно и то же.
Пожалуйста, порекомендуйте.