所以这就是问题,我实际上是在Sitecore中这样做,但是非常沮丧,我打破了一个新的样板WebApi项目,只是为了找到我的问题。
我的断言是,鉴于以下请求,
/ API /简单/ AspNetJsonDeserializing实例= {%20 “$类型”:%20 “SimpleWebApi.Controllers.ConcreteTestInstance,%20SimpleWebApi” %20 “主机名”:%20 “google.com” %20} <? / p>
我应该在ConcreteTestInstance
操作方法中为ITestInstance
实例获取AspNetJsonDeserializing
的非空参数值。
但是,我收到以下异常:
无法创建界面实例。
相反,如果我使用我的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>
答案 0 :(得分:0)
快速更新。
我改变了一些事情,这些事情提供了一些新的结果。
首先,我已将AspNetJsonDeserializing
属性切换为HttpPost
。
我还将AspNetJsonDeserializing
参数ITestInstance instance
属性切换为[FromBody]
显然现在,如果强迫我通过PostMan调用它。
所有这些现在都删除了异常,但实例为null。在ConcreteTestInstance构造函数上没有命中断点(我添加了另一个零参数构造函数来两种方式验证它。)
以下是所有变化。
[System.Web.Http.HttpPost]
public JsonResult<string> AspNetJsonDeserializing([FromBody] ITestInstance instance)
{
ConcreteTestInstance myConcreteTestInstance = ((ConcreteTestInstance) instance);
return Json($"Uri:{myConcreteTestInstance._instanceUri}");
}
这么简短的故事,我还在寻找,为什么instance
为空
答案 1 :(得分:0)
另一个更新。
我现在已经使用HttpPost处理了代码。问题是json格式:FACEPALM:
在PostMan中,我使用的格式是
{instance: {
"$type": "SimpleWebApi.Controllers.ConcreteTestInstance, SimpleWebApi",
"hostName": "google.com"
}}
当我删除实例变量时,它更正了问题。
此外,我测试过,ITestInstance参数的[FromBody]
属性无关紧要。
所以问题仍然是我如何以HttpGet 启用此功能。
目前,当我将属性从HttpPost切换到HttpGet时,我开始收到第一篇文章中提到的异常。