Decimal decoding user interface in ASP.NET

I have a web api application using asp.net mvc web api that get some decimal numbers in viewmodels models. I would like to create a custom mediator for the decimal type and make it work for all decimal numbers. I have a viewModel like this:

 public class ViewModel { public decimal Factor { get; set; } // other properties } 

And the external application can send json with an invalid decimal number, for example: 457945789654987654897654987.79746579651326549876541326879854

I would like to respond with a 400 - Bad Request error and a custom message. I tried to create a custom mediator that implements System.Web.Http.ModelBinding.IModelBinder and register on global.asax, but it does not work. I would like to make it work for all decimal places in my code, see what I tried:

 public class DecimalValidatorModelBinder : System.Web.Http.ModelBinding.IModelBinder { public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { var input = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (input != null && !string.IsNullOrEmpty(input.AttemptedValue)) { if (bindingContext.ModelType == typeof(decimal)) { decimal result; if (!decimal.TryParse(input.AttemptedValue, NumberStyles.Number, Thread.CurrentThread.CurrentCulture, out result)) { actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, ErrorHelper.GetInternalErrorList("Invalid decimal number")); return false; } } } return true; //base.BindModel(controllerContext, bindingContext); } } 

Adding on Application_Start :

 GlobalConfiguration.Configuration.BindParameter(typeof(decimal), new DecimalValidatorModelBinder()); 

What can I do? Thanks.

+4
source share
2 answers

By default, the Web API reads a complex type from the request body using a media type formatter. In this case, it does not pass the model binder.

+5
source

for JSON, you can create a JsonConverter (if you are using JSON.NET by default:

 public class DoubleConverter : JsonConverter { public override bool CanWrite { get { return false; } } public override bool CanConvert(Type objectType) { return (objectType == typeof(double) || objectType == typeof(double?)); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JToken token = JToken.Load(reader); if (token.Type == JTokenType.Float || token.Type == JTokenType.Integer) { return token.ToObject<double>(); } if (token.Type == JTokenType.String) { // customize this to suit your needs var wantedSeperator = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator; var alternateSeparator = wantedSeperator == "," ? "." : ","; double actualValue; if (double.TryParse(token.ToString().Replace(alternateSeparator, wantedSeperator), NumberStyles.Any, CultureInfo.CurrentCulture, out actualValue)) { return actualValue; } else { throw new JsonSerializationException("Unexpected token value: " + token.ToString()); } } if (token.Type == JTokenType.Null && objectType == typeof(double?)) { return null; } if (token.Type == JTokenType.Boolean) { return token.ToObject<bool>() ? 1 : 0; } throw new JsonSerializationException("Unexpected token type: " + token.Type.ToString()); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException("Unnecessary because CanWrite is false. The type will skip the converter."); } } 
0
source

Source: https://habr.com/ru/post/1494361/


All Articles