使用Cordova Phone App保存更改的Breeze Web API

时间:2012-12-01 21:52:05

标签: breeze

我创建了一个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”。我不确定这是否相关,但如果有人可以提供帮助,我肯定希望找到一些解决方案。

由于 标记

1 个答案:

答案 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流量。

希望这有效。