十进制和Nancy模型绑定的全球化问题

时间:2012-09-13 18:09:42

标签: model-binding nancy

我是Nancy的新手,我正在尝试使用Nancy.ModelBinding命名空间绑定一个十进制属性,如下所示:

var model = this.Bind<AddPaymentModel>();

我的应用程序正在使用非美国文化(pt-BR),其中小数的表示方式不同(4.50将是4,50)并且上面的代码会引发错误,即使将CurrentCulture正确设置为pt-BR也是如此。我发布了JSON,我认为它可能与JSON反序列化器有关...

我的堆栈跟踪的一部分:

Nancy.RequestExecutionException: Oh noes! ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: 450,00 is not a valid value for Decimal. ---> System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
at System.Decimal.Parse(String s, NumberStyles style, IFormatProvider provider)
at System.ComponentModel.DecimalConverter.FromString(String value, NumberFormatInfo formatInfo)
at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
--- End of inner exception stack trace ---
at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at System.ComponentModel.TypeConverter.ConvertFromInvariantString(String text)
at Nancy.Json.JavaScriptSerializer.ConvertToType(Type type, Object obj)
at Nancy.Json.JavaScriptSerializer.ConvertToObject(IDictionary`2 dict, Type type)
at Nancy.Json.JavaScriptSerializer.ConvertToType(Type type, Object obj)
at Nancy.Json.JavaScriptSerializer.ConvertToType[T](Object obj)
at Nancy.Json.JavaScriptSerializer.Deserialize[T](String input)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Nancy.ModelBinding.DefaultBodyDeserializers.JsonBodyDeserializer.Deserialize(String contentType, Stream bodyStream, BindingContext context)
at Nancy.ModelBinding.DefaultBinder.DeserializeRequestBody(BindingContext context)
at Nancy.ModelBinding.DefaultBinder.Bind(NancyContext context, Type modelType, String[] blackList)

我错过了什么?

1 个答案:

答案 0 :(得分:0)

您可以尝试切换到Nancy的Newtonsoft.JsonNet序列化程序。

http://nuget.org/packages/Nancy.Serialization.JsonNet

这是一个“全部捕获”示例实现

using System;
using System.Collections.Generic;
using Nancy;
using Nancy.Bootstrapper;
using Nancy.Serialization.JsonNet;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Application
{
    public class Bootstrapper : DefaultNancyBootstrapper
    {

        protected override NancyInternalConfiguration InternalConfiguration
        {
            get
            {
                return NancyInternalConfiguration.WithOverrides(
                c => c.Serializers.Insert(0, typeof(ModifiedJsonNetJsonSerializer)));
            }
        }

        public class ModifiedJsonNetJsonSerializer : JsonNetSerializer
        {
            public ModifiedJsonNetJsonSerializer()
                : base(new List<JsonConverter> { new FloatConverter() })
            { }

            public class FloatConverter : JsonConverter
            {
                public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
                {
                    var floatValue = (float)value;
                    writer.WriteValue(string.Format("{0:0.00}", floatValue));
                }

                public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
                {
                    var jobject = JToken.Load(reader);
                    var str = jobject.Value<string>();
                    float number;
                    try
                    {
                        number = float.Parse(str);
                    }
                    catch (FormatException)
                    {
                        str = str.IndexOf(".", StringComparison.Ordinal) > -1 ? str.Replace('.', ',') : str.Replace(',', '.');
                        number = float.Parse(str);
                    }
                    return number;
                }

                public override bool CanConvert(Type objectType)
                {
                    return objectType == typeof(float) || objectType == typeof(Single);
                }
            }
        }
    }
}