У меня есть контроллер
[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 следует присвоить значение по умолчанию, то есть одежду. Если я вызываю контроллер как api / products / 1? PType = somegarbagevalue, тогда контроллер должен генерировать исключение неверного запроса. Как я могу этого добиться?
3 ответа
Вы должны иметь дело с 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
не может связать значение.
Этот тип проверки должен выполняться в конвейере, а не в контроллере.
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 для подробного объяснения
Определение всех параметров перечисления в виде строк с последующим их анализом повсюду означает, что вы должны делать это для каждого отдельного действия , и вам нужно будет разработать последовательный подход, чтобы все ошибки синтаксического анализа соответствовали друг другу.
Это проблема привязки параметров, и ее не следует решать на уровне контроллера, о ней следует позаботиться в конвейере. Один из способов сделать это - создать собственный фильтр и добавить его в конфигурацию.
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>
}
}
});
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.
TypeEnum
из вопроса? Я задал связанный вопрос, который также связан с вашим.