它在測試版定製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
我問題
- 這可能是什麼原因?
- 如何正確調試?我有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).
我看到我已經收到了一些意見。我知道這是一個糟糕的問題,但我真的需要一些幫助。相當卡住了。高興地提出所有建議。我可以添加什麼來更容易地回答這個問題? – Mithon 2012-07-27 06:02:26