HttpClient in Windows Phone 8.1 Universal app - windows-phone-8

So i'm testing universal applications and have reached this:
I have an application on Windows Tablet that gets data from server.
Server is protected with certificate ( SSL )
I have this code, runs great on simple Windows Store Application, and Universal application project for tablet, but not Phone
async public static Task<string> GetDataFromServer()
{
try
{
HttpClientHandler aHandler = new HttpClientHandler();
aHandler.ClientCertificateOptions = ClientCertificateOption.Automatic;
HttpClient aClient = new HttpClient(aHandler);
aClient.DefaultRequestHeaders.ExpectContinue = false;
aClient.DefaultRequestHeaders.MaxForwards = 3;
Uri requestUri = new Uri("MYURL");
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);
var result = await aClient.GetAsync(requestUri, HttpCompletionOption.ResponseContentRead);
var responseHeader = result.Headers;
var responseBody = await result.Content.ReadAsStringAsync();
return responseBody;
}
catch (Exception e)
{
return "";
}
}
All needed capabilities are set in manifest:
<Capabilities>
<Capability Name="internetClient" />
<Capability Name="sharedUserCertificates" />
<Capability Name="privateNetworkClientServer" />
<Capability Name="internetClientServer" />
</Capabilities>
<Extensions>
<Extension Category="windows.certificates">
<Certificates>
<Certificate StoreName="Root" Content="Assets\CoolCertificate.cer" />
</Certificates>
</Extension>
Phone code - doesn't crash, no errors or warnings - just blank result.
Code: {StatusCode: 404, ReasonPhrase: 'Not Found', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:{ Content-Length: 0}}
And no notification to the user like in WinRT:

Please use aHandler.UseDefaultCredentials= true; property and try once.hope that may solve the issue?

Note that in Windows Phone 8.1, there's two HttpClient classes. One is inside System.Net.Http namespace, and the other Windows.Web.Http namespace.
You want to use the one in Windows.Web.Http.

I hope you have the certificate that you need to use as PFX. In that case please refer to my reply in the link
Client Certificates Windows Phone 8.1

Related

How to launch app from another app in Windows Phone 8.1

I want to launch my app from another app in the Windows Phone 8.1 environment. I followed the instructions in MSDN, but I cannot figure out how to call the first app from the second. This is the protocol I added in the first app's manifest file:
<Extensions>
<Extension Category="windows.protocol">
<Protocol Name="myapp">
<Logo>Assets\SmallLogo.scale-240.png</Logo>
<DisplayName>my App 1</DisplayName>
</Protocol>
</Extension>
</Extensions>
This is my call from the second app, that does absolutely nothing:
private async void btn_Click(object sender, RoutedEventArgs e)
{
await Windows.System.Launcher.LaunchUriAsync(new System.Uri("myapp:"));
}
Follow the steps in Auto-launching apps using file and URI associations for Windows Phone 8
And you have use use a class which is derived from UriMapperBase to handle the navigation and have to set it as RootFrame.UriMapper in the App.xaml.cs
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
// Assign the URI-mapper class to the application frame.
RootFrame.UriMapper = new AssociationUriMapper();
******
}

Windows Phone 8 Receiving raw Push Notification issue

I am unable to receive raw notification on my WindowsPhone8.
Followed :https://github.com/barryvdh/PushPlugin/#uccb-wp8-only
Able to get toast notification. In my app toggle is happening like below.
Case 1: If I comment ecb able to get both raw and toast but not
channel uri.
Case 2: If I won't comment ecb able to get toast and channel uri but
not raw
My code as follows:
if (device.platform == "Win32NT") {
console.log("called");
pushNotification.register(
channelHandler,
errorHandler,
{
"channelName": "channelName",
"ecb": onNotificationWP8,
"uccb": channelHandler,
"errcb": jsonErrorHandler
});
}
else {
console.log("not called");
}
}
function channelHandler(event) {
var uri = event.uri;
console.log("UUUUURRRRRRRRRRRIIIIIIIII :" + uri);
}
function errorHandler(e) {
}
function jsonErrorHandler(error) {
$("#app-status-ul").append('<li style="color:red;">error:' + error.code + '</li>');
$("#app-status-ul").append('<li style="color:red;">error:' + error.message + '</li>');
}
function onNotificationWP8(e) {
console.log("notification called");
if (e.type == "toast" && e.jsonContent){
pushNotification.showToastNotification(successHandler, errorHandler,
{
"Title": e.jsonContent["wp:Text1"], "Subtitle": e.jsonContent["wp:Text2"], "NavigationUri": e.jsonContent["wp:Param"]
});
}
if (e.type == "raw" && e.jsonContent) {
alert(e.jsonContent.Body);
}
}
Tried with error and trail methods. Please suggest what might went wrong.
The issue observed does not appear to be related to Worklight at all. From the description and the code snippet, you are bypassing Worklight client SDK and server completely , and using a custom Cordova Push plugin. The custom plugin's working in your application should be analyzed to understand the variance in behaviour.
Since you are not using Worklight Push at all, you can try disabling it and check if this helps your case.
To do this, navigate to the config.xml . This will be located in apps/YourAppName/WindowsPhone8/native/Resources folder.
Look for :
<feature name="Push">
<param name="wp-package" value="Push" />
</feature>
Change this to:
<feature name="Push">
<param name="wp-package" value="Push" />
<param name="onload" value="false" />
</feature>
On the query regarding Worklight API:
There are no Worklight APIs that return Channel URI. When using Worklight SDK for Push, all this is done automatically and hidden from the user. Even with a Push Adapter in place, it is not possible to obtain the channel URI as there no APIs published to obtain this information.
Finally it got solved by adding Coding4Fun.Toolkit.Controls.dll
And some code updation in PushPlugin.cs
using Coding4Fun.Toolkit.Controls;
using System.Windows.Threading;
void PushChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
string msg = string.Empty;
foreach (var item in e.Collection)
{
if (item.Key == "wp:Text1")
{
msg = item.Value;
}
}
MessageBox.Show(msg, "Notification", MessageBoxButton.OK);
});
}
My heart-full thanks to Rajith who helped me to make it happen.

new APIs for windows phone 8.1

I am trying to use these two methods (of WP 8) in windows phone 8.1, but it gives error and doesn't compile, most probably becasue they are removed. I tried searching the new APIs but couldn't get any. What are other alternatives for these.
Dispatcher.BeginInvoke( () => {}); msdn link
System.Threading.Thread.Sleep(); msdn link
They still exists for Windows Phone 8.1 SIlverlight Apps, but not for Windows Phone Store Apps. The replacements for Windows Store Apps is:
Sleep (see Thread.Sleep replacement in .NET for Windows Store):
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(30));
Dispatcher (see How the Deployment.Current.Dispatcher.BeginInvoke work in windows store app?):
CoreDispatcher dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { });
Dispatcher.BeginInvoke( () => {}); is replaced by
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () => {});
and System.Threading.Thread.Sleep(); is replaced by
await Task.Delay(TimeSpan.FromSeconds(doubleValue));
Be aware that not only has the API changed (adopting the API from WindowsStore apps), but the way that the Dispatcher was obtained in windowsPhone 8.0 has changed as well.
#Johan Faulk's suggestion, although will work, may return null under a multitude of conditions.
Old code to grab the dispatcher:
var dispatcher = Deployment.Current.Dispatcher;
or
Deployment.Current.Dispatcher.BeginInvoke(()=>{
// any code to modify UI or UI bound elements goes here
});
New in Windows 8.1 Deployment is not an available object or namespace.
In order to make sure the Main UI Thread dispatcher is obtained, use the following:
var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
or
CoreApplication.MainWindow.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
()=>{
// UI code goes here
});
Additionally, although the method SAYS it will be executed Async the keyword await can not be used in the method invoked by RunAsync. (in the above example the method is anonymous).
In order to execute an awaitable method inside anonymous method above, decorate the anonymous method inside RunAsync() with the async keyword.
CoreApplication.MainWindow.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
**async**()=>{
// UI code goes here
var response = **await** LongRunningMethodAsync();
});
For Dispatcher, try this. MSDN
private async Task MyMethod()
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { });
}
For Thread.Sleep() try await Task.Delay(1000). MSDN

Windows phone 8 notification hub unregister

Can someone show me or tell some example how to unregister from notification hub in windows phone 8. I tried on this way but it doesn't work.
public void registerForNotifications(string[] tags)
{
var channel = HttpNotificationChannel.Find("xxx");
if (channel == null)
{
channel = new HttpNotificationChannel("xxx");
channel.Open();
channel.BindToShellToast();
}
string[] tagsToSubscribeTo = tags;
channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(async (o, args) =>
{
var hub = new NotificationHub("xxx", "xxx");
await hub.RegisterNativeAsync(args.ChannelUri.ToString(), tagsToSubscribeTo);
});
}
public async void unregisterFromNotifications()
{
var channel = HttpNotificationChannel.Find("xxx");
var hub = new NotificationHub("xxx", "xxx");
await hub.UnregisterAllAsync(channel.ChannelUri.ToString());
}
You didn't say what "it didn't work" means. Did you get an error message? Did it report success but actually fail? In your questions, it really helps more if you share those things. But I'll take a stab at this anyway.
I suspect that you might be using the DefaultListenSharedAccessSignature endpoint from your Windows Phone 8 app.
According to http://msdn.microsoft.com/en-us/library/dn495373.aspx, the Listen access level grants permission to:
Create/Update registration.
Read registration.
Read all registrations for a handle.
Delete registration.
Reading that last one, I wonder if the UnregisterAllAsync method might require a higher access level to delete all registrations, rather than just one.
But rather than use the DefaultFullSharedAccessSignature endpoint, I would rather just try the UnregisterAsync method instead of UnregisterAllAsync.
Disclaimer: I have not tried this out. It may not help at all.

How to trust a self-signed certificate in a windows store app

I am trying to override the certificate validation in a Windows Store App to accept a self-signed certificate on two external services (using HttpClient) to allow the Windows 8 app to accept the certificates and establish a trust relationship for SSL
EDIT:
I implemented the approach documented here : Installing certs by using the appmanifest
and added the relevant .cer files to my application and ensured they are 'Content' and 'Copy Always'.
My package.appxmanifest Extensions section looks like this:
<Extensions>
<Extension Category="windows.certificates">
<Certificates>
<Certificate StoreName="TrustedPeople" Content="Assets\ReportingServices.cer" />
<Certificate StoreName="TrustedPeople" Content="Assets\Crm.cer" />
<Certificate StoreName="CA" Content="Assets\DigiCertHighAssurance.cer" />
<TrustFlags ExclusiveTrust="true" />
<SelectionCriteria AutoSelect="true" />
</Certificates>
</Extension>
but this still does not work.
I have tried putting the app certificates in the 'Root' StoreName but still no success. Does anyone have any ideas why this might not work please?
This is a bit of old one, but seeing as there are quite a few watchers I will give my solution.
// Create the httpClient and send the request
HttpBaseProtocolFilter aHBPF = new HttpBaseProtocolFilter();
// If you want to ignore expired Certs
aHBPF.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired);
// Untrused because this is a self signed cert that is not installed
aHBPF.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
// Host names and certs names may not match
aHBPF.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
HttpClient httpClient = new HttpClient(aHBPF);
HttpResponseMessage response = await httpClient.SendRequestAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).AsTask(cts.Token);
Just to save your time. I got to resolve this for 2 days of trial and error. Here you can solve it.
Add the .cer file to your project, Make the build action as "Content", copy as newer
then add this to your app manifest
<Capabilities>
<Capability Name="sharedUserCertificates" />
<Capability Name="enterpriseAuthentication" />
<Capability Name="privateNetworkClientServer" />
<Capability Name="internetClient" />
</Capabilities>
<Extensions>
<Extension Category="windows.certificates">
<Certificates>
<Certificate StoreName="Root" Content="Certificates\vibeapi.cer" />
<TrustFlags ExclusiveTrust="true" />
<SelectionCriteria AutoSelect="true" />
</Certificates>
</Extension>
</Extensions>
and to your code behind you can now access the file using this
//Testing https connection
HttpClientHandler msgHandler = new HttpClientHandler();
using (System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient(msgHandler, true))
{
var HTTPSURL = new Uri("https://www.sample.net/");
var response = await httpClient.GetAsync(HTTPSURL);
var responseStr = await response.Content.ReadAsStringAsync();
}
see link for reference
help
It will work if you put cer file to the project root and change Content section in manifest file to Content="file.cer"