2012-12-01 15 views
5

Ho creato un progetto API Web ASP.NET MVC 4 e installato Breeze, inclusi campioni client tramite NuGet e l'applicazione ToDo funziona molto bene. Ho anche l'app in esecuzione via Cordova su un tablet Android che chiama WebAPI e anche questo funziona alla grande se non salvando le entità. Ho apportato le modifiche appropriate a Global.asax ("Access-Control-Allow-Origin", "*") per supportare le operazioni tra domini diversi.Breeze Web API con Cordova Phone App Salvataggio delle modifiche

I dati vengono effettivamente salvati nel database quando il client Android chiama saveChanges() ma la promessa di fail è sempre attiva sul client.

Sul server Web API Ho notato che quando si effettuano chiamate Breeze tramite un browser ottengo il seguente traccia di uscita e di successo salva:

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 

Ma quando viene chiamato da App Android vengo dati scritti, ma questa traccia con un errore:

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) 

a parte qualche errore di serializzazione ho anche notato l'intestazione post "application/xml". Non sono sicuro che questo sia pertinente, ma di certo vorrei un aiuto per cercare di trovare una soluzione se qualcuno può aiutare per favore.

Grazie Mark

risposta

4

sono abbastanza sicuro "application/xml"è rilevante.

Dopo il salvataggio, il controllore API Breeze Web restituisce le entità di aggiornamento/aggiunta. L'intestazione "Accetta" che hai menzionato causerebbe l'API Web per provare a formattare quelle entità con il formattatore XML che quasi sempre fallisce.

Non credo che Breeze imposti in modo nativo un'intestazione Accept sul POST (non sono sicuro se imposta l'intestazione Accept sul GET).

Uno sguardo alla richiesta generata da jQuery AJAX in IE10 mostra che l'intestazione Accept per un GET è "application/json, text/javascript, */*; q=0.01". Per un POST le intestazioni Accept e Content-type sono rispettivamente "*\*" e "application/json".

Quali sono le intestazioni Accept nel traffico Android? Non hai specificato quale intestazione era impostata su "application/xml" ... ma poiché è sempre "sbagliato" non credo che importi :)

È possibile personalizzare l'adattatore Breeze AJAX o sostituirlo interamente as described here. Potresti provare:

 
// 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" 
     }, 
};

Sembrava fare il trucco nei miei test sia su IE10 sia su Chrome.

Raccomanderò anche che l'API Breeze Web JsonFormatterAttribute rimuova il formattatore XML, ma sappiamo che non funziona per il traffico Breeze.

Spero che questo funzioni.

+0

Grazie mille Ward che ha aggiunto l'intestazione Accept funzionante. Ho un enorme sorriso sul mio viso ora guardando questa app Android PhoneGap/Cordova aggiornare il mio database EF tramite un'API Web .NET. –

Problemi correlati