我开始遇到一个奇怪的问题。
我有一个 ASP.NET 项目,其中有一个接受 POST 参数的 API。由于我使用接口,因此我使用自定义反序列化器来读取 POST 对象。它工作正常,直到最后几天。但是,有一天我开始收到 500 - 内部服务器错误,说“无法创建接口的实例......通过 CreateModel”。当时,我正在使用 PostMan 应用程序。由于代码几乎没有变化,我认为可能是 PostMan 应用程序损坏了。
我不确定,所以我在 Fiddler 上尝试了相同的查询,它运行良好。现在,3-4 天后,Fiddler 也停止工作,出现同样的错误。
深入研究后,我发现“BindModel”以某种方式开始执行可能在 ActionFilterAttribute 之前。我只是不确定这怎么可能。有什么办法可以克服这种情况吗?我发布的 http 调用只是没有进入 JsonFilter 的 OnActionExecuting 方法
错误信息:
[MissingMethodException:无法创建接口的实例。]
System.RuntimeTypeHandle.CreateInstance(...)
System.RuntimeType.CreateInstanceSlow(...)
System.Activator.CreateInstance(...)
System.Activator.CreateInstance(.. .)
System.Web.Mvc.DefaultModelBinder.CreateModel(...)[MissingMethodException:无法创建接口的实例。对象类型'MyCommonObj.IMyInterface'。]
System.Web.Mvc.DefaultModelBinder.CreateModel(...)
System.Web.Mvc.DefaultModelBinder.BindComplexModel(...)
System.Web.Mvc.DefaultModelBinder.BindModel(... )
代码片段:
public class JsonFilter : ActionFilterAttribute {
public string Parameter { get; set; }
public Type JsonDataType { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext) {
if (filterContext.HttpContext.Request.ContentType.Contains("application/json")) {
string inputContent;
filterContext.HttpContext.Request.InputStream.Position = 0;
using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream)) {
inputContent = sr.ReadToEnd();
};
var jsonSerializerSettings = new JsonSerializerSettings() {
TypeNameHandling = TypeNameHandling.All
};
if (JsonDataType == typeof(MyClass)) {
var result = JsonConvert.DeserializeObject<MyClass>(inputContent, jsonSerializerSettings);
filterContext.ActionParameters[Parameter] = result;
}
else {
throw new NotImplementedException();
}
}
}
}
[HttpPost]
[JsonFilter(Parameter = "config", JsonDataType = typeof(MyClass))]
public ActionResult ExecuteApi(MyClass config) {
var result = DoSomething(config);
return Json(result);
}
public interface IMyInterface {
string GetValue();
}
public class MyDerivedClass : IMyInterface {
public string Value { get; set; }
public MyDerivedClass(string v) {
Value = v;
}
public string GetValue() { return Value; }
}
public class Query {
[JsonProperty(TypeNameHandling = TypeNameHandling.All)]
public IMyInterface type { get; set; }
public Query () {}
}
public class MyClass {
List<Query> myList { get; set; }
public MyClass () {}
}