它在测试版定制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