Gmail User/Password Authentication in Google Drive API for DotNet - asp.net

Iam using GoogleDriveAPI to upload Documents to Drive from Asp.net.It is working fine but i need to use ClientID and ClientSecret for Authentication. Not the gmail userName/Password.After Authentication for Authorization it is redirected to gmail for login after login it is asking for AccessPermission for Drive.So how can i pass the GmailUserID and Password for Authentication not the ClientID and ClientSecret . and after that can i restrict again from Login for Authorization .
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DotNetOpenAuth.OAuth2;
using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using Google.Apis.Drive.v2;
using Google.Apis.Drive.v2.Data;
using Google.Apis.Util;
using System.Diagnostics;
using DotNetOpenAuth.Messaging;
using System.Text;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
private static DriveService driveService;
private static OAuth2Authenticator<WebServerClient> authenticator;
private static IAuthorizationState _state;
String CLIENT_ID = "90994017777728.apps.googleusercontent.com";
String CLIENT_SECRET = "IR777777773Nf3vnLT0v";
private static readonly string[] SCOPES = new[] { DriveService.Scopes.Drive.GetStringValue() };
protected void Page_Load(object sender, EventArgs e)
{
Login();
}
private IAuthorizationState AuthState {
get {
return _state ?? HttpContext.Current.Session["GoogleAuthState"] as IAuthorizationState;
}
}
private OAuth2Authenticator<WebServerClient> CreateAuthenticator() {
var provider = new WebServerClient(GoogleAuthenticationServer.Description,CLIENT_ID,CLIENT_SECRET);
var authenticator = new OAuth2Authenticator<WebServerClient>(provider,GetAuthorization);
return authenticator;
}
private IAuthorizationState GetAuthorization(WebServerClient client) {
IAuthorizationState state = AuthState;
if (state != null) {
if (state.AccessTokenExpirationUtc.Value.CompareTo(DateTime.Now.ToUniversalTime()) > 0)
return state;
else
state = null;
}
state = client.ProcessUserAuthorization(new HttpRequestInfo(HttpContext.Current.Request));
if (state != null && (!string.IsNullOrEmpty(state.AccessToken) || !string.IsNullOrEmpty(state.RefreshToken))) {
if (state.RefreshToken == null)
state.RefreshToken = "";
HttpContext.Current.Session["GoogleAuthState"] = _state = state;
return state;
}
client.RequestUserAuthorization(SCOPES,"",HttpContext.Current.Request.Url); // Redirecting to Gmail LoginPage
return null;
}
private string GetContentType(string fileExtension) {
if (string.IsNullOrEmpty(fileExtension))
return string.Empty;
string contentType = string.Empty;
switch (fileExtension) {
case "htm":
case "html":
contentType = "text/HTML";
break;
case "txt":
contentType = "text/plain";
break;
case "doc":
case "rtf":
case "docx":
contentType = "Application/msword";
break;
case "xls":
case "xlsx":
contentType = "Application/x-msexcel";
break;
case "jpg":
case "jpeg":
contentType = "image/jpeg";
break;
case "png":
contentType = "image/png";
break;
case "bmp":
contentType = "image/bmp";
break;
case "gif":
contentType = "image/GIF";
break;
case "pdf":
contentType = "application/pdf";
break;
}
return contentType;
}
public void Login() {
if (authenticator == null)
authenticator = CreateAuthenticator();
if (driveService == null) {
driveService = new DriveService(authenticator);
}
}
protected void Button1_Click(object sender,EventArgs e) {
string[] stringParts = FileUpload1.FileName.Split(new char[] { '/' });
string str = stringParts[stringParts.Length - 1].ToString();
string[] strType = str.Split(new char[] { '.' });
string type = GetContentType(strType[1]);
Google.Apis.Drive.v2.Data.File newFile = new Google.Apis.Drive.v2.Data.File { Title = FileUpload1.FileName,MimeType = type };
byte[] byteArray = FileUpload1.FileBytes;
MemoryStream stream = new MemoryStream(byteArray);
FilesResource.InsertMediaUpload request = driveService.Files.Insert(newFile,stream,newFile.MimeType);
request.Convert = true;
request.Upload();
Google.Apis.Drive.v2.Data.File file = request.ResponseBody;
InsertPermission(driveService,file);
HttpContext.Current.Session["GoogleAuthState"] = null;
Response.Write(file.AlternateLink);
}
public void InsertPermission(DriveService service,Google.Apis.Drive.v2.Data.File file) {
Permission newPermission = new Permission();
newPermission.Value = TextBox1.Text;
newPermission.Type = "user";
newPermission.Role = "reader";
try {
Permission per = service.Permissions.Insert(newPermission,file.Id).Fetch();
}
catch (Exception e) {
Console.WriteLine("An error occurred: " + e.Message);
}
}

Related

FCM PushNotification to iOS device from .NET

Is it possible to use Firebase's FCM to send apns push notifications to an ios device?
Desired Workflow:
iOS app sends request to my .NET server to provide it the push token. My .NET server will handle all push notifications. So I assume this would be http requests to firebase and firebase would send out the notification?
Is this workflow possible?
I have worked with Android Applications using Firebase's FCM.. so i think there must be way to work with ios.
here is the snippet of code for sending push notification using fcm in c#.
NotifBooking objnotif = new NotifBooking();
string ApplicationID = "AIzaSyCBM20ZXXXXXXXXXXjog3Abv88";
string SENDER_ID = "962XXXXXXX";
var value = "Alert :" + Message + ""; //message text box
WebRequest tRequest;
tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send"); tRequest.Method = "post";
tRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
tRequest.Headers.Add(string.Format("Authorization: key={0}", ApplicationID)); tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));
tRequest.ContentType = "application/json";
var data1 = new
{
to = "" + dt.Rows[i]["RegId"].ToString().Trim() + "",//Device RegID
priority = "high",
notification = new
{
body = Message,
title = Heading,
is_background = true,
image = "abc.com/images/1_icon.png",
appicon = "abc.com/images/1_icon.png",
sound = "default"
},
data = new
{
//body = Message,
//is_background=false,
//title = "Test FCM",
//appicon = "myicon",
image = "abc.com/images/1_icon.png"
},
};
Console.WriteLine(data1);
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data1);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
string str = sResponseFromServer;
}
}
}
}
objnotif.data = json;
}
You should get device token from Firebase and register the current user in backend side with the same token.
After that, you can send push notifications from your backend.
Put this code in AppDelegate class.
Call InitAPNS() from FinishedLaunching.
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
//TODO: save token and register one in backend side
Settings.DeviceTokenFCM = InstanceId.SharedInstance.Token;
}
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
ShowPushMessage(userInfo);
}
private void ShowPushMessage(NSDictionary userInfo)
{
if (userInfo != null)
{
try
{
var apsDictionary = userInfo["aps"] as NSDictionary;
var alertDictionary = apsDictionary?["alert"] as NSDictionary;
var body = alertDictionary?["body"].ToString();
var title = alertDictionary?["title"].ToString();
var window = UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
var alert = UIAlertController.Create(title, body, UIAlertControllerStyle.Alert);
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Cancel, null));
vc.PresentViewController(alert, animated: true, completionHandler: null);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
}
}
private void InitAPNS()
{
// Monitor token generation
InstanceId.Notifications.ObserveTokenRefresh(TokenRefreshNotification);
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Sound, (granted, error) =>
{
if (granted)
{
InvokeOnMainThread(UIApplication.SharedApplication.RegisterForRemoteNotifications);
}
});
}
else if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var pushSettings = UIUserNotificationSettings.GetSettingsForTypes(
UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound,
new NSSet());
UIApplication.SharedApplication.RegisterUserNotificationSettings(pushSettings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
else
{
UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
}
Firebase.Core.App.Configure();
}
private void TokenRefreshNotification(object sender, NSNotificationEventArgs e)
{
ConnectToFCM();
}
private void ConnectToFCM()
{
var tokenFirebase = InstanceId.SharedInstance.Token;
////registation token in background thread
System.Threading.Tasks.Task.Run(() =>
{
if (!string.IsNullOrEmpty(tokenFirebase))
{
Firebase.CloudMessaging.Messaging.SharedInstance.SetApnsToken(tokenFirebase, ApnsTokenType.Production);
}
});
Messaging.SharedInstance.ShouldEstablishDirectChannel = true;
}
IOS push Notification using C#.I have worked with Android Applications using Firebase's FCM.here is the snippet of code for sending push notification using fcm in c#.
**
namespace push
{
public partial class pushios : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
SendPushNotification(txtDeviceToken.Text, txtMessage.Text);
}
private void SendPushNotification(string deviceToken,string message)
{
try
{
//Get Certificate
var appleCert = System.IO.File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/Files/Certificate/IOS/Production_Certificate.p12"));
// Configuration (NOTE: .pfx can also be used here)
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Production, appleCert, "1234567890");
// Create a new broker
var apnsBroker = new ApnsServiceBroker(config);
// Wire up events
apnsBroker.OnNotificationFailed += (notification, aggregateEx) =>
{
aggregateEx.Handle(ex =>
{
// See what kind of exception it was to further diagnose
if (ex is ApnsNotificationException)
{
var notificationException = (ApnsNotificationException)ex;
// Deal with the failed notification
var apnsNotification = notificationException.Notification;
var statusCode = notificationException.ErrorStatusCode;
string desc = $"Apple Notification Failed: ID={apnsNotification.Identifier}, Code={statusCode}";
Console.WriteLine(desc);
Label1.Text = desc;
}
else
{
string desc = $"Apple Notification Failed for some unknown reason : {ex.InnerException}";
// Inner exception might hold more useful information like an ApnsConnectionException
Console.WriteLine(desc);
Label1.Text = desc;
}
// Mark it as handled
return true;
});
};
apnsBroker.OnNotificationSucceeded += (notification) =>
{
Label1.Text = "Apple Notification Sent successfully!";
};
var fbs = new FeedbackService(config);
fbs.FeedbackReceived += (string devicToken, DateTime timestamp) =>
{
};
apnsBroker.Start();
if (deviceToken != "")
{
apnsBroker.QueueNotification(new ApnsNotification
{
DeviceToken = deviceToken,
Payload = JObject.Parse(("{\"aps\":{\"badge\":1,\"sound\":\"oven.caf\",\"alert\":\"" + (message + "\"}}")))
});
}
apnsBroker.Stop();
}
catch (Exception)
{
throw;
}
}
}
**
I have worked with Android Applications using Firebase's FCM..
namespace pushios.Controllers
{
public class HomeController : ApiController
{
[HttpGet]
[Route("sendmessage")]
public IHttpActionResult SendMessage()
{
var data = new {
to = "xxxxxxxxxxxxxxxxxxx",
data = new
{
body="Test",
confId= "6565",
pageTitle= "test",
pageFormat= "",
dataValue= "",
title= "C#",
webviewURL= "",
priority = "high",
notificationBlastID = "0",
status = true
}
};
SendNotification(data);
return Ok();
}
public void SendNotification(object data)
{
var Serializer = new JavaScriptSerializer();
var json = Serializer.Serialize(data);
Byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(json);
SendNotification(byteArray);
}
public void SendNotification(Byte[] byteArray)
{
try
{
String server_api_key = ConfigurationManager.AppSettings["SERVER_API_KEY"];
String senderid = ConfigurationManager.AppSettings["SENDER_ID"];
WebRequest type = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
type.Method = "post";
type.ContentType = "application/json";
type.Headers.Add($"Authorization: key={server_api_key}");
type.Headers.Add($"Sender: id={senderid}");
type.ContentLength = byteArray.Length;
Stream datastream = type.GetRequestStream();
datastream.Write(byteArray, 0, byteArray.Length);
datastream.Close();
WebResponse respones = type.GetResponse();
datastream = respones.GetResponseStream();
StreamReader reader = new StreamReader(datastream);
String sresponessrever = reader.ReadToEnd();
reader.Close();
datastream.Close();
respones.Close();
}
catch (Exception)
{
throw;
}
}
}
}
```

how to make a web application in .NET send notifications to firebase? [duplicate]

I am using this code to send notification message by C# with GCM, using Winforms, Webforms, whatever. Now I want to send to FCM (Firebase Cloud Messaging). Should I update my code? :
public class AndroidGCMPushNotification
{
public AndroidGCMPushNotification()
{
//
// TODO: Add constructor logic here
//
}
public string SendNotification(string deviceId, string message)
{
string SERVER_API_KEY = "server api key";
var SENDER_ID = "application number";
var value = message;
WebRequest tRequest;
tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
tRequest.Method = "post";
tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));
tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));
string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
Console.WriteLine(postData);
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;
Stream dataStream = tRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse tResponse = tRequest.GetResponse();
dataStream = tResponse.GetResponseStream();
StreamReader tReader = new StreamReader(dataStream);
String sResponseFromServer = tReader.ReadToEnd();
tReader.Close();
dataStream.Close();
tResponse.Close();
return sResponseFromServer;
}
}
but the GCM was changed to FCM. Is this same code to send the notification?
Where can I find the SERVER_API_KEY? Is the same solution?
firebase cloud messaging with c#:
working all .net platform (asp.net, .netmvc, .netcore)
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
//serverKey - Key from Firebase cloud messaging server
tRequest.Headers.Add(string.Format("Authorization: key={0}", "AIXXXXXX...."));
//Sender Id - From firebase project setting
tRequest.Headers.Add(string.Format("Sender: id={0}", "XXXXX.."));
tRequest.ContentType = "application/json";
var payload = new
{
to = "e8EHtMwqsZY:APA91bFUktufXdsDLdXXXXXX..........XXXXXXXXXXXXXX",
priority = "high",
content_available = true,
notification = new
{
body = "Test",
title = "Test",
badge = 1
},
data = new
{
key1 = "value1",
key2 = "value2"
}
};
string postbody = JsonConvert.SerializeObject(payload).ToString();
Byte[] byteArray = Encoding.UTF8.GetBytes(postbody);
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
if (dataStreamResponse != null) using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
//result.Response = sResponseFromServer;
}
}
}
}
Here is another approach of writing Notification Service inside ASP.Net REST API.
public async Task<bool> NotifyAsync(string to, string title, string body)
{
try
{
// Get the server key from FCM console
var serverKey = string.Format("key={0}", "Your server key - use app config");
// Get the sender id from FCM console
var senderId = string.Format("id={0}", "Your sender id - use app config");
var data = new
{
to, // Recipient device token
notification = new { title, body }
};
// Using Newtonsoft.Json
var jsonBody = JsonConvert.SerializeObject(data);
using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, "https://fcm.googleapis.com/fcm/send"))
{
httpRequest.Headers.TryAddWithoutValidation("Authorization", serverKey);
httpRequest.Headers.TryAddWithoutValidation("Sender", senderId);
httpRequest.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
using (var httpClient = new HttpClient())
{
var result = await httpClient.SendAsync(httpRequest);
if (result.IsSuccessStatusCode)
{
return true;
}
else
{
// Use result.StatusCode to handle failure
// Your custom error handler here
_logger.LogError($"Error sending notification. Status Code: {result.StatusCode}");
}
}
}
}
catch (Exception ex)
{
_logger.LogError($"Exception thrown in Notify Service: {ex}");
}
return false;
}
References:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
I have posted this answer as this question was viewed most and this server side code was written in VS 2015 in C# for sending push notification either single device based on device id or subscribed topic to Xamarin Android app
public class FCMPushNotification
{
public FCMPushNotification()
{
// TODO: Add constructor logic here
}
public bool Successful
{
get;
set;
}
public string Response
{
get;
set;
}
public Exception Error
{
get;
set;
}
public FCMPushNotification SendNotification(string _title, string _message, string _topic)
{
FCMPushNotification result = new FCMPushNotification();
try
{
result.Successful = true;
result.Error = null;
// var value = message;
var requestUri = "https://fcm.googleapis.com/fcm/send";
WebRequest webRequest = WebRequest.Create(requestUri);
webRequest.Method = "POST";
webRequest.Headers.Add(string.Format("Authorization: key={0}", YOUR_FCM_SERVER_API_KEY));
webRequest.Headers.Add(string.Format("Sender: id={0}", YOUR_FCM_SENDER_ID));
webRequest.ContentType = "application/json";
var data = new
{
// to = YOUR_FCM_DEVICE_ID, // Uncoment this if you want to test for single device
to="/topics/"+_topic, // this is for topic
notification=new
{
title=_title,
body=_message,
//icon="myicon"
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
webRequest.ContentLength = byteArray.Length;
using (Stream dataStream = webRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream dataStreamResponse = webResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
result.Response = sResponseFromServer;
}
}
}
}
}
catch(Exception ex)
{
result.Successful = false;
result.Response = null;
result.Error = ex;
}
return result;
}
}
and its uses
// start sending push notification to apps
FCMPushNotification fcmPush = new FCMPushNotification();
fcmPush.SendNotification("your notificatin title", "Your body message","news");
// end push notification
Yes, you should update your code to use Firebase Messaging interface.
There's a GitHub Project for that here.
using Stimulsoft.Base.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
namespace _WEBAPP
{
public class FireBasePush
{
private string FireBase_URL = "https://fcm.googleapis.com/fcm/send";
private string key_server;
public FireBasePush(String Key_Server)
{
this.key_server = Key_Server;
}
public dynamic SendPush(PushMessage message)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(FireBase_URL);
request.Method = "POST";
request.Headers.Add("Authorization", "key=" + this.key_server);
request.ContentType = "application/json";
string json = JsonConvert.SerializeObject(message);
//json = json.Replace("content_available", "content-available");
byte[] byteArray = Encoding.UTF8.GetBytes(json);
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
HttpWebResponse respuesta = (HttpWebResponse)request.GetResponse();
if (respuesta.StatusCode == HttpStatusCode.Accepted || respuesta.StatusCode == HttpStatusCode.OK || respuesta.StatusCode == HttpStatusCode.Created)
{
StreamReader read = new StreamReader(respuesta.GetResponseStream());
String result = read.ReadToEnd();
read.Close();
respuesta.Close();
dynamic stuff = JsonConvert.DeserializeObject(result);
return stuff;
}
else
{
throw new Exception("Ocurrio un error al obtener la respuesta del servidor: " + respuesta.StatusCode);
}
}
}
public class PushMessage
{
private string _to;
private PushMessageData _notification;
private dynamic _data;
private dynamic _click_action;
public dynamic data
{
get { return _data; }
set { _data = value; }
}
public string to
{
get { return _to; }
set { _to = value; }
}
public PushMessageData notification
{
get { return _notification; }
set { _notification = value; }
}
public dynamic click_action
{
get
{
return _click_action;
}
set
{
_click_action = value;
}
}
}
public class PushMessageData
{
private string _title;
private string _text;
private string _sound = "default";
//private dynamic _content_available;
private string _click_action;
public string sound
{
get { return _sound; }
set { _sound = value; }
}
public string title
{
get { return _title; }
set { _title = value; }
}
public string text
{
get { return _text; }
set { _text = value; }
}
public string click_action
{
get
{
return _click_action;
}
set
{
_click_action = value;
}
}
}
}
Based on Teste's code .. I can confirm the following works. I can't say whether or not this is "good" code, but it certainly works and could get you back up and running quickly if you ended up with GCM to FCM server problems!
public AndroidFCMPushNotificationStatus SendNotification(string serverApiKey, string senderId, string deviceId, string message)
{
AndroidFCMPushNotificationStatus result = new AndroidFCMPushNotificationStatus();
try
{
result.Successful = false;
result.Error = null;
var value = message;
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
tRequest.Headers.Add(string.Format("Authorization: key={0}", serverApiKey));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
result.Response = sResponseFromServer;
}
}
}
}
}
catch (Exception ex)
{
result.Successful = false;
result.Response = null;
result.Error = ex;
}
return result;
}
public class AndroidFCMPushNotificationStatus
{
public bool Successful
{
get;
set;
}
public string Response
{
get;
set;
}
public Exception Error
{
get;
set;
}
}
You need change url from https://android.googleapis.com/gcm/send to https://fcm.googleapis.com/fcm/send and change your app library too. this tutorial can help you https://firebase.google.com/docs/cloud-messaging/server#implementing-http-connection-server-protocol
Try to send a json object.
Replace this:
tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
Console.WriteLine(postData);
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
For this:
tRequest.ContentType = "application/json";
var data = new
{
to = deviceId,
notification = new
{
body = "This is the message",
title = "This is the title",
icon = "myicon"
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
Here's the code for server side firebase cloud request from C# / Asp.net.
Please note that your client side should have same topic.
e.g.
FirebaseMessaging.getInstance().subscribeToTopic("news");
public String SendNotificationFromFirebaseCloud()
{
var result = "-1";
var webAddr = "https://fcm.googleapis.com/fcm/send";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add("Authorization:key=" + YOUR_FIREBASE_SERVER_KEY);
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"to\": \"/topics/news\",\"data\": {\"message\": \"This is a Firebase Cloud Messaging Topic Message!\",}}";
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
return result;
}
You can use this library, makes it seamless to send push notifications using Firebase Service from a C# backend download here
public SendNotice(int deviceType, string deviceToken, string message, int badge, int status, string sound)
{
AndroidFCMPushNotificationStatus result = new AndroidFCMPushNotificationStatus();
try
{
result.Successful = false;
result.Error = null;
var value = message;
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var serializer = new JavaScriptSerializer();
var json = "";
tRequest.Headers.Add(string.Format("Authorization: key={0}", "AA******"));
tRequest.Headers.Add(string.Format("Sender: id={0}", "11********"));
if (DeviceType == 2)
{
var body = new
{
to = deviceToken,
data = new
{
custom_notification = new
{
title = "Notification",
body = message,
sound = "default",
priority = "high",
show_in_foreground = true,
targetScreen = notificationType,//"detail",
},
},
priority = 10
};
json = serializer.Serialize(body);
}
else
{
var body = new
{
to = deviceToken,
content_available = true,
notification = new
{
title = "Notification",
body = message,
sound = "default",
show_in_foreground = true,
},
data = new
{
targetScreen = notificationType,
id = 0,
},
priority = 10
};
json = serializer.Serialize(body);
}
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
result.Response = sResponseFromServer;
}
}
}
}
}
catch (Exception ex)
{
result.Successful = false;
result.Response = null;
result.Error = ex;
}
}
I write this code and It's worked for me .
public static string ExcutePushNotification(string title, string msg, string fcmToken, object data)
{
var serverKey = "AAAA*******************";
var senderId = "3333333333333";
var result = "-1";
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://fcm.googleapis.com/fcm/send");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add(string.Format("Authorization: key={0}", serverKey));
httpWebRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
httpWebRequest.Method = "POST";
var payload = new
{
notification = new
{
title = title,
body = msg,
sound = "default"
},
data = new
{
info = data
},
to = fcmToken,
priority = "high",
content_available = true,
};
var serializer = new JavaScriptSerializer();
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = serializer.Serialize(payload);
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
return result;
}
I am using this approach and it is working fine:
public class PushNotification
{
private static readonly ILog Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// firebase
private static Uri FireBasePushNotificationsURL = new Uri("https://fcm.googleapis.com/fcm/send");
private static string ServerKey = ConfigurationManager.AppSettings["FIREBASESERVERKEY"];
public static async Task<bool> SendPushNotification(List<SendNotificationModel> notificationData)
{
try
{
bool sent = false;
foreach (var data in notificationData)
{
var messageInformation = new Message()
{
notification = new Notification()
{
title = data.Title,
text = data.Message,
ClickAction = "FCM_PLUGIN_ACTIVITY"
},
data = data.data,
priority="high",
to =data.DeviceId
};
string jsonMessage = JsonConvert.SerializeObject(messageInformation);
//Create request to Firebase API
var request = new HttpRequestMessage(HttpMethod.Post, FireBasePushNotificationsURL);
request.Headers.TryAddWithoutValidation("Authorization", "key=" + ServerKey);
request.Content = new StringContent(jsonMessage, Encoding.UTF8, "application/json");
HttpResponseMessage result;
using (var client = new HttpClient())
{
result = await client.SendAsync(request);
sent = result.IsSuccessStatusCode;
}
}
return sent;
}
catch(Exception ex)
{
Logger.Error(ex);
return false;
}
}
}
Following Approach, I have used for writing Firebase Notification Service inside ASP.Net REST API.
public async Task<bool> NotifyAsync(string to, string title, string body)
{
try
{
//Server key from FCM console
var serverKey = string.Format("key={0}", "Provide your Server key here from Fibase console");
//Sender id from FCM console
var senderId = string.Format("id={0}", "Provide your Sender Id here from Firebase Console");
var data = new
{
to, // Recipient device token
notification = new { title, body }
};
// Using Newtonsoft.Json
var jsonBody = JsonConvert.SerializeObject(data);
using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, "https://fcm.googleapis.com/fcm/send"))
{
httpRequest.Headers.TryAddWithoutValidation("Authorization", serverKey);
httpRequest.Headers.TryAddWithoutValidation("Sender", senderId);
httpRequest.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
using (var httpClient = new HttpClient())
{
var result = await httpClient.SendAsync(httpRequest);
if (result.IsSuccessStatusCode)
{
return true;
}
else
{
// Use result.StatusCode to handle failure
// Your custom error handler here
return false;
}
}
}
}
catch (Exception ex)
{
throw ex;
}
return false;
}
Refer This blog for send Group Notification
https://firebase.google.com/docs/cloud-messaging/android/send-multiple

Windows Phone 8 http post file upload timeout

I am developing a Windows phone 8 app that needs to upload photos to amazon s3 storage. However, I find that this is impossible since the HttpClient time out after about 60 seconds regardless of what timeout setting I use.
Is there really no way to upload large files from Windows Phone?
BackgroundTransferRequest is useless since it cannot send the neccessary metadata with file uploads.
I use this code (which times out):
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromMinutes(30);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, m_uploadUrl);
httpContent.Headers.Add("Keep-Alive", "true");
request.Content = httpContent; // 3-5 Mb file
response = await httpClient.SendAsync(request);
statusCode = response.StatusCode;
}
I also tried PostAsync(), but same result. After about 60 sec the call completes with a status code 400 or 404. This is not a server timeout. IPhone and Android apps use the same service. No problems there.
Any ideas on how to upload files that takes more than 60 seconds to send?
I too faced similar things. The timeout glitch.
Check if you could use another class instead of HttpClient.
WebClient may be.
Check if this helps you:
http://blog.anthonybaker.me/2013/06/how-to-upload-file-from-windows-phone.html
and even this:
http://chriskoenig.net/2011/08/19/upload-files-from-windows-phone/
I got things working for me with those.
I've used several days now to implement a new uploader and get all the details working. I used HttpWebRequest with the async methods and split the file into chuncks. Finally I got it working and it uploads without the timeout. Here is the complete code:
using System;
using Models;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Services
{
public class UploadData
{
public Stream PostStream { get; set; }
public Stream FileStream { get; set; }
public byte[] HeaderBytes {get; set;}
public byte[] FooterBytes {get; set;}
public byte[] Buffer { get; set; }
public Photo Upload { get; set; }
public int BytesWritten { get; set; }
}
public class UploadEventArgs : EventArgs
{
public Photo Upload { get; set; }
public int Progress { get; set; }
}
public class UploadService
{
public delegate void CompletedEventHandler(object sender, UploadEventArgs e);
public event CompletedEventHandler UploadCompleted;
public delegate void ProgressEventHandler(object sender, UploadEventArgs e);
public event ProgressEventHandler ProgressChanged;
private static string contentType = "multipart/form-data; boundary={0}";
private static string headerString = "Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\nContent-Type: Content-Type: application/octet-stream\r\n\r\n";
private HttpWebRequest m_request;
private static string boundarystr;
private UploadData m_uploadData;
private bool m_isStopped;
public async Task StartUpload(Photo upload, Uri uri, Dictionary<string, string> parameters)
{
try
{
m_isStopped = false;
var fileStream = (await upload.File.OpenReadAsync()).AsStreamForRead();
var uploadData = new UploadData();
boundarystr = "---------------------------" + DateTime.Now.Ticks.ToString("x");
string para = GetParamsString(parameters);
string headAndParams = para + String.Format(headerString, HttpUtility.UrlEncode(upload.File.Name));
var headerBytes = System.Text.Encoding.UTF8.GetBytes(headAndParams);
var footerBytes = Encoding.UTF8.GetBytes("\r\n--" + boundarystr + "--\r\n");
uploadData.Upload = upload;
uploadData.FileStream = fileStream;
uploadData.FooterBytes = footerBytes;
uploadData.HeaderBytes = headerBytes;
uploadData.BytesWritten = 0;
m_uploadData = uploadData;
m_request = (HttpWebRequest)WebRequest.Create(uri);
m_request.Method = "POST";
m_request.AllowWriteStreamBuffering = false;
m_request.ContentType = string.Format(contentType, boundarystr);
m_request.ContentLength = fileStream.Length + headerBytes.Length + footerBytes.Length;
var asyncResult = m_request.BeginGetRequestStream((ar) => { GetRequestStreamCallback(ar, uploadData); }, m_request);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Start upload failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
m_uploadData.FileStream.Close();
m_uploadData.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult, UploadData uploadData)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
postStream.Write(uploadData.HeaderBytes, 0, uploadData.HeaderBytes.Length);
var args = new UploadEventArgs();
args.Upload = uploadData.Upload;
args.Progress = 1;
OnProgressChanged(args);
uploadData.PostStream = postStream;
WriteNextChunck(uploadData);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Header write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
m_uploadData.FileStream.Close();
m_uploadData.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void WriteNextChunck(UploadData upload)
{
try
{
if ((upload.FileStream.Length - upload.BytesWritten) >= 16 * 1024)
{
upload.Buffer = new byte[16 * 1024];
}
else
{
// Last part
upload.Buffer = new byte[upload.FileStream.Length - upload.BytesWritten];
}
upload.FileStream.Read(upload.Buffer, 0, (int)upload.Buffer.Length);
upload.PostStream.BeginWrite(upload.Buffer, 0, upload.Buffer.Length, BeginWriteCallback, upload);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Buffer write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
upload.FileStream.Close();
upload.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void BeginWriteCallback(IAsyncResult ar)
{
try
{
var upload = ar.AsyncState as UploadData;
upload.PostStream.EndWrite(ar);
upload.BytesWritten += upload.Buffer.Length;
var args = new UploadEventArgs();
args.Upload = upload.Upload;
args.Progress = (int)(((decimal)upload.BytesWritten / (decimal)upload.FileStream.Length) * 100);
OnProgressChanged(args);
if (m_isStopped)
{
upload.FileStream.Close();
upload.PostStream.Close();
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Upload stopped");
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
return;
}
// write next chunck
if (upload.BytesWritten < upload.FileStream.Length)
{
WriteNextChunck(upload);
}
if (upload.BytesWritten >= upload.FileStream.Length)
{
WriteFooter(upload);
}
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Upload write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
}
}
private void WriteFooter(UploadData upload)
{
try
{
upload.PostStream.Write(upload.FooterBytes, 0, upload.FooterBytes.Length);
upload.PostStream.Close();
var asyncResult = m_request.BeginGetResponse(new AsyncCallback(GetResponseCallback), m_request);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Footer write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
}
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
streamResponse.Close();
streamRead.Close();
response.Close();
m_uploadData.FileStream.Close();
m_uploadData.Upload.UploadInfo.StatusCode = response.StatusCode;
if (response.StatusCode == HttpStatusCode.NoContent)
{
m_uploadData.Upload.UploadInfo.Exception = null;
}
else
{
m_uploadData.Upload.UploadInfo.Exception = new Exception(responseString);
}
var args = new UploadEventArgs();
args.Upload = m_uploadData.Upload;
args.Progress = 100;
OnUploadComplete(args);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = ex;
var args = new UploadEventArgs();
args.Upload = m_uploadData.Upload;
OnUploadComplete(args);
}
}
private string GetParamsString(Dictionary<string, string> parameters)
{
bool needsCLRF = false;
string result = "";
foreach (var param in parameters)
{
// Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
// Skip it on the first parameter, add it to subsequent parameters.
if (needsCLRF)
result += "\r\n";
needsCLRF = true;
string prm = string.Format("--{0}\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Disposition: form-data; name={1}\r\n\r\n{2}",
boundarystr,
param.Key,
param.Value);
result += prm;
}
// Add the end of the request. Start with a newline
string footer = "\r\n--" + boundarystr + "\r\n";
result += footer;
return result;
}
protected virtual void OnUploadComplete(UploadEventArgs e)
{
if (UploadCompleted != null)
UploadCompleted(this, e);
}
protected virtual void OnProgressChanged(UploadEventArgs e)
{
if (ProgressChanged != null)
ProgressChanged(this, e);
}
public void Stop()
{
m_isStopped = true;
}
}
}

Upload file to Secured FTP in ASP.NET

I want to upload files to FTPS and SFTP. My code is currently using FtpWebRequest object to upload to FTP. What changes or class should I use to upload to FTP, FTPS and SFTP servers?
SFTP is not a built-in protocol for .NET, you'll have to use a third-party library, like SharpSSH; however, FTP and FTPS are. There are a number of third-party libraries both commercial and OpenSource (SSH Factory for .NET , Rebex SFTP for .NET/.NET CF, SharpSSH - A Secure Shell (SSH) library for .NET, Compare SFTP (SSH File Transfer Protocol) components for .NET (C#, VB.NET) - SecureBlackbox®) and you'll need to do some research to determine which one will best suit your needs.
Here's a sample console app I wrote that does FTP and FTPS using the .NET Framework's FtpWebRequest:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace FtpSslTest
{
class Program
{
static void Main(string[] args)
{
string server = null;
do
{
Console.Write("Enter the server to connect to: ");
server = Console.ReadLine();
} while (IsServerValid(server) == false);
UriBuilder ftpUrl = new UriBuilder("ftp", server);
bool useSsl = GetYesNo("Use SSL?");
bool allowInvalidCertificate = false;
if (useSsl)
{
allowInvalidCertificate = GetYesNo("Allow invalid SSL certificate?");
}
bool useActiveFtp = GetYesNo("Use Active FTP?");
string path = null;
do
{
Console.Write("Enter the path: ");
path = Console.ReadLine();
} while (IsValidPath(path) == false);
ftpUrl.Path = path;
Console.Write("Enter the user name: ");
string userName = Console.ReadLine();
string password = GetPasswordFromUser();
Console.WriteLine();
Console.WriteLine();
List<string> directoryContents = null;
try
{
directoryContents = DisplayDirectoryContents(ftpUrl.ToString(), userName, password, useSsl, allowInvalidCertificate, useActiveFtp, false);
}
catch (WebException ex)
{
Console.WriteLine("The request failed with status {0}. {1}", ex.Status, ex.Message);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString());
}
if (directoryContents != null && directoryContents.Count == 1)
{
bool saveFile = GetYesNo(string.Format("Download the file {0} from {1}? ", directoryContents[0], server));
if (saveFile)
{
string savePath = null;
do
{
Console.Write("Enter a local path to save the file: ");
savePath = Console.ReadLine();
} while (!IsValidPath(savePath));
try
{
DownloadFileFromServer(ftpUrl.ToString(), userName, password, useSsl, allowInvalidCertificate, useActiveFtp, savePath);
}
catch (WebException ex)
{
Console.WriteLine("The request failed with status {0}. {1}", ex.Status, ex.Message);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString());
}
}
}
}
private static bool GetYesNo(string message)
{
Console.Write("{0} (Y/N) ", message);
string input = null;
do
{
input = new string(Console.ReadKey(true).KeyChar, 1);
} while (!input.Equals("Y", StringComparison.CurrentCultureIgnoreCase) && !input.Equals("N", StringComparison.CurrentCultureIgnoreCase));
Console.WriteLine(input);
return input.Equals("Y", StringComparison.CurrentCultureIgnoreCase);
}
private static bool IsValidPath(string path)
{
bool validPath = false;
validPath = path != null && path.IndexOfAny(Path.GetInvalidPathChars()) < 0;
if (validPath == false)
{
Console.WriteLine("You must enter a valid path.");
}
return validPath;
}
private static bool IsServerValid(string server)
{
bool serverValid = false;
if (!string.IsNullOrEmpty(server))
{
try
{
IPAddress[] addresses = Dns.GetHostAddresses(server);
serverValid = (addresses != null && addresses.Length > 0);
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
}
}
else
{
Console.WriteLine("You must provide a valid host name or IP address.");
}
return serverValid;
}
private static string GetPasswordFromUser()
{
Console.Write("Enter the password: ");
StringBuilder password = new StringBuilder();
char readChar = '\x00';
while (readChar != '\r')
{
readChar = Console.ReadKey(true).KeyChar;
if (readChar == '\b')
{
if (password.Length > 0)
{
password.Length--;
Console.Write("\b \b");
}
}
else if (readChar != '\r')
{
Console.Write('*');
password.Append(readChar);
}
}
return password.ToString();
}
public static bool ServicePointManager_ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
bool allowCertificate = true;
if (sslPolicyErrors != SslPolicyErrors.None)
{
Console.WriteLine("Accepting the certificate with errors:");
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
{
Console.WriteLine("\tThe certificate subject {0} does not match.", certificate.Subject);
}
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
{
Console.WriteLine("\tThe certificate chain has the following errors:");
foreach (X509ChainStatus chainStatus in chain.ChainStatus)
{
Console.WriteLine("\t\t{0}", chainStatus.StatusInformation);
if (chainStatus.Status == X509ChainStatusFlags.Revoked)
{
allowCertificate = false;
}
}
}
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
{
Console.WriteLine("No certificate available.");
allowCertificate = false;
}
Console.WriteLine();
}
return allowCertificate;
}
private static FtpWebRequest CreateFtpWebRequest(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
request.Credentials = new NetworkCredential(userName, password);
if (useSsl)
{
request.EnableSsl = true;
if (allowInvalidCertificate)
{
ServicePointManager.ServerCertificateValidationCallback = ServicePointManager_ServerCertificateValidationCallback;
}
else
{
ServicePointManager.ServerCertificateValidationCallback = null;
}
}
request.UsePassive = !useActiveFtp;
return request;
}
private static List<string> DisplayDirectoryContents(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp, bool detailed)
{
List<string> directoryContents = new List<string>();
FtpWebRequest request = CreateFtpWebRequest(ftpUrl, userName, password, useSsl, allowInvalidCertificate, useActiveFtp);
if (detailed)
{
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
}
else
{
request.Method = WebRequestMethods.Ftp.ListDirectory;
}
Stopwatch stopwatch = new Stopwatch();
long bytesReceived = 0;
stopwatch.Start();
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine(response.BannerMessage);
Console.WriteLine(response.WelcomeMessage);
Console.WriteLine(response.StatusDescription);
using (Stream responseStream = response.GetResponseStream())
using (StreamReader responseStreamReader = new StreamReader(responseStream))
{
while (!responseStreamReader.EndOfStream)
{
string directoryEntry = responseStreamReader.ReadLine();
Console.WriteLine(directoryEntry);
directoryContents.Add(directoryEntry);
}
}
Console.WriteLine(response.ExitMessage);
}
stopwatch.Stop();
Console.WriteLine();
Console.WriteLine("{0} bytes received in {1} seconds.", bytesReceived, stopwatch.ElapsedMilliseconds / 1000.0);
return directoryContents;
}
private static List<string> ListDirectoryContents(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp, bool detailed)
{
List<string> directoryContents = new List<string>();
FtpWebRequest request = CreateFtpWebRequest(ftpUrl, userName, password, useSsl, allowInvalidCertificate, useActiveFtp);
if (detailed)
{
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
}
else
{
request.Method = WebRequestMethods.Ftp.ListDirectory;
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
using (StreamReader responseStreamReader = new StreamReader(responseStream))
{
while (!responseStreamReader.EndOfStream)
{
string directoryEntry = responseStreamReader.ReadLine();
directoryContents.Add(directoryEntry);
}
}
}
return directoryContents;
}
private static void DownloadFileFromServer(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp, string savePath)
{
FtpWebRequest request = CreateFtpWebRequest(ftpUrl, userName, password, useSsl, allowInvalidCertificate, useActiveFtp);
request.Method = WebRequestMethods.Ftp.DownloadFile;
Stopwatch stopwatch = new Stopwatch();
long bytesReceived = 0;
stopwatch.Start();
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine(response.BannerMessage);
Console.WriteLine(response.WelcomeMessage);
Console.WriteLine(response.StatusDescription);
using (Stream responseStream = response.GetResponseStream())
using (FileStream saveFileStream = File.OpenWrite(savePath))
{
// Note that this method call requires .NET 4.0 or higher. If using an earlier version it will need to be replaced.
responseStream.CopyTo(saveFileStream);
}
bytesReceived = response.ContentLength;
Console.WriteLine(response.ExitMessage);
}
stopwatch.Stop();
Console.WriteLine();
Console.WriteLine("{0} bytes received in {1} seconds.", bytesReceived, stopwatch.ElapsedMilliseconds / 1000.0);
}
private static void UploadFileToServer(string ftpUrl, string userName, string password, bool useSsl, bool allowInvalidCertificate, bool useActiveFtp, string filePath)
{
FtpWebRequest request = CreateFtpWebRequest(ftpUrl, userName, password, useSsl, allowInvalidCertificate, useActiveFtp);
request.Method = WebRequestMethods.Ftp.UploadFile;
Stopwatch stopwatch = new Stopwatch();
long bytesReceived = 0;
stopwatch.Start();
long bytesSent = 0;
using (Stream requestStream = request.GetRequestStream())
using (FileStream uploadFileStream = File.OpenRead(filePath))
{
// Note that this method call requires .NET 4.0 or higher. If using an earlier version it will need to be replaced.
uploadFileStream.CopyTo(requestStream);
bytesSent = uploadFileStream.Position;
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine(response.BannerMessage);
Console.WriteLine(response.WelcomeMessage);
Console.WriteLine(response.StatusDescription);
bytesReceived = response.ContentLength;
Console.WriteLine(response.ExitMessage);
}
stopwatch.Stop();
Console.WriteLine();
Console.WriteLine("{0} bytes sent in {1} seconds.", bytesSent, stopwatch.ElapsedMilliseconds / 1000.0);
}
}
}
You can also get detailed tracing for debugging purposes by using the following config file with the sample application:
<?xml version="1.0"?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.Net">
<listeners>
<add name="TraceFile"/>
</listeners>
</source>
<source name="System.Net.Sockets" maxdatasize="1024">
<listeners>
<add name="TraceFile"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="TraceFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="System.Net.trace.log" traceOutputOptions="DateTime"/>
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose"/>
<!--<add name="System.Net.Sockets" value="Verbose"/>-->
</switches>
<trace autoflush="true" />
</system.diagnostics>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
I use this library to download and upload files over sftp. Should be samples of how to use the library if you download the source. http://sshnet.codeplex.com

making asynchronous calls from generic handler (.ashx)

I have a form in my website which posts json to the async handler which validates the data and return back the resonse OK or error and i will make the redirect on the client based on the response give by my handler.
But when the response is ok, i want to perform some tasks asynchronously. But the asynchronous calls are not working inside the .ashx code. it is always synchronous.
Could you please give me an advice on this.?
code:
public class ValidateHandler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
NameValueCollection nvcForm = context.Request.Form;
Dictionary<string, string> errorFieldsDict = new Dictionary<string, string>();
foreach (string nameValueKey in nvcForm.AllKeys)
{
regExpToTest = string.Empty;
switch (nameValueKey)
{
case "firstName":
//validate
break;
case "lastName":
//validate
break;
case "email":
//validate
break;
case "phoneNumber":
//validate
break;
case "phoneCountryCode":
//validate
break;
case "country":
//validate
break;
case "addressLine1":
//validate
break;
case "addressLine2":
//validate
break;
case "city":
//validate
break;
case "postalCode":
//validate
break;
default:
//validate
break;
}
if (!string.IsNullOrEmpty(regExpToTest) && !Regex.IsMatch(nvcForm[nameValueKey], regExpToTest) && !string.IsNullOrEmpty(nvcForm[nameValueKey]))
{
errorFieldsDict.Add(nameValueKey, "Please Enter Correct Value");
isSuccess = false;
}
}
//Do your business logic here and finally
if (isSuccess)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
try
{
Dictionary<string, object> formValues = GetDictionaryForJson(nvcForm);
string previoiusUrl = GetRequestedURL(context);
string partner = string.Empty;
if (System.Web.HttpContext.Current.Session["yourpartner"] != null)
partner = System.Web.HttpContext.Current.Session["yourpartner"].ToString();
else if (System.Web.HttpContext.Current.Request.QueryString["utm_source"] != null)
partner = System.Web.HttpContext.Current.Request.QueryString["utm_source"];
else
partner = "company";
formValues.Add("partnerCode", partner);
string brochureType = string.Empty;
if (!string.IsNullOrEmpty(nvcForm["addressLine1"]) || !string.IsNullOrEmpty(nvcForm["addressLine2"]))
brochureType = "FBRO";
else
brochureType = "EBRO";
//Create a row in database
Item programItem = Sitecore.Context.Database.Items.GetItem(programRootpath + nvcForm["selectYourProgram"]); ;
AsyncMailSender caller = new AsyncMailSender(SendEmail);
IAsyncResult result = caller.BeginInvoke(programItem, nvcForm["email"], null, null);
}
catch (Exception ex)
{
isSuccess = false;
Log.Error("Enquiry handler failure: " + ex.Message, ex);
response.response = "error";
response.message = ex.Message;
context.Response.ContentType = "application/json";
context.Response.Write(JsonConvert.SerializeObject(response));
}
if (isSuccess)
{
response.response = "ok";
context.Response.ContentType = "application/json";
context.Response.Write(JsonConvert.SerializeObject(response));
}
}
else
{
response.response = "errorFields";
response.errorFields = errorFieldsDict;
context.Response.ContentType = "application/json";
string responseJson = JsonConvert.SerializeObject(response);
context.Response.Write(JsonConvert.SerializeObject(response, Newtonsoft.Json.Formatting.None));
}
}
private string GetRequestedURL(HttpContext context)
{
string previousURL = string.Empty;
try
{
previousURL = context.Request.ServerVariables["HTTP_REFERER"];
}
catch
{
previousURL = context.Request.Url.AbsolutePath;
}
return previousURL;
}
public bool IsReusable
{
get
{
return false;
}
}
private void SendEmail(Item programItem, string toEmail)
{
if (programItem != null)
{
SendEmail()
}
}
private Dictionary<string, object> GetDictionaryForJson(NameValueCollection formValues)
{
Dictionary<string, object> formDictionary = new Dictionary<string, object>();
foreach (string key in formValues.AllKeys)
{
formDictionary.Add(key, formValues[key]);
}
return formDictionary;
}
}
public delegate void AsyncMailSender(Item program, string toAddress);
PS: I did hide some code which is just our business.But Would be great if you can comment on that.
thanks guys
In ASP.NET 4.5 is the HttpTaskAsyncHandler. You can use it like this:
public class MyHandler : HttpTaskAsyncHandler {
public override async Task ProcessRequestAsync(HttpContext context) {
await WhateverAsync(context);
}
}
You need to implmement IHttpAsyncHandler rather than IHttpHandler and register it as such in the web.config file. Browsers will also observe connection limits, so make sure IIS is configured properly to handle multiple connections, keep-alive, etc.
Here's a detailed walk through: http://msdn.microsoft.com/en-us/library/ms227433.aspx

Resources