Reputation: 7414
I am using the Parse API in a .NET Universal app. I have added the Parse library to a PCL and then included the .NET WinRT library with the actual Windows RT project. The following is my service call.
public async Task<IEnumerable<BasicTask>> GetTasksAsync()
{
ParseQuery<ParseObject> query = ParseObject.GetQuery(typeof(BasicTask).Name);
IEnumerable<ParseObject> parseObjects = await query.FindAsync();
// Convert the parse objects returned from the cloud into our local model representation.
// We do this in order order to maintain support for the model across multiple cloud services
// instead of restricting ourselves to the entire app using ParseCloud only.
return parseObjects.Select(po => this.ConvertParseObjectToDutyTask(po));
}
This method works fine with the following unit test:
[TestMethod]
public async Task TaskService_GetTasks_HasValue()
{
var service = new ParseCloudTaskService();
var tasks = await service.GetTasksAsync();
Debug.WriteLine(string.Format("{0} tasks found.", tasks.Count()));
}
I get back all of the records (only 1 atm) from Parse.
When I use this same method in my Windows App Store app, I get an The remote name could not be resolved: 'api.parse.com'
exception. For the time being, I am calling it within my Page load event. The event handler invokes an Intialize method in my view model, which asks a repository for all tasks. The repository gets the tasks from the service and returns it.
Page
private async void pageRoot_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
if (!(this.DataContext is MainPageViewModel))
{
return;
}
var vm = this.DataContext as MainPageViewModel;
await vm.Initialize();
this.TasksList.ItemsSource = vm.Tasks;
}
View Model
public async Task Initialize()
{
try
{
IEnumerable<BasicTask> tasks = await this.repository.GetTasksAsync();
this.tasks = new ObservableCollection<BasicTask>(tasks);
}
catch (Exception)
{
throw;
}
}
Repository
public async Task<IEnumerable<BasicTask>> GetTasksAsync()
{
IEnumerable<BasicTask> tasks = await this.service.GetTasksAsync();
return tasks;
}
When the event is executed, the exception gets thrown when the serivce calls await query.FindAsnyc()
.
The following is the full exception.
System.Net.Http.HttpRequestException was unhandled by user code
HResult=-2146233088
Message=An error occurred while sending the request.
Source=mscorlib
StackTrace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Parse.PlatformHooks.<RequestAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Parse.Internal.InternalExtensions.<>c__DisplayClass7`1.<OnSuccess>b__6(Task t)
at System.Threading.Tasks.ContinuationResultTaskFromTask`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Parse.Internal.InternalExtensions.<>c__DisplayClass7`1.<OnSuccess>b__6(Task t)
at System.Threading.Tasks.ContinuationResultTaskFromTask`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Duty.Services.ParseCloud.ParseCloudTaskService.<GetTasksAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Duty.Repositories.Tasks.BasicTaskRepository.<GetTasksAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Duty.WindowsAppStore.ViewModels.MainPageViewModel.<Initialize>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Duty.WindowsAppStore.Views.MainPage.<pageRoot_Loaded>d__0.MoveNext()
InnerException: System.Net.WebException
HResult=-2146233079
Message=The remote name could not be resolved: 'api.parse.com'
Source=System
StackTrace:
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
InnerException:
Does anyone have any idea why it works fine in the unit test, but fails to hit the service within the app? Am I using the async pattern wrong? I'm not sure if that is affecting it since the exception happens at the call to the Parse service.
EDIT
Just to clarify, I have a single WinRT project that references a Universal PCL repository library and a universal PCL services library. Immediately upon invoking await query.FindAsync();
it fails. My Unit Test is a standard Windows Unit Test project and references the exact same two PCL libraries. The only difference between the two is that one is WinRT and one is a standard Windows Unit Test. Both use the same libraries and both make the calls using async. Both libraries are targeting Windows 8, Windows Phone 8 and .NET 4.5
Is there special permissions I have to give my app to allow network access on a WinRT device?
Any help would be awesome!
Upvotes: 0
Views: 1329
Reputation: 7414
I was able to resolve this finally. You have to modify the Package.appxmanifest file to tell the device that the app needs outbound internet privileges. This explains why the unit tests worked and the app did not.
As soon as I enabled internet privileges on the app, the network call succeeded and I had data return from Parse. I wish that the framework would throw a InternetCapabilityNotSet
exception or something. Anything other that what it is currently throwing when the right capabilities are not set.
Upvotes: 2