2012-07-26 84 views
1

它在测试版定制JsonMediaTypeFormatter抛出InvalidOperationException异常的get_DeclaringMethod()

工作,我有型ChangeSet<T>ChangeSet派生的对象,需要一些定制反序列化,以便我的网络API来完成其他工作。它是在asp.net mvc 4 beta中工作的,但在rc中它已经坏掉了,而且我发现很难调试。

我的场景

变更集可以表示一个号码由ID列表描述T对象的的变化。我想反序列化成某种类型的对象数组或字典来描述T对象的哪些属性应该被改变,但是我有问题反序列化成正确的数据类型。所以我介绍了T型的Change属性。然后,新问题是并非所有Change属性都应该保留。只有那些包含在json中的。所以我让有一个属性属性包含一个字符串列表。

我的问题

,让我来填充属性,我需要访问原始JSON,这就是为什么我需要一个定制MediaTypeFormatter。 (xml-serializer有一个SetSerializer(..),但没有这样的JsonSerializer方法。在下面的ReadFromStreamAsync中,我这样做,问题是它崩溃了,我无法步入崩溃点得到一个内部异常我得到的是下面的JSON响应我的要求:。

{ 
    "ExceptionType": "System.InvalidOperationException", 
    "Message":  "Method may only be called on a Type for which Type.IsGenericParameter is true.", 
    "StackTrace": " at System.RuntimeType.get_DeclaringMethod()" 
} 

如果我删除我的ChangeSetJsonFormatter代码不破,但我当然没有Properties

我问题

  1. 这可能是什么原因?
  2. 如何正确调试?我有Log4Net,但我应该看什么?我能否以某种方式进入问题?

代码

这是我FormatterConfig

public class FormatterConfig 
{ 
    public static void RegisterGlobalFormatters(MediaTypeFormatterCollection formatters) 
    { 
     var jsonSerializerSettings = formatters.JsonFormatter.SerializerSettings; 
     jsonSerializerSettings.Converters.Add(new IsoDateTimeConverter()); 
     jsonSerializerSettings.NullValueHandling = NullValueHandling.Ignore; 

     // At index 0 so that it will try this before the default handler. 
     formatters.Insert(0, new ChangeSetJsonFormatter(jsonSerializerSettings)); 

     formatters.Remove(formatters.XmlFormatter); 
    } 
} 

这是我的自定义媒体格式(抱歉的长度):

public class ChangeSetJsonFormatter : JsonMediaTypeFormatter 
{ 
    private static readonly Type ChangeSetType = typeof (ChangeSet<Entity>); 

    public ChangeSetJsonFormatter(JsonSerializerSettings jsonSerializerSettings) 
    { 
     SerializerSettings = jsonSerializerSettings; 
    } 

    public override bool CanReadType(Type type) 
    { 
     return type.IsGenericType && type.Namespace == ChangeSetType.Namespace && type.Name == ChangeSetType.Name; 
    } 

    public override bool CanWriteType(Type type) 
    { 
     return type.IsGenericType && type.Namespace == ChangeSetType.Namespace && type.Name == ChangeSetType.Name; 
    } 

    public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger) 
    { 
     var task = Task.Factory.StartNew(() => 
     { 
      using (var streamReader = new StreamReader(stream)) 
      { 
       var jsonSource = streamReader.ReadToEnd(); 
       var deserializedObject = 
        JsonConvert.DeserializeObject(jsonSource, type, 
               SerializerSettings); 
       var changeSet = deserializedObject as ChangeSet; 
       if (changeSet != null && 
        (changeSet.Properties == null || 
        changeSet.Properties.Count == 0)) 
       { 
        var properties = 
         JObject.Parse(jsonSource)["Change"] 
           .Select(t => ((JProperty) t).Name) 
           .ToList(); 
        changeSet.Properties = properties; 
       } 

       return deserializedObject; 
      } 
     }); 

     return task; 
    } 
} 

而且这些都是ChangeSet类别:

[DataContract] 
public abstract class ChangeSet 
{ 
    [DataMember] 
    public IList<string> Properties { get; set; } 

    [DataMember] 
    public IList<int> IdList { get; set; } 
} 

[DataContract] 
public class ChangeSet<T> : ChangeSet where T : Entity 
{ 
    [DataMember] 
    public T Change { get; set; } 

    public Dictionary<PropertyInfo, object> Changes 
    { 
     get 
     { 
      if (Properties == null || Properties.Count == 0) 
       return new Dictionary<PropertyInfo, object>(); 

      return typeof (T) 
       .GetProperties() 
       .Where(pi => Properties.Contains(pi.Name)) 
       .ToDictionary(pi => pi, pi => pi.GetValue(Change, null)); 
     } 
    } 
} 

编辑:我能够生成跟踪此文档的服务堆栈跟踪。现在,如果只有我能够得到我的例外条目。以下是默认侦听器的输出:

System.Web.Http.Request: ;;http://localhost:50500/MyService/User?_dc=1343396746443 
System.Web.Http.Controllers: DefaultHttpControllerSelector;SelectController;Route='controller:User' 
System.Web.Http.Controllers: DefaultHttpControllerSelector;SelectController;User 
System.Web.Http.Controllers: HttpControllerDescriptor;CreateController; 
System.Web.Http.Controllers: DefaultHttpControllerActivator;Create; 
System.Web.Http.Controllers: DefaultHttpControllerActivator;Create;MyCompany.Admin.Service.Controllers.UserController 
System.Web.Http.Controllers: HttpControllerDescriptor;CreateController;MyCompany.Admin.Service.Controllers.UserController 
System.Web.Http.Controllers: UserController;ExecuteAsync; 
System.Web.Http.Action: ApiControllerActionSelector;SelectAction; 
System.Web.Http.Action: ApiControllerActionSelector;SelectAction;Selected action 'Put(ChangeSet`1 changeSet)' 
System.Web.Http.ModelBinding: HttpActionBinding;ExecuteBindingAsync; 
System.Web.Http.ModelBinding: FormatterParameterBinding;ExecuteBindingAsync;Binding parameter 'changeSet' 
System.Net.Http.Formatting: ChangeSetJsonFormatter;ReadFromStreamAsync;Type='ChangeSet`1', content-type='application/json' 
System.Net.Http.Formatting: ChangeSetJsonFormatter;ReadFromStreamAsync;Value read='MyCompany.Admin.Service.Data.ChangeSet`1[MyCompany.Data.Model.User]' 
System.Web.Http.ModelBinding: FormatterParameterBinding;ExecuteBindingAsync; 
System.Web.Http.ModelBinding: HttpActionBinding;ExecuteBindingAsync; 
System.Web.Http.Controllers: UserController;ExecuteAsync; 
System.Net.Http.Formatting: DefaultContentNegotiator;Negotiate;Type='HttpError', formatters=[JsonMediaTypeFormatterTracer, JsonMediaTypeFormatterTracer, FormUrlEncodedMediaTypeFormatterTracer, FormUrlEncodedMediaTypeFormatterTracer] 
System.Net.Http.Formatting: JsonMediaTypeFormatter;GetPerRequestFormatterInstance;Obtaining formatter of type 'JsonMediaTypeFormatter' for type='HttpError', mediaType='application/json; charset=utf-8' 
System.Net.Http.Formatting: JsonMediaTypeFormatter;GetPerRequestFormatterInstance;Will use same 'JsonMediaTypeFormatter' formatter 
System.Net.Http.Formatting: DefaultContentNegotiator;Negotiate;Selected formatter='JsonMediaTypeFormatter', content-type='application/json; charset=utf-8' 
System.Web.Http.Request: ;;Content-type='application/json; charset=utf-8', content-length=unknown 
System.Net.Http.Formatting: JsonMediaTypeFormatter;WriteToStreamAsync;Value='System.Web.Http.HttpError', type='HttpError', content-type='application/json; charset=utf-8' 
System.Net.Http.Formatting: JsonMediaTypeFormatter;WriteToStreamAsync; 
System.Web.Http.Controllers: UserController;Dispose; 
System.Web.Http.Controllers: UserController;Dispose; 
The thread '<No Name>' (0x1ea0) has exited with code 0 (0x0). 
The thread '<No Name>' (0x1d6c) has exited with code 0 (0x0). 
The thread '<No Name>' (0x19b4) has exited with code 0 (0x0). 
+0

我看到我已经收到了一些意见。我知道这是一个糟糕的问题,但我真的需要一些帮助。相当卡住了。高兴地提出所有建议。我可以添加什么来更容易地回答这个问题? – Mithon 2012-07-27 06:02:26

回答