如何在控制器方法参数的值绑定期间使用ServiceStack.Text Json序列化程序对ASP.NET MVC请求中的字符串进行反序列化?
答案 0 :(得分:1)
我最终不得不写自定义课程。要使用下面的工厂,请使用以下代码更新您的Application_Start
ValueProviderFactories.Factories.Remove( ValueProviderFactories.Factories.OfType< JsonValueProviderFactory >().FirstOrDefault() );
ValueProviderFactories.Factories.Add( new JsonServiceStackValueProviderFactory() )
这对我有用:
public sealed class JsonServiceStackValueProviderFactory: ValueProviderFactory
{
public override IValueProvider GetValueProvider( ControllerContext controllerContext )
{
if( controllerContext == null )
throw new ArgumentNullException( "controllerContext" );
var jsonData = GetDeserializedObject( controllerContext );
if( jsonData == null )
return null;
var backingStore = new Dictionary< string, object >( StringComparer.OrdinalIgnoreCase );
AddToBackingStore( backingStore, String.Empty, jsonData );
return new DictionaryValueProvider< object >( backingStore, CultureInfo.CurrentCulture );
}
private static object GetDeserializedObject( ControllerContext controllerContext )
{
if( !controllerContext.HttpContext.Request.ContentType.StartsWith( "application/json", StringComparison.OrdinalIgnoreCase ) )
{
// not JSON request
return null;
}
var reader = new StreamReader( controllerContext.HttpContext.Request.InputStream );
var bodyText = reader.ReadToEnd();
if( String.IsNullOrEmpty( bodyText ) )
{
// no JSON data
return null;
}
var firstNonEmptyChar = GetFirstNonEmptyChar( bodyText );
if( firstNonEmptyChar == '[' )
{
var jsonData = JsonSerializer.DeserializeFromString< List< Dictionary< string, object > > >( bodyText );
return jsonData;
}
else
{
var jsonData = JsonSerializer.DeserializeFromString< Dictionary< string, object > >( bodyText );
return jsonData;
}
}
private static void AddToBackingStore( Dictionary< string, object > backingStore, string prefix, object value )
{
var d = value as IDictionary< string, object >;
if( d != null )
{
foreach( var entry in d )
{
AddToBackingStore( backingStore, MakePropertyKey( prefix, entry.Key ), entry.Value );
}
return;
}
var l = value as IList;
if( l != null )
{
for( var i = 0; i < l.Count; i++ )
{
AddToBackingStore( backingStore, MakeArrayKey( prefix, i ), l[ i ] );
}
return;
}
// primitive
backingStore[ prefix ] = value;
}
private static string MakeArrayKey( string prefix, int index )
{
return prefix + "[" + index.ToString( CultureInfo.InvariantCulture ) + "]";
}
private static string MakePropertyKey( string prefix, string propertyName )
{
return ( String.IsNullOrEmpty( prefix ) ) ? propertyName : prefix + "." + propertyName;
}
private static char? GetFirstNonEmptyChar( string @string )
{
for( var i = 0; i < @string.Length; i++ )
{
if( !char.IsWhiteSpace( @string[ i ] ) )
return @string[ i ];
}
return new char?();
}
}