我创建了一个ASP.NET MVC 4 Web API项目并通过NuGet安装了包含客户端示例的Breeze,并且ToDo应用程序运行良好。我还在Android平板电脑上通过Cordova运行应用程序,呼叫WebAPI,除了保存实体外,这也很有用。我对Global.asax(“Access-Control-Allow-Origin”,“*”)进行了适当的更改,以支持跨域操作。
当Android客户端调用它的saveChanges()时,数据实际上被保存到数据库中,但它的失败承诺总是在客户端上启动。
在Web API服务器上,我注意到当通过浏览器进行Breeze调用时,我得到以下输出跟踪并成功保存:
iisexpress.exe Information: 0 : Operation=ODataActionFilter.ActionExecuting
iisexpress.exe Information: 0 : Message='Action returned 'Breeze.WebApi.SaveResult'', Operation=ReflectedHttpActionDescriptor.ExecuteAsync
iisexpress.exe Information: 0 : Message='Will use same 'JsonMediaTypeFormatter' formatter', Operation=JsonMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Selected formatter='JsonMediaTypeFormatter', content-type='application/json; charset=utf-8'', Operation=DefaultContentNegotiator.Negotiate
iisexpress.exe Information: 0 : Operation=ApiControllerActionInvoker.InvokeActionAsync, Status=200 (OK)
iisexpress.exe Information: 0 : Operation=ODataActionFilter.ActionExecuted, Status=200 (OK)
iisexpress.exe Information: 0 : Operation=BreezeSampleController.ExecuteAsync, Status=200 (OK)
**iisexpress.exe Information: 0 : Response, Status=200 (OK), Method=POST, Url=http://localhost:59912/api/BreezeSample/SaveChanges, Message='Content-type='application/json; charset=utf-8', content-length=unknown'**
iisexpress.exe Information: 0 : Operation=JsonMediaTypeFormatter.WriteToStreamAsync
iisexpress.exe Information: 0 : Operation=BreezeSampleController.Dispose
但是当从Android应用程序调用时,我会写入数据,但此跟踪出现错误:
iisexpress.exe Information: 0 : Message='Action returned 'Breeze.WebApi.SaveResult'', Operation=ReflectedHttpActionDescriptor.ExecuteAsync
iisexpress.exe Information: 0 : Message='Will use same 'XmlMediaTypeFormatter' formatter', Operation=XmlMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Selected formatter='XmlMediaTypeFormatter', content-type='application/xml; charset=utf-8'', Operation=DefaultContentNegotiator.Negotiate
iisexpress.exe Information: 0 : Operation=ApiControllerActionInvoker.InvokeActionAsync, Status=200 (OK)
iisexpress.exe Information: 0 : Operation=ODataActionFilter.ActionExecuted, Status=200 (OK)
iisexpress.exe Information: 0 : Operation=BreezeSampleController.ExecuteAsync, Status=200 (OK)
**iisexpress.exe Information: 0 : Response, Status=200 (OK), Method=POST, Url=http://192.168.1.9:59912/api/BreezeSample/SaveChanges, Message='Content-type='application/xml; charset=utf-8', content-length=unknown'**
iisexpress.exe Error: 0 : Operation=XmlMediaTypeFormatter.WriteToStreamAsync, Exception=System.Runtime.Serialization.SerializationException: Type 'SMHMobileAPI.Models.BreezeSampleTodoItem' with data contract name 'BreezeSampleTodoItem:http://schemas.datacontract.org/2004/07/SMHMobileAPI.Models' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at WriteArrayOfanyTypeToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract )
at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
at WriteSaveResultToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract )
at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph)
at System.Net.Http.Formatting.XmlMediaTypeFormatter.<>c__DisplayClass7.<WriteToStreamAsync>b__6()
at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)
除了一些序列化错误,我还注意到帖子标题“application / xml”。我不确定这是否相关,但如果有人可以提供帮助,我肯定希望找到一些解决方案。
由于 标记
答案 0 :(得分:4)
我非常确定"application/xml"
相关。
保存后,Breeze Web API控制器会向您返回更新/添加的实体。 &#34;接受&#34;您提到的标题会导致Web API尝试使用XML格式化程序格式化这些实体,而这些格式化程序几乎总是失败。
我不认为Breeze本身在POST上设置了Accept标头(我不确定它是否在GET上设置了Accept标头)。
查看IE10中生成的jQuery AJAX请求,显示GET的Accept标头为"application/json, text/javascript, */*; q=0.01"
。对于POST,Accept和Content-type标题分别为"*\*"
和"application/json"
。
Android流量中的Accept标头有哪些?您没有指定哪个标头设置为"application/xml"
...但由于这始终是&#34;错误&#34;我不认为这很重要:)
您可以自定义Breeze AJAX适配器或完全替换它as described here。你可以试试:
// get the current default Breeze ajax adapter var ajaxAdapter = breeze.core.config.getAdapterInstance("ajax"); // set fixed headers ajaxAdapter.defaultSettings = { headers: { "Accept": "application/json, text/javascript, */*; q=0.01" }, };
这似乎是我在IE10和Chrome测试中的诀窍。
我还建议Breeze Web API JsonFormatterAttribute删除XML格式化程序,我们知道一个人不适用于Breeze流量。
希望这有效。