2012-12-01 12 views
5

私はASP.NET MVC 4 Web APIプロジェクトを作成し、NuGet経由でBreezeクライアントサンプルをインストールし、ToDoアプリケーションがうまく機能します。私はまた、WebAPIを呼び出すアンドロイドタブレットでCordova経由でアプリを実行しています。これは、エンティティを保存する場合を除いて素晴らしいことです。私は、クロスドメイン操作をサポートするためにGlobal.asax( "Access-Control-Allow-Origin"、 "*")を適切に変更しました。Breeze Web API with Cordova電話アプリケーション

AndroidクライアントからsaveChanges()が呼び出されたときに、データが実際にデータベースに保存されていますが、失敗するということは常にクライアントで発生するということです。

ウェブAPIサーバー上

私は気づいたそのブラウザ経由ブリーズ呼び出しを行うとき、私は次の出力トレースを取得し、成功したが、保存されます。

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) 

は、私はまた、ポストヘッダー「アプリケーション/ XMLを」気づきます。私はこれが関連しているかどうかはわかりませんが、もし誰かが助けてくれれば解決策を見つけて欲しいと確信しています。

おかげ マーク

答えて

4

私は"application/xml"関連しているかなり確信しています。

保存後、Breeze Web APIコントローラは更新/追加エンティティを返します。あなたが言及した "Accept"ヘッダーは、Web APIがほとんど常に失敗するXMLフォーマッタでエンティティをフォーマットしようとします。

私は、BreezeがネイティブにAcc​​eptヘッダーをPOSTに設定しているとは思っていません(GETにAcceptヘッダーを設定するかどうかわかりません)。

IE10でjQuery AJAXによって生成された要求を見ると、GETのAcceptヘッダーは"application/json, text/javascript, */*; q=0.01"です。 POSTの場合、AcceptおよびContent-typeヘッダーはそれぞれ"*\*"および"application/json"です。

AndroidトラフィックのAcceptヘッダーとは何ですか?どのヘッダが"application/xml"に設定されているかは指定していませんが、それは常に「間違っている」ため、重要ではないと思われます。

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は、Breezeトラフィックに対して動作しないことがわかっているXMLフォーマッタを削除することもお勧めします。

これはうまくいきます。

+0

ありがとうございましたウォードはAcceptヘッダーを追加しました。私はこのPhoneGap/CordovaのAndroidアプリが.NET Web API経由で私のEFデータベースを更新しているのを見て、私の顔に大きな笑みを浮かべています。 –