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

回答

相關問題