Параметр asp.net webapi enum со значением по умолчанию
У меня есть контроллер
[HttpGet]
[RoutePrefix("api/products/{productId}")]
public HttpResponseMessage Products(int productId,TypeEnum ptype=TypeEnum.Clothes)
{
if(!Enum.IsDefined(typeOf(TypeEnum),ptype))
//throw bad request exception
else
//continue processing
}
Myenum объявлен как
public TypeEnum
{
Clothes,
Toys,
Electronics
}
В настоящее время, если передано некоторое значение мусора, оно преобразуется в значение по умолчанию.
Я хочу сделать это, если я вызову контроллер как api/products/1, тогда ptype следует присвоить значение по умолчанию i.e. Если я вызову контроллер как api/products/1? PType = somegarbagevalue, тогда контроллер должен выбросить исключение с помощью "плохого запроса". Как я могу достичь этого?
Ответы
Ответ 1
Вы должны использовать string
и использовать TryParse()
для преобразования строки в значение Enum
.
public HttpResponseMessage Products(int productId,string ptype="Clothes")
{
TypeEnum category = TypeEnum.Clothes;
if(!Enum.TryParse(ptype, true, out category))
//throw bad request exception if you want. but it is fine to pass-through as default Cloathes value.
else
//continue processing
}
Это может показаться наивным, но преимущество этого подхода состоит в том, чтобы разрешить параметр ptype
для любой строки и выполнять процесс без исключения, когда ptype
не удалось привязать значение.
Ответ 2
Определение всех параметров перечисления в виде строк, а затем их разбор по всему миру означает, что вы должны делать это на каждом отдельном действии, и вам нужно будет разработать последовательный подход, чтобы соответствовали всем ошибкам синтаксического анализа.
Это проблема с привязкой параметров и не должна рассматриваться на уровне контроллера, ее следует позаботиться о ней. Один из способов сделать это - создать настраиваемый фильтр и добавить его в свою конфигурацию.
public class ModelStateValidationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
actionContext.Response = <your standardised error response>
}
}
}
И в вашем файле global.asax.cs
...
GlobalConfiguration.Configure(WebApiConfig.Register);
...
public class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
...
config.Filters.Add(new ModelStateValidationAttribute());
...
}
}
Если у вас возникли проблемы с состоянием модели, это тип ModelStateDictionary, и вы просто перебираете его, а затем свойство Errors содержит все связанные с моделью проблемы. например.
modelState = actionContext.ModelState;
modelState.ForEach(x =>
{
var state = x.Value;
if (state.Errors.Any())
{
foreach (var error in state.Errors)
{
<work your magic>
}
}
});
Ответ 3
Этот тип проверки должен обрабатываться в конвейере, а не в контроллере.
public abstract class ETagMatchAttribute : ParameterBindingAttribute
{
private ETagMatch _match;
public ETagMatchAttribute(ETagMatch match)
{
_match = match;
}
public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
{
if (parameter.ParameterType == typeof(ETag))
{
return new ETagParameterBinding(parameter, _match);
}
return parameter.BindAsError("Wrong parameter type");
}
}
что-то вроде этого. обратитесь к ссылке MSDN для подробного объяснения