How to display an error message in Xamarin PCL - xamarin

I'm doing a simple try/catch (in a PCL project) to validate the users connection to the app, but I cant seem to find the DisplayAlert() method used in the Xamarin websites example.
Here are my usings:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Security;
using System.Diagnostics;
Here is the code:
public async Task Connexion()
{
// on met en place un try catch pour déceler toute erreur dans la procédure de connexion
try
{
// url de récupération du json de l'acteur
string urlActeur = "http://10.0.0.5/ppe3JoJuAd/gsbAppliFraisV2/webservices/w_visiteur.php" + "?" + "login=" + Login + "&" + "pass=" + Pass;
//instanciation du client http qui envoi un header json
HttpClient clientActeur = new HttpClient();
clientActeur.DefaultRequestHeaders.Accept.Clear();
clientActeur.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//réponse à la requête Http
var response = await clientActeur.GetAsync(urlActeur);
var json = response.Content.ReadAsStringAsync().Result;
var acteurJson = JsonConvert.DeserializeObject<ActeurJson>(json);
//on vérifie les informations de connexion du user (ici cela se ait avec oldMdp car pas d'implémentation du SHA1 actuellement en Xamarin, auquel cas nous auions converti le contenu du champ pass en sha1 puis vérification avec le champ mdp de l'acteur)
if (acteurJson.Acteur.login == login && acteurJson.Acteur.mdp == acteurJson.Acteur.oldMdp)
App.Current.MainPage = new VisitePage();
}
catch
{
await DisplayAlert()//intelisense does not find the using or the required dll
}
where should I look or what should I do to display the message ?

You shouldn't do a DisplayAlert from a Task. You should relay a message back to the calling class about a failure or just raise the exception to the calling class. For a task to come back into the UI and raise a message is bad.
Also your use of HttpClient is off. HttpClient is meant to be used as a singleton method. Try and create one per project or modules as a static singleton.
All that being said, try this:
public class ConnexionHelper
{
public async Task Connexion()
{
try
{
System.Diagnostics.Debug.WriteLine("trying stuff");
}
catch( Exception ex )
{
Xamarin.Forms.Page ourPage = App.Current.MainPage.Navigation.NavigationStack.LastOrDefault();
if (ourPage != null)
{
await ourPage.DisplayAlert("eeek", "error has occurrred", "not ok");
}
}
}

Application.Current.MainPage.DisplayAlert should works

Its better to add userdialogs plugin for xamarin. It comes up with different type of alerts,toasts etc for showing messages in the UI. Also it gives a better UI.
You can install the userdialogs from https://www.nuget.org/packages/Acr.UserDialogs/
After installing, you can show alert as follows:
UserDialogs.Instance.Alert("","","OK">);
You can also display alert as toasts.

You can display toast message using Toasts.Forms.Plugin
Setup
In your iOS, Android, WinRT and UWP projects please call:
DependencyService.Register<ToastNotification>(); // Register your dependency
ToastNotification.Init();
// If you are using Android you must pass through the activity
ToastNotification.Init(this);
If you are using Xamarin Forms, you must do this AFTER your call to Xamarin.Forms.Init();
Permissions
In iOS you must request permission to show local notifications first since it is a user interrupting action.
// Request Permissions
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
// Request Permissions
UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound, (granted, error) =>
{
// Do something if needed
});
}
else if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var notificationSettings = UIUserNotificationSettings.GetSettingsForTypes(
UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, null);
app.RegisterUserNotificationSettings(notificationSettings);
}
Usage
Use dependency service in order to resolve IToastNotificator.
var notificator = DependencyService.Get<IToastNotificator>();
var options = new NotificationOptions()
{
Title = "Title",
Description = "Description"
};
var result = await notificator.Notify(options);
The result that is returned is a NotificationResult with an Action inside with one of the following values.
[Flags]
public enum NotificationAction
{
Timeout = 1, // Hides by itself
Clicked = 2, // User clicked on notification
Dismissed = 4, // User manually dismissed notification
ApplicationHidden = 8, // Application went to background
Failed = 16 // When failed to display the toast
}
If you want the Clicked NotificationAction you must set IsClickable = true in the NotificationOptions.

Related

UWP sideload app that use Microsoft.Office.Interop.Outlook COM

Hello Im updating a UWP app that we use in ouroffice.
Before when we use it to send email it uses the Windows.ApplicationModel.Email.EmailMessage however this i really limited. So i would like to use Microsoft.Office.Interop.Outlook instead to create the email directly with outlook
My test code looks like this.
try
{
List<string> lstAllRecipients = new List<string>();
//Below is hardcoded - can be replaced with db data
lstAllRecipients.Add("info#test.com");
//lstAllRecipients.Add("chandan.kumarpanda#testmail.com");
Outlook.Application outlookApp = new Outlook.Application();
Outlook._MailItem oMailItem = (Outlook._MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
Outlook.Inspector oInspector = oMailItem.GetInspector;
// Thread.Sleep(10000);
// Recipient
Outlook.Recipients oRecips = (Outlook.Recipients)oMailItem.Recipients;
foreach (String recipient in lstAllRecipients)
{
Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add(recipient);
oRecip.Resolve();
}
////Add CC
//Outlook.Recipient oCCRecip = oRecips.Add("THIYAGARAJAN.DURAIRAJAN#testmail.com");
//oCCRecip.Type = (int)Outlook.OlMailRecipientType.olCC;
//oCCRecip.Resolve();
//Add Subject
oMailItem.Subject = "Test Mail";
// body, bcc etc...
//Display the mailbox
oMailItem.Display(true);
}
catch (Exception objEx)
{
await new MessageDialog(objEx.Message, "Error email to Outlook").ShowAsync();
}
I have added the Microsoft.Office.Interop.Outlook.dll version to the app by finding it in C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Interop.Outlook\15.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Outlook.dll it is file version 15.0.4569.1507
My problem is when i run the code i get the following error
Creating an instance of the COM component with CLSID {0006F03A-0000-0000-C000-000000000046} using CoCreateInstanceFromApp failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)). Please make sure your COM object is in the allowed list of CoCreateInstanceFromApp.
I guees i have to add a reference in the appxmanifest how ever i cannot figure out what.

sponsored messages on facebook with bot framework

How can I send a message to the user without the user sending me a message? Like for example CNN bot is sending messages every day in the morning by itself. How can I do that in the bot framework?
See this.
In fact, you do not strictly need to receive a message from the user first, but addressing manually can be error-prone (you have to know the user's and bot's channel account, the service URL, etc.)
And in turn (per #thegaram's message), that only works for some channels. For example, Skype requires that the user contact the bot before the bot can message the user.
Once contacted, you can store the user's channelAccount data once they contact you and use that to send them proactive messages. For example if the user has subscribed to hear sports scores for a particular team over time.
Any sort of unsolicited spam messages of course are prohibited by the policies of the Bot Framework (and most of the channels).
Yes you can do that. We called it Greeting from Bot. I have done it and sharing a sample code with you.
Write this code in your messageController or first dialog used in bot.
if (activity.Text == null)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
Activity isActivityTyping = activity.CreateReply();
isActivityTyping.Type = ActivityTypes.Typing;
await connector.Conversations.ReplyToActivityAsync(isActivityTyping);
await Conversation.SendAsync(activity, () => new Dialogs.GreetDialog());
}
after this code you need to create a dialog GreetDialog. Below is the cs file code for your reference.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
namespace GPP.Bot.Dialogs
{
[Serializable]
internal class GreetDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(Greeting);
}
private async Task Greeting(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
var message = await argument;
if (string.IsNullOrEmpty(message.Text))
{
// Hero Card
var cardMsg = context.MakeMessage();
var attachment = BotWelcomeCard("Hello, I am a bot. Right now I am on training and in a prototype state", "");
cardMsg.Attachments.Add(attachment);
await context.PostAsync(cardMsg);
context.Call<object>(new ActionDialog(), AfterGreetingDialogCompleted);
}
else
{
context.Call<object>(new ActionDialog(), AfterGreetingDialogCompleted);
}
}
private static Attachment BotWelcomeCard(string responseFromQNAMaker, string userQuery)
{
var heroCard = new HeroCard
{
Title = userQuery,
Subtitle = "",
Text = responseFromQNAMaker,
Images = new List<CardImage> { new CardImage("https://i2.wp.com/lawyerist.com/lawyerist/wp-content/uploads/2016/08/docubot.gif?fit=322%2C294&ssl=1") },
Buttons = new List<CardAction> { new CardAction(ActionTypes.ImBack, "Show Menu", value: "Show Bot Menu") }
};
return heroCard.ToAttachment();
}
private async Task AfterGreetingDialogCompleted(IDialogContext context, IAwaitable<object> result)
{
context.Done<object>(new object());
}
}
}
this is a working code. Do let me know in case you face ant issue.
~cheers :)

WebRequest returns 404 when switching to SSL

Having built an app using PCL method in Xamarin and have had it working 100% using standard HTTP I now changed the remote test server to use SSL with self signed certs.
The app contacts a custom API for logging onto a server and querying for specific data.
I've changed the app to look at SSL now and initially got an error regarding Authentication not working or something but turned off SSL related errors for testing using:
ServicePointManager.ServerCertificateValidationCallback += (o, certificate, chain, errors) => true;
in my AppDelegate files FinishedLaunching method which got over that error.
I'm now getting a 404 / protocol error when trying to do my Login POST to the given URL.
I am using HttpWebRequest for my RESTful calls and this works fine if I change back to plain http.
Not sure why but some articles suggested using ModernHttpClient, which I did. I imported the component (also added the package using NuGet) to no avail.
Am I missing something else that I should be configuring in my code related to httpwebresponse when contacting the SSL server or is this component simply incapable of speaking to an SSL server?
My login function is as follows (Unrelated code removed/obfuscated):
public JsonUser postLogin(string csrfToken, string partnerId, string username, string password){
string userEndPoint = SingletonAppSettngs.Instance ().apiEndPoint;
userEndPoint = userEndPoint.Replace ("druid/", "");
var request = WebRequest.CreateHttp(string.Format(this.apiBaseUrl + userEndPoint + #"user/login.json"));
// Request header collection set up
request.ContentType = "application/json";
request.Headers.Add ("X-CSRF-Token", csrfToken);
// Add other configs
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json_body_content = "{\"username\":\"" + username + "\",\"password\":\"" + password + "\"}";
streamWriter.Write(json_body_content);
streamWriter.Flush();
streamWriter.Close();
}
try{
HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader (httpResponse.GetResponseStream ())) {
var content = reader.ReadToEnd ();
content = content.Replace ("[],", "null,");
content = content.Replace ("[]", "null");
if (content == null) {
throw new Exception ("request_post_login - content is NULL");
} else {
JsonSerializerSettings jss = new JsonSerializerSettings();
jss.NullValueHandling = NullValueHandling.Ignore;
JsonUser deserializedUser = JsonConvert.DeserializeObject<JsonUser>(content, jss);
if(content.Contains ("Hire company admin user")){
deserializedUser.user.roles.__invalid_name__5 = "Hire company admin user";
deserializedUser.user.roles.__invalid_name__2 = "authenticated user";
}
return deserializedUser;
}
}
}catch(Exception httpEx){
Console.WriteLine ("httpEx Exception: " + httpEx.Message);
Console.WriteLine ("httpEx Inner Exception: " + httpEx.InnerException.Message);
JsonUser JsonUserError = new JsonUser ();
JsonUserError.ErrorMessage = "Error occured: " + httpEx.Message;
return JsonUserError;
}
}
When making a Web Request using ModernHttpClient, I generally follow the pattern below. Another great library created by Paul Betts is refit, and can be used to simplify rest calls.
using (var client = new HttpClient(new NativeMessageHandler(false, false)))
{
client.BaseAddress = new Uri(BaseUrl, UriKind.Absolute);
var result = await Refit.RestService.For<IRestApi>(client).GetData();
}
The second parameter for NativeMessageHandler should be set to true if using a customSSLVerification.
Here's a look at IRestApi
public interface IRestApi
{
[Get("/foo/bar")]
Task<Result> GetMovies();
}
Number of things I had to do to get this to work.
The Self Signed Cert had to allow TLS 1.2
As the API is Drupal based, HTTPS had to be enabled on the server and a module installed to manage the HTTP specific pages.

Error occuring in authenticating my weburl to windows

I have doing push notifications for my windows phone 8.1.
for getting push notifications i am trying to authenticate with WNS(windows notification service) in order to get a access token..
Here is my code..
protected async void GetAccessToken(string secret, string sid)
{
var urlSe =WebUtility.UrlEncode(secret);
var urlsId = WebUtility.UrlEncode(sid);
var body = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com",urlSe ,urlsId);
Uri url1 = new Uri("https://login.live.com/accesstoken.srf" + body);
String response1;
System.Net.Http.HttpClient httpclient = new System.Net.Http.HttpClient();
using (var client = httpclient)
{
client.DefaultRequestHeaders.Add("Content-Type", "application/x-www-form-urlencoded");
System.Net.Http.HttpResponseMessage respnse = await client.GetAsync(url1);
var result =await respnse.Content.ReadAsStringAsync();
}
}
Whenever it try's to enter the "respnse" line of code it gives me a exception
A first chance exception of type 'System.InvalidOperationException' occurred in System.Net.Http.Phone.ni.DLL
I don't know what is the problem,i referred to the following link
and created this code..
https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868206.aspx
Note:the code is for windows 8 phone,but i am doing for windows 8.1 phone app

How to open a webView in Windows Phone 7.x?

I would like my app to have only one view.
I need this view to be an external URL.
I tried to use the webBrowser Task following the example on microsoft.
I put on my constractor :
WebBrowserTask webBrowserTask = new WebBrowserTask();
webBrowserTask.Uri = new Uri("http://msdn.microsoft.com", UriKind.Absolute);
webBrowserTask.Show();
However when i press the back button instead of navigating outside the app , i am navigating to the first page which is empty...
My code looks like this :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
//added this for push
using Microsoft.Phone.Notification;
using System.Text;
//added this to open an external URL using the WebBrowser Task
using Microsoft.Phone.Tasks;
namespace WindowsPush
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
/// Holds the push channel that is created or found.
HttpNotificationChannel pushChannel;
// The name of our push channel.
string channelName = "ToastSampleChannel";
InitializeComponent();
// Try to find the push channel.
pushChannel = HttpNotificationChannel.Find(channelName);
// If the channel was not found, then create a new connection to the push service.
if (pushChannel == null)
{
pushChannel = new HttpNotificationChannel(channelName);
// Register for all the events before attempting to open the channel.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
// Register for this notification only if you need to receive the notifications while your application is running.
//pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
pushChannel.Open();
// Bind this new channel for toast events.
pushChannel.BindToShellToast();
}
else
{
// The channel was already open, so just register for all the events.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
// Register for this notification only if you need to receive the notifications while your application is running.
//pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
// Display the URI for testing purposes. Normally, the URI would be passed back to your web service at this point.
System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString());
// MessageBox.Show(String.Format("Channel Uri is {0}", pushChannel.ChannelUri.ToString()));
}
object uniqueID;
if (Microsoft.Phone.Info.DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueID) == true)
{
byte[] bID = (byte[])uniqueID;
string deviceID = Convert.ToBase64String(bID); // There you go
System.Diagnostics.Debug.WriteLine("Device Unique Id is: {0}", deviceID);
}
//opening the external URL using webBrowserTask
WebBrowserTask webBrowserTask = new WebBrowserTask();
webBrowserTask.Uri = new Uri("http://msdn.microsoft.com", UriKind.Absolute);
webBrowserTask.Show();
}
void PushChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
Dispatcher.BeginInvoke(() =>
{
// Display the new URI for testing purposes. Normally, the URI would be passed back to your web service at this point.
System.Diagnostics.Debug.WriteLine(e.ChannelUri.ToString());
MessageBox.Show(String.Format("Channel Uri is {0}", e.ChannelUri.ToString()));
});
}
void PushChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
{
// Error handling logic for your particular application would be here.
Dispatcher.BeginInvoke(() =>
MessageBox.Show(String.Format("A push notification {0} error occurred. {1} ({2}) {3}", e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData)));
}
}
}
What i need is just load an external URL on the first and only view of my app.
How could i do that?
You're looking for the WebBrowser control. Add it to the main application page and handle it like you would a WebBrowserTask.
If you're going to use the WebBrowserTask then you could close the app on returning to it by throwing an unhandled exception:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.Back)
{
throw new Exception("deliberately doing this to force the app to close");
}
}
If/when you do this in Windows Phone 8 you can call Application.Current.Terminate(); instead of throwing the exception.
Be sure to check the marketplace certification requirements for apps that just launch an external website before submitting though.

Resources