Using WCF Data Services (ODATA) operations in Windows Phone development

1

I'm developing a windows phone application that needs to consume data from an OData feed (using WCF Data Services). Specifically, I need to call the following operation

http://localhost/ODATA/PIDataService.svc/RecordedValues?path='\\OPENXC\OpenXC\EventFrames[testFrame]|Sinusoid'&startTime='*-1d'&endTime='*'

When I execute this in the browser (Chrome) it gives me the proper result

<feed xml:base="http://[redacted]/OData/PIDataService.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title type="text">RecordedValues</title>
<id>http://[redacted]/ODATA/PIDataService.svc/RecordedValues</id>
<updated>2012-09-11T12:09:12Z</updated>
<link rel="self" title="RecordedValues" href="RecordedValues"/>
<entry>
<id>http://[redacted]/OData/PIDataService.svc/TimeseriesValues(SourceAttributePath='//OPENXC/OpenXC/EventFrames%5BtestFrame%5D%7CSinusoid',Timestamp=datetime'2012-09-10T13%3A31%3A09Z')</id>
<title type="text"/>
<updated>2012-09-11T12:09:12Z</updated>
<author>
<name/>
</author>
<link rel="edit" title="TimeSeriesValue" href="TimeseriesValues(SourceAttributePath='//OPENXC/OpenXC/EventFrames%5BtestFrame%5D%7CSinusoid',Timestamp=datetime'2012-09-10T13%3A31%3A09Z')"/>
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/UOM" type="application/atom+xml;type=entry" title="UOM" href="TimeseriesValues(SourceAttributePath='//OPENXC/OpenXC/EventFrames%5BtestFrame%5D%7CSinusoid',Timestamp=datetime'2012-09-10T13%3A31%3A09Z')/UOM"/>
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/SourceAttribute" type="application/atom+xml;type=entry" title="SourceAttribute" href="TimeseriesValues(SourceAttributePath='//OPENXC/OpenXC/EventFrames%5BtestFrame%5D%7CSinusoid',Timestamp=datetime'2012-09-10T13%3A31%3A09Z')/SourceAttribute"/>
<category term="vCampus.OData.Web.ObjectModel.TimeSeriesValue" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<content type="application/xml">
<m:properties>
<d:Timestamp m:type="Edm.DateTime">2012-09-10T13:31:09Z</d:Timestamp>
<d:SourceAttributePath>\\OPENXC\OpenXC\EventFrames[testFrame]|Sinusoid</d:SourceAttributePath>
<d:Value>85.7081527709961</d:Value>
<d:UOMName m:null="true"/>
<d:AdditionalInfo/>
<d:Annotated m:type="Edm.Boolean">false</d:Annotated>
<d:IsGood m:type="Edm.Boolean">true</d:IsGood>
<d:Questionable m:type="Edm.Boolean">false</d:Questionable>
<d:Status>Good</d:Status>
<d:Substituted m:type="Edm.Boolean">false</d:Substituted>
</m:properties>
</content>
</entry>
<entry>
<id>http://[redacted]/OData/PIDataService.svc/TimeseriesValues(SourceAttributePath='//OPENXC/OpenXC/EventFrames%5BtestFrame%5D%7CSinusoid',Timestamp=datetime'2012-09-10T14%3A40%3A09Z')</id>
<title type="text"/>
<updated>2012-09-11T12:09:12Z</updated>
<author>
<name/>
</author>
<link rel="edit" title="TimeSeriesValue" href="TimeseriesValues(SourceAttributePath='//OPENXC/OpenXC/EventFrames%5BtestFrame%5D%7CSinusoid',Timestamp=datetime'2012-09-10T14%3A40%3A09Z')"/>
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/UOM" type="application/atom+xml;type=entry" title="UOM" href="TimeseriesValues(SourceAttributePath='//OPENXC/OpenXC/EventFrames%5BtestFrame%5D%7CSinusoid',Timestamp=datetime'2012-09-10T14%3A40%3A09Z')/UOM"/>
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/SourceAttribute" type="application/atom+xml;type=entry" title="SourceAttribute" href="TimeseriesValues(SourceAttributePath='//OPENXC/OpenXC/EventFrames%5BtestFrame%5D%7CSinusoid',Timestamp=datetime'2012-09-10T14%3A40%3A09Z')/SourceAttribute"/>
<category term="vCampus.OData.Web.ObjectModel.TimeSeriesValue" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
<content type="application/xml">
<m:properties>
<d:Timestamp m:type="Edm.DateTime">2012-09-10T14:40:09Z</d:Timestamp>
<d:SourceAttributePath>\\OPENXC\OpenXC\EventFrames[testFrame]|Sinusoid</d:SourceAttributePath>
<d:Value>99.2516555786133</d:Value>
<d:UOMName m:null="true"/>
<d:AdditionalInfo/>
<d:Annotated m:type="Edm.Boolean">false</d:Annotated>
<d:IsGood m:type="Edm.Boolean">true</d:IsGood>
<d:Questionable m:type="Edm.Boolean">false</d:Questionable>
<d:Status>Good</d:Status>
<d:Substituted m:type="Edm.Boolean">false</d:Substituted>
</m:properties>
</content>
</entry>
...

The (Windows Phone) client code:

  var path = attr.Path;
                   var context = new DatabaseData(new Uri(MainPage.serviceUrl));

                   var query = context.CreateQuery<TimeSeriesValue>("RecordedValues")
                       .AddQueryOption("path", string.Format("'{0}'", path))
                       .AddQueryOption("startTime", "'*-1d'")
                       .AddQueryOption("endTime", "'*'");
                   query.BeginExecute(TimeSeriesReady, query);


   private void TimeSeriesReady(IAsyncResult result)
    {
        var context = result.AsyncState as DataServiceQuery<TimeSeriesValue>;
        var values = context.EndExecute(result).ToList();
        values.ForEach(v => Debug.WriteLine(v.Value));
    }

This presents me with an 'InvalidOperationException' with

An error occurred while processing this request.

The innerexception message is '0x80000012' and the stack trace is

 at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
       at MS.Internal.XcpImports.WebRequest_Send(InternalWebRequest request)
       at MS.Internal.InternalWebRequest.Send()
       at System.Net.Browser.ClientHttpWebRequest.PrepareAndSendRequest(String method, Uri requestUri, Stream requestBodyStream, WebHeaderCollection headerCollection, CookieContainer cookieContainer)
       at System.Net.Browser.ClientHttpWebRequest.BeginGetResponseImplementation()
       at System.Net.Browser.ClientHttpWebRequest.InternalBeginGetResponse(AsyncCallback callback, Object state)
       at System.Net.Browser.ClientHttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state)
       at System.Data.Services.Http.ClientHttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state)
       at System.Data.Services.Client.BaseAsyncResult.InvokeAsync(Func`3 asyncAction, AsyncCallback callback, Object state)
       at System.Data.Services.Client.QueryResult.BeginExecute(DataServiceContext context)
       at System.Data.Services.Client.DataServiceRequest.BeginExecute(Object source, DataServiceContext context, AsyncCallback callback, Object state)
       at System.Data.Services.Client.DataServiceQuery`1.BeginExecute(AsyncCallback callback, Object state)
       at vCampus.OData.Phone.DetailsPage.eventFrames_LoadCompleted(Object sender, LoadCompletedEventArgs e)
       at System.Data.Services.Client.DataServiceCollection`1.<>c__DisplayClass11.<>c__DisplayClass13.<BeginLoadAsyncOperation>b__f()
       at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
       at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
       at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
       at System.Delegate.DynamicInvokeOne(Object[] args)
       at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
       at System.Delegate.DynamicInvoke(Object[] args)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
       at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
       at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
       at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
       at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)

I have searched for this error code, but could not find any answers. Code samples available online suggest this approach, but give no explanation for this error.

windows-phone-7
wcf-data-services
odata
webget
asked on Stack Overflow Sep 11, 2012 by MvdV

1 Answer

0

As Vitek suggested, Uri.EscapeUriString needs to be used to escape the path query option:

var path = attr.Path;
var context = new DatabaseData(new Uri(MainPage.serviceUrl));
var query = context.CreateQuery<TimeSeriesValue>("RecordedValues")
                .AddQueryOption("path", string.Format("'{0}'", Uri.EscapeUriString(path)))
                .AddQueryOption("startTime", "'*-1d'")
                .AddQueryOption("endTime", "'*'");
query.BeginExecute(TimeSeriesReady, query);

One of our devs tested and verified on both our existing Windows Phone client bits as well as our upcoming Windows Phone client bits.


User contributions licensed under CC BY-SA 3.0