【发布时间】:2018-02-01 21:30:56
【问题描述】:
所以问题来了,我实际上是在 Sitecore 中这样做的,但我非常沮丧,我推出了一个新的样板 WebApi 项目,只是为了找到我的问题。
我的断言是,鉴于以下请求,
/api/Simple/AspNetJsonDeserializing?instance={%20"$type":%20"SimpleWebApi.Controllers.ConcreteTestInstance,%20SimpleWebApi",%20"hostName":%20"google.com"%20}
我应该在我的AspNetJsonDeserializing 操作方法中为ITestInstance 实例获取ConcreteTestInstance 的非空参数值。
但是,我收到以下异常:
无法创建接口的实例。
相反,如果我使用我的 NewtonsoftJsonDeserializing 操作方法,并传递一个 jsonString 并使用 Newtonsoft JsonConvert 显式反序列化它,它将很好地反序列化。
我做错了什么?
这是所有代码
Json
{
"$type": "SimpleWebApi.Controllers.ConcreteTestInstance, SimpleWebApi",
"hostName": "google.com"
}
控制器/动作
[JsonInterfaceBindingAndNonDefaultConstructors]
public class SimpleController : ApiController
{
[System.Web.Http.HttpGet]
public JsonResult<string> NewtonsoftJsonDeserializing(string jsonString) // [FromUri] ITestInstance instance) //
{
JsonSerializerSettings jsonSerializerSettingForTypeHandling = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor };
ITestInstance instance = JsonConvert.DeserializeObject<ITestInstance>(jsonString, jsonSerializerSettingForTypeHandling);
return Json("OK");
}
[System.Web.Http.HttpGet]
public JsonResult<string> AspNetJsonDeserializing([FromUri] ITestInstance instance)
{
return Json($"Uri:{((ConcreteTestInstance)instance)._instanceUri}");
}
}
用于修改 SerializerSettings 的属性
[AttributeUsage(AttributeTargets.Class)]
public class JsonInterfaceBindingAndNonDefaultConstructors : Attribute, IControllerConfiguration
{
public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
{
IEnumerable<JsonMediaTypeFormatter> jsonFormatters = controllerSettings.Formatters.OfType<JsonMediaTypeFormatter>();
foreach (var jsonFormatter in jsonFormatters)
{
jsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver(); //new JsonContractResolver(new JsonMediaTypeFormatter() {});
jsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.All;
jsonFormatter.SerializerSettings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
}
}
}
界面
public interface ITestInstance
{
}
具体子类
public class ConcreteTestInstance : ITestInstance
{
private const string SCHEME = "http://";
private const int PORT = 80;
private const string API_PATH = "/";
private const string QUERYSTRING = "";
public readonly Uri _instanceUri;
public ConcreteTestInstance(string hostName)
{
_instanceUri = new UriBuilder(SCHEME, hostName, PORT, API_PATH, QUERYSTRING).Uri;
}
}
异常:无法创建接口实例。
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>Cannot create an instance of an interface.</ExceptionMessage>
<ExceptionType>System.MissingMethodException</ExceptionType>
<StackTrace>
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) at System.Activator.CreateInstance(Type type, Boolean nonPublic) at System.Activator.CreateInstance(Type type) at System.Web.Http.ModelBinding.Binders.MutableObjectModelBinder.CreateModel(HttpActionContext actionContext, ModelBindingContext bindingContext) at System.Web.Http.ModelBinding.Binders.MutableObjectModelBinder.EnsureModel(HttpActionContext actionContext, ModelBindingContext bindingContext) at System.Web.Http.ModelBinding.Binders.MutableObjectModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) at System.Web.Http.Controllers.HttpActionContextExtensions.Bind(HttpActionContext actionContext, ModelBindingContext bindingContext, IEnumerable`1 binders) at System.Web.Http.ModelBinding.Binders.CompositeModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) at System.Web.Http.ModelBinding.ModelBinderParameterBinding.ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) at System.Web.Http.Controllers.HttpActionBinding.<ExecuteBindingAsyncCore>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
</StackTrace>
</Error>
【问题讨论】:
标签: json asp.net-web-api json.net