I have created a web service to send emails from a Winform application.
The data is sent as a BYTE[] but only works with the array being under 3mb. Within the Web config and App Config I have increased maxAllowedContentLength to their limit. This is the line that fails: HttpWebResponse oWebResp = myReq.GetResponse() as HttpWebResponse;
Here is the SMTP Web service:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Mail;
using System.Configuration;
using System.IO;
namespace SMTPWebService.Models
{
public class Mailer : IMailer
{
public void SendMail(EmailContentDto emailContentDto)
{
MailMessage mail = new MailMessage(emailContentDto.Sender,
emailContentDto.Recipient);
SmtpClient client = new SmtpClient();
client.Port = Convert.ToInt32(ConfigurationManager.AppSettings["SMTPServerPort"]);
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Timeout = 80000;
client.Host = ConfigurationManager.AppSettings["SMTPServerAddress"];
mail.Subject = emailContentDto.Subject;
mail.Body = emailContentDto.HtmlBody;
mail.IsBodyHtml = true;
if (emailContentDto.FileBinary != null)
mail.Attachments.Add(
new Attachment(
new MemoryStream(emailContentDto.FileBinary),
emailContentDto.FileName,
emailContentDto.FileFormat));
try
{
client.Send(mail);
}
catch (Exception)
{
throw;
}
}
}
}
Here is the Winform wending the data:
public void SendEmail(String sender, String recipient, String subject, String htmlBody, String fileLocation, String AttachemntNewName)
{
var stFileName = "";
var stFileExt = "";
byte[] buffer = null;
String key_ = "";
if (!String.IsNullOrEmpty(fileLocation))
{
FileStream st = new FileStream(fileLocation, FileMode.Open);
stFileName = st.Name;
stFileExt = Path.GetExtension(stFileName.ToLower());
buffer = new byte[st.Length];
st.Read(buffer, 0, (int)st.Length);
st.Close();
key_ = MimeTypesAutoGet(stFileExt);
};
EmailDto emailDto = new EmailDto()
{
Sender = sender,
Recipient = recipient,
Subject = subject,
HtmlBody = htmlBody,
FileBinary = buffer,
FileFormat = key_,
FileName = stFileName // AttachemntNewName
};
String apiUrl = "http://ADDRESS_TO_SERVER";
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(apiUrl);
byte[] reqBytes = System.Text.UTF8Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(emailDto));
myReq.SendChunked = true;
myReq.AllowWriteStreamBuffering = false;
myReq.KeepAlive = true;
myReq.Timeout = 30000;
myReq.Credentials = CredentialCache.DefaultCredentials;
myReq.ContentLength = reqBytes.Length;
myReq.Method = "POST";
// myReq.ContentType = "multipart/form-data";
myReq.ContentType = "application/json";
Stream oReqStream = myReq.GetRequestStream();
oReqStream.Write(reqBytes, 0, reqBytes.Length);
string StringByte = BitConverter.ToString(reqBytes);
try
{
HttpWebResponse oWebResp = myReq.GetResponse() as HttpWebResponse;
}
catch (WebException Ex)
{
MessageBox.Show(Ex.ToString());
}
}
This is the DTO:
public class EmailContentDto
{
public String Recipient { get; set; }
public String Sender { get; set; }
public String Subject { get; set; }
public String HtmlBody { get; set; }
public Byte[] FileBinary { get; set; }
public String FileFormat { get; set; }
public String FileName { get; set; }
}
Here is the Controller:
public class HomeController : Controller
{
private IMailer _mailer = new Mailer();
public ActionResult Index()
{
return View();
}
public ActionResult SendMail([FromBody]EmailContentDto emailContentDto)
{
_mailer.SendMail(emailContentDto);
return null;
}
}
Related
I am struggling with web requests to some websites like (mrporter.com or size.co.uk). Outside USA (so no USA IPs), I can make requests just fine. However once I am behind USA IP, requests either time out or end up with "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond" exception. I have tried all kind of headers combinations, still no luck. I need to note, that those websites are opening in browsers just fine.
This is my implementation that works with non-USA ips.
var _request = (HttpWebRequest)WebRequest.Create("https://www.mrporter.com");
_request.CookieContainer = new CookieContainer();
_request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36";
_request.KeepAlive = true;
_request.AutomaticDecompression = (DecompressionMethods.GZip | DecompressionMethods.Deflate);
_request.Headers.Add("Accept-Encoding", "gzip, deflate");
_request.Headers.Add("Accept-Language", "en-GB, en-US; q=0.9, en; q=0.8");
_request.Headers.Add("Upgrade-Insecure-Requests", "1");
var _srr = "";
using (var response = _request.GetResponse())
{
var httpWebResponse = response.GetResponseStream();
using (var sr = new StreamReader(httpWebResponse))
{
_srr = sr.ReadToEnd();
}
}
Anybody can help? I seriously wasted hours with it with no result ...
This is the procedure used test the Server you mentioned (https://www.mrporter.com/)
The main method can be called this way:
(The StreamObject class returns a number of informations about the Server, including the Html of the landing page. (Also its Cookies, IP Address etc.)
public async void SomeMethodAsync()
{
StreamObject _streamObj = new StreamObject()
{
ResourceURI = new Uri(#"https://www.mrporter.com/"),
ProcessStream = true
};
_streamObj = await HTTP_GetStreamAsync(_streamObj);
}
I had to cut out the Proxy setup (it's inititialized if needed in the same method that initializes the WebRequest Headers). Anyway, it should looks like this:
if ([UseProxy])
if ([ProxyHost] != null) {
WebRequest.Proxy = new WebProxy([ProxyHost], [ProxyPort]);
if ([Credentials] != null)
WebRequest.Proxy.Credentials = new NetworkCredential([Credentials].UserID, [Credentials].Password);
} else {
WebRequest.Proxy = WebRequest.GetSystemWebProxy();
}
}
If you plan on using a Proxy, you should also insert this parameter in
your app.config file:
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
When the main method (HTTP_GetStreamAsync()) returns, StreamObject.Payload will contain the decoded Html Page of the Site you connected to.
There are a number of sub-utilities and it might look complicated, but everything should work fine. You just need to insert all of the code inside a class and modify the calling method (SomeMethodAsync()) accordingly.
(I'll edit this when I have a moment).
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
private const uint COR_E_INVALIDOPERATION = 0x80131509;
public class StreamObject
{
public Stream ContentStream { get; set; }
public bool ProcessStream { get; set; }
public Uri ResourceURI { get; set; }
public Uri ResponseURI { get; set; }
public string Referer { get; set; }
public string Payload { get; set; }
public string ServerType { get; set; }
public string ServerName { get; set; }
public IPAddress[] ServerIP { get; set; }
public string ContentName { get; set; }
public string ContentType { get; set; }
public string ContentCharSet { get; set; }
public string ContentLanguage { get; set; }
public long ContentLenght { get; set; }
public HttpStatusCode StatusCode { get; set; }
public string StatusDescription { get; set; }
public WebExceptionStatus WebException { get; set; }
public string WebExceptionDescription { get; set; }
public CookieContainer Cookies { get; set; }
}
public async Task<StreamObject> HTTP_GetStreamAsync(StreamObject RequestObject)
{
if (string.IsNullOrEmpty(RequestObject.ResourceURI.ToString().Trim()))
return null;
MemoryStream _memstream = new MemoryStream();
HttpWebRequest httpRequest;
CookieContainer _cookiejar = new CookieContainer();
HttpStatusCode _StatusCode = HttpStatusCode.OK;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback += TlsValidationCallback;
if (RequestObject.Cookies != null && RequestObject.Cookies.Count > 0)
_cookiejar = RequestObject.Cookies;
httpRequest = WebRequest.CreateHttp(RequestObject.ResourceURI);
try
{
HTTP_RequestHeadersInit(ref httpRequest, _cookiejar, null);
httpRequest.Referer = RequestObject.Referer;
using (HttpWebResponse httpResponse = (HttpWebResponse)await httpRequest.GetResponseAsync())
{
Stream ResponseStream = httpResponse.GetResponseStream();
if (_StatusCode == HttpStatusCode.OK)
{
await ResponseStream.CopyToAsync(_memstream);
RequestObject.ContentStream = _memstream;
RequestObject.ResponseURI = httpResponse.ResponseUri;
RequestObject.ContentLenght = _memstream.Length;
RequestObject.ContentCharSet = httpResponse.CharacterSet ?? string.Empty;
RequestObject.ContentLanguage = httpResponse.Headers["Content-Language"] ?? string.Empty;
RequestObject.ContentType = httpResponse.ContentType.ToLower();
if (RequestObject.ContentType.IndexOf(#"/") > -1)
{
do
{
RequestObject.ContentType = RequestObject.ContentType.Substring(RequestObject.ContentType.IndexOf(#"/") + 1);
if (RequestObject.ContentType.IndexOf(#"/") < 0)
break;
} while (true);
if (RequestObject.ContentType.IndexOf(";") > -1)
RequestObject.ContentType = RequestObject.ContentType.Substring(0, RequestObject.ContentType.IndexOf(#";"));
RequestObject.ContentType = "." + RequestObject.ContentType;
}
RequestObject.ContentName = httpResponse.Headers["Content-Disposition"] ?? string.Empty;
if (RequestObject.ContentName.Length == 0)
RequestObject.ContentName = RequestObject.ResourceURI.Segments.Last();
RequestObject.ServerType = httpResponse.Server;
RequestObject.ServerName = RequestObject.ResponseURI.DnsSafeHost;
RequestObject.ServerIP = await Dns.GetHostAddressesAsync(RequestObject.ServerName);
RequestObject.StatusCode = _StatusCode;
RequestObject.StatusDescription = httpResponse.StatusDescription;
if (RequestObject.ProcessStream)
RequestObject.Payload = ProcessResponse(RequestObject.ContentStream,
Encoding.GetEncoding(RequestObject.ContentCharSet),
httpResponse.ContentEncoding);
}
}
}
catch (WebException exW)
{
if (exW.Response != null)
{
RequestObject.StatusCode = ((HttpWebResponse)exW.Response).StatusCode;
RequestObject.StatusDescription = ((HttpWebResponse)exW.Response).StatusDescription;
}
RequestObject.WebException = exW.Status;
RequestObject.WebExceptionDescription = exW.Message;
}
catch (System.Exception exS)
{
if ((uint)exS.HResult == COR_E_INVALIDOPERATION)
{
RequestObject.WebException = await PingHostAddressAsync("8.8.8.8", 500) > 0
? WebExceptionStatus.NameResolutionFailure
: WebExceptionStatus.ConnectFailure;
RequestObject.WebExceptionDescription = RequestObject.WebException.ToString();
}
else
{
RequestObject.WebException = WebExceptionStatus.RequestCanceled;
RequestObject.WebExceptionDescription = RequestObject.WebException.ToString();
}
}
finally
{
ServicePointManager.ServerCertificateValidationCallback -= TlsValidationCallback;
}
RequestObject.Cookies = httpRequest.CookieContainer;
RequestObject.StatusCode = _StatusCode;
return RequestObject;
} //HTTP_GetStream
private bool TlsValidationCallback(object sender, X509Certificate CACert, X509Chain CAChain, SslPolicyErrors sslPolicyErrors)
{
X509Certificate2 _Certificate = new X509Certificate2(CACert);
//ADD A CERIFICATE HERE IF NEEDED
//X509Certificate2 _CACert = new X509Certificate2(#"[localstorage]/ca.cert");
//CAChain.ChainPolicy.ExtraStore.Add(_CACert);
X509Certificate2 cert = (X509Certificate2)CACert;
CAChain.Build(_Certificate);
foreach (X509ChainStatus CACStatus in CAChain.ChainStatus)
{
if ((CACStatus.Status != X509ChainStatusFlags.NoError) &
(CACStatus.Status != X509ChainStatusFlags.UntrustedRoot))
return false;
}
return true;
}
private void HTTP_RequestHeadersInit(ref HttpWebRequest _httpreq, CookieContainer _cookiecontainer, StreamObject sObject)
{
_httpreq.Date = DateTime.Now;
_httpreq.Timeout = 30000;
_httpreq.ReadWriteTimeout = 30000;
_httpreq.CookieContainer = _cookiecontainer;
_httpreq.KeepAlive = true;
_httpreq.ConnectionGroupName = Guid.NewGuid().ToString();
_httpreq.AllowAutoRedirect = true;
_httpreq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
_httpreq.ServicePoint.MaxIdleTime = 30000;
_httpreq.ServicePoint.Expect100Continue = false;
_httpreq.Referer = sObject.Referer ?? string.Empty;
_httpreq.UserAgent = "Mozilla/5.0 (Windows NT 10; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0";
_httpreq.Accept = "ext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
_httpreq.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US;q=0.8,en-GB;q=0.5,en;q=0.3");
_httpreq.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate;q=0.8");
_httpreq.Headers.Add(HttpRequestHeader.CacheControl, "no-cache");
//I had to cut out the WebRequest Proxy setup here
}
private string ProcessResponse(Stream stream, Encoding encoding, string ContentEncoding)
{
string html = string.Empty;
stream.Position = 0;
try
{
using (MemoryStream _memStream = new MemoryStream())
{
if (ContentEncoding.Contains("gzip"))
{
using (GZipStream _gzipStream = new GZipStream(stream, System.IO.Compression.CompressionMode.Decompress))
{
_gzipStream.CopyTo(_memStream);
};
}
else if (ContentEncoding.Contains("deflate"))
{
using (DeflateStream _deflStream = new DeflateStream(stream, System.IO.Compression.CompressionMode.Decompress))
{
_deflStream.CopyTo(_memStream);
};
}
else
{
stream.CopyTo(_memStream);
}
_memStream.Position = 0;
using (StreamReader _reader = new StreamReader(_memStream, encoding))
{
html = _reader.ReadToEnd().Trim();
html = DecodeMetaCharSetEncoding(_memStream, html, encoding);
};
};
}
catch (Exception)
{
return string.Empty;
}
return html;
}
private string DecodeMetaCharSetEncoding(Stream memStream, string _html, Encoding _encode)
{
Match _match = new Regex("<meta\\s+.*?charset\\s*=\\s*\"?(?<charset>[A-Za-z0-9_-]+)\"?",
RegexOptions.Singleline |
RegexOptions.IgnoreCase).Match(_html);
if (_match.Success)
{
string charset = _match.Groups["charset"].Value.ToLower() ?? "utf-8";
if ((charset == "unicode") | (charset == "utf-7") | (charset == "utf-16"))
charset = "utf-8";
try
{
Encoding metaEncoding = Encoding.GetEncoding(charset);
if (_encode.WebName != metaEncoding.WebName)
{
memStream.Position = 0L;
using (StreamReader recodeReader = new StreamReader(memStream, metaEncoding))
{ _html = recodeReader.ReadToEnd().Trim(); }
}
}
catch (ArgumentException)
{
_html = string.Empty;
}
catch (Exception)
{
_html = string.Empty;
}
}
return _html;
}
public async Task<IPStatus> PingHostAddressAsync(string HostAddress, int timeout)
{
if (string.IsNullOrEmpty(HostAddress.Trim()))
return IPStatus.BadDestination;
byte[] buffer = new byte[32];
PingReply iReplay = null;
IPStatus ipStatus;
using (Ping iPing = new Ping())
{
try
{
IPAddress _IPAddress = IPAddress.Parse(HostAddress);
iReplay = await iPing.SendPingAsync(_IPAddress, timeout, buffer, new PingOptions(64, false));
return iReplay.Status;
}
catch (FormatException)
{
return IPStatus.BadDestination;
}
catch (NotSupportedException nsex)
{
ipStatus = (IPStatus)nsex.HResult;
ipStatus = IPStatus.DestinationProtocolUnreachable;
}
catch (PingException pex)
{
ipStatus = (IPStatus)pex.HResult;
}
catch (SocketException soex)
{
ipStatus = (IPStatus)soex.HResult;
}
catch (Exception ex)
{
//Log ex
ipStatus = (IPStatus)ex.HResult;
}
return (iReplay != null) ? iReplay.Status : ipStatus;
}
}
I am trying to send a request from server side to my API, here is my code from Server
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:59606/api/values/UserCheck");
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"username\":\"User\"," +
"\"password\":\"Mypassword\"," +
"\"logonfrom\":\"DOMAIN\\DomainName\"}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.WriteLine(result);
Console.ReadLine();
}
May API code are below:
[HttpPost]
[ActionName("UserCheck")]
public bool UserCheck([FromBody]User value)
{
ContextType CT = ContextType.Domain;
if (value.logonfrom.Split('\\')[0] == "DOMAIN")
{
CT = ContextType.Domain;
}else if(value.logonfrom.Split('\\')[0] == "MACHINE")
{
CT = ContextType.Machine;
}else
{
return false;
}
return CheckCredentials(value.username, value.password, CT,value.logonfrom.Split('\\')[1]);
}
when my request reach the Action of UserCheck, the value of
([FromBody]User value)
is null
my Class for the User is below
public class User
{
public string username { get; set; }
public string password { get; set; }
public string system { get; set; }
public string IP { get; set; }
public string logonfrom { get; set; }
}
BUT once i remove the logonfrom variable from json there is no error, i mean the parameter (value) successfully captures the content i sent.
Thanks
use the following peace of code.
string json = JsonConvert.SerializeObject(new { username = "afsa", password = "fsaf", system = "fsaf", ip = "fsf", logonfrom ="fsfsd"});
I can able to send the push notification on my android application using the console. but using server side code, I get the successfully message send notification but actually notification does not able to receive at device end. Please, tell me what is wrong with my code:
public static string SendPushNotification() {
try {
string applicationID = "AAAA4GkXVHA:....-qRw";
string senderId = "963..28";
string deviceId = "APA91bHLV...IC4s";
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new {
to = deviceId,
notification = new {
body = "hema",
title = "hem",
//priority = "normal",
//sound = "Enabled"
},
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", applicationID));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
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;
return str;
}
}
}
}
}
catch (Exception ex) {
string str = ex.Message;
return str;
}
}
where I got the response in return is as follows :
{"multicast_id":8288766196764532656,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1481612825945796%6ad79a87f9fd7ecd"}]}
Sending the json in right format:
{
"to" : "APA91bHLV__P6Qer8U70j82blZt0VdDgc2zo_4DtAD4_MtE-......",
"notification" : {
"body" : "Success!",
"title" : "Hema",
"icon" : "myicon"
}
}
To check it properly, you can also use the postman:
Even I experienced the same problem. Finish all the steps in connecting the FCM from Client side. If you implement GetMessage() method from client side, only then your device is able to get the Notification from Server side
I wrote a small tutorial for this: https://www.kendar.org/?p=/tutorials/notifications with an Android app and a .Net core Server. To summarize here is the "main" server code
public NotificationResult Send(NotificationModel messageData)
{
var result = "-1";
var webAddr = "https://fcm.googleapis.com/fcm/send";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add(HttpRequestHeader.Authorization, "key=PROJECTSETTINGS->Cloud Messagings->Server Key");
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string strNJson = JsonConvert.SerializeObject(new NotificationMessage
{
To = "/topics/ServiceNow",
Data = new NotificationData
{
Description = messageData.Description,
IncidentNo = messageData.IncidentNo,
ShortDesc = messageData.ShortDesc
},
Notification = new Notification
{
Title = "ServiceNow: Incident No." + messageData.IncidentNo,
Text = "Notification"
}
});
streamWriter.Write(strNJson);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
return new NotificationResult
{
Result = result
};
}
And the classes that wrap the message to FCM (with the Json annotations to correct the mismatch between .Net and Json naming standards)
public class NotificationData
{
public string ShortDesc { get; set; }
public long IncidentNo { get; set; }
public string Description { get; set; }
}
public class Notification
{
public Notification()
{
Sound = "default";
}
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
[JsonProperty("sound")]
public string Sound { get; set; }
}
public class NotificationMessage
{
[JsonProperty("to")]
public string To { get; set; }
[JsonProperty("data")]
public NotificationData Data { get; set; }
[JsonProperty("notification")]
public Notification Notification { get; set; }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.IO;
using Newtonsoft.Json;
using System.Net.Http;
public partial class _Default : System.Web.UI.Page
{
protected string googleplus_client_id = "clientid";
protected string googleplus_client_sceret = "id";
protected string googleplus_redirect_url="http://localhost"; // Replace this with your Redirect URL; Your Redirect URL from your developer.google application should match this URL.
protected string Parameters;
protected void Page_Load(object sender, EventArgs e)
{
if (Session.Contents.Count > 0)
{
if (Session["loginWith"] != null)
{
if (Session["loginWith"].ToString() == "google")
{
try
{
var url = Request.Url.Query;
if (url != "")
{
string queryString = url.ToString();
char[] delimiterChars = { '=' };
string[] words = queryString.Split(delimiterChars);
string code = words[1];
if (code != null)
{
//get the access token
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
webRequest.Method = "POST";
Parameters = "code=" + code + "&client_id=" + googleplus_client_id + "&client_secret=" + googleplus_client_sceret + "&redirect_uri=" + googleplus_redirect_url + "&grant_type=authorization_code";
byte[] byteArray = Encoding.UTF8.GetBytes(Parameters);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = byteArray.Length;
Stream postStream = webRequest.GetRequestStream();
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
WebResponse response = webRequest.GetResponse();
postStream = response.GetResponseStream();
StreamReader reader = new StreamReader(postStream);
string responseFromServer = reader.ReadToEnd();
GooglePlusAccessToken serStatus = JsonConvert.DeserializeObject<GooglePlusAccessToken>(responseFromServer);
if (serStatus != null)
{
string accessToken = string.Empty;
accessToken = serStatus.access_token;
if (!string.IsNullOrEmpty(accessToken))
{
// getgoogleplususerdataSer(accessToken);
}
else
{ }
}
else
{ }
}
else
{ }
}
}
catch (Exception ex)
{
//throw new Exception(ex.Message, ex);
Response.Redirect("index.aspx");
}
}
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
var Googleurl = "https://accounts.google.com/o/oauth2/auth?response_type=code&redirect_uri=" + googleplus_redirect_url + "&scope=https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile&client_id=" + googleplus_client_id;
Session["loginWith"] = "google";
Response.Redirect(Googleurl);
}
public class GooglePlusAccessToken
{
public string access_token { get; set; }
public string token_type { get; set; }
public int expires_in { get; set; }
public string id_token { get; set; }
public string refresh_token { get; set; }
}
private async void getgoogleplususerdataSer(string access_token)
{
try
{
HttpClient client = new HttpClient();
var urlProfile = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + access_token;
client.CancelPendingRequests();
HttpResponseMessage output = await client.GetAsync(urlProfile);
if (output.IsSuccessStatusCode)
{
string outputData = await output.Content.ReadAsStringAsync();
GoogleUserOutputData serStatus = JsonConvert.DeserializeObject<GoogleUserOutputData>(outputData);
if (serStatus != null)
{
// You will get the user information here.
}
}
}
catch (Exception ex)
{
//catching the exception
}
}
}
public class GoogleUserOutputData
{
public string id { get; set; }
public string name { get; set; }
public string given_name { get; set; }
public string email { get; set; }
public string picture { get; set; }
}
I don't know from where i can store the user information in my table,
actually I don't know about google authentication and i find ths=is code on stackoverflow
I just want to store all the information in a table and if a user is logged in for the first time the page should be redirected to new user page and if the user is old user the page should redirect to welcome page
To start with, I definitely agree that Google's documentation is a murky business.
There are a couple of different ways in which you can validate the integrity of the ID token on the server side (btw this is the page you're looking for):
"Manually" - constantly download Google's public keys, verify signature and then each and every field, including the iss one; the main advantage (albeit a small one in my opinion) I see here is that you can minimize the number of requests sent to Google).
"Automatically" - do a GET on Google's endpoint to verify this token
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
Using a Google API Client Library - like the official one.
Here's how this could look:
private const string GoogleApiTokenInfoUrl = "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}";
public ProviderUserDetails GetUserDetails(string providerToken)
{
var httpClient = new MonitoredHttpClient();
var requestUri = new Uri(string.Format(GoogleApiTokenInfoUrl, providerToken));
HttpResponseMessage httpResponseMessage;
try
{
httpResponseMessage = httpClient.GetAsync(requestUri).Result;
}
catch (Exception ex)
{
return null;
}
if (httpResponseMessage.StatusCode != HttpStatusCode.OK)
{
return null;
}
var response = httpResponseMessage.Content.ReadAsStringAsync().Result;
var googleApiTokenInfo = JsonConvert.DeserializeObject<GoogleApiTokenInfo>(response);
if (!SupportedClientsIds.Contains(googleApiTokenInfo.aud))
{
Log.WarnFormat("Google API Token Info aud field ({0}) not containing the required client id", googleApiTokenInfo.aud);
return null;
}
return new ProviderUserDetails
{
Email = googleApiTokenInfo.email,
FirstName = googleApiTokenInfo.given_name,
LastName = googleApiTokenInfo.family_name,
Locale = googleApiTokenInfo.locale,
Name = googleApiTokenInfo.name,
ProviderUserId = googleApiTokenInfo.sub
};
}
I am having a problem with Google Cloud Printing, it always throw an error when I submit a print job using C#:
The remote server returned an error: (426) Requires HTTPS..
I even try it on http://www.google.com/cloudprint/simulate.html but the same problem.
Any way to workaround this or am I missing something?
This is an example of the HTTP POST message which finally got the Submit operation working.
POST http://www.google.com/cloudprint/submit?printerid=<printerid>&output=json HTTP/1.1
Host: www.google.com
Content-Length: 44544
X-CloudPrint-Proxy: Google-JS
Content-Type: multipart/form-data; boundary=----CloudPrintFormBoundaryqeq6g6ncj5v7
------CloudPrintFormBoundaryqeq6g6ncj5v7
Content-Disposition: form-data; name="capabilities"
{"capabilities":[{}]}
------CloudPrintFormBoundaryqeq6g6ncj5v7
Content-Disposition: form-data; name="contentType"
dataUrl
------CloudPrintFormBoundaryqeq6g6ncj5v7
Content-Disposition: form-data; name="title"
zodiac-pig-pic.jpg
------CloudPrintFormBoundaryqeq6g6ncj5v7
Content-Disposition: form-data; name="content"
data:image/jpeg;base64,JVBERi0xLjQKJeHp69MKMiAwIG...2NgolJUVPRg==
------CloudPrintFormBoundaryqeq6g6ncj5v7--
This is the complete code if it helps:
using System;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using GoogleCloudPrintServices.DTO;
namespace GoogleCloudPrintServices.Support
{
public class GoogleCloudPrint
{
public string UserName { get; set; }
public string Password { get; set; }
public string Source { get; set; }
private const int ServiceTimeout = 10000;
public GoogleCloudPrint (String source)
{
Source = source;
}
public CloudPrintJob PrintDocument (string printerId, string title, byte[] document, String mimeType)
{
try
{
string authCode;
if (!Authorize (out authCode))
return new CloudPrintJob { success = false };
var b64 = Convert.ToBase64String (document);
var request = (HttpWebRequest)WebRequest.Create ("http://www.google.com/cloudprint/submit?output=json&printerid=" + printerId);
request.Method = "POST";
// Setup the web request
SetupWebRequest (request);
// Add the headers
request.Headers.Add ("X-CloudPrint-Proxy", Source);
request.Headers.Add ("Authorization", "GoogleLogin auth=" + authCode);
var p = new PostData ();
p.Params.Add (new PostDataParam { Name = "printerid", Value = printerId, Type = PostDataParamType.Field });
p.Params.Add (new PostDataParam { Name = "capabilities", Value = "{\"capabilities\":[{}]}", Type = PostDataParamType.Field });
p.Params.Add (new PostDataParam { Name = "contentType", Value = "dataUrl", Type = PostDataParamType.Field });
p.Params.Add (new PostDataParam { Name = "title", Value = title, Type = PostDataParamType.Field });
p.Params.Add (new PostDataParam
{
Name = "content",
Type = PostDataParamType.Field,
Value = "data:" + mimeType + ";base64," + b64
});
var postData = p.GetPostData ();
Trace.WriteLine (postData);
byte[] data = Encoding.UTF8.GetBytes (postData);
request.ContentType = "multipart/form-data; boundary=" + p.Boundary;
Stream stream = request.GetRequestStream ();
stream.Write (data, 0, data.Length);
stream.Close ();
// Get response
var response = (HttpWebResponse)request.GetResponse ();
var responseContent = new StreamReader (response.GetResponseStream ()).ReadToEnd ();
var serializer = new DataContractJsonSerializer (typeof (CloudPrintJob));
var ms = new MemoryStream (Encoding.Unicode.GetBytes (responseContent));
var printJob = serializer.ReadObject (ms) as CloudPrintJob;
return printJob;
}
catch (Exception ex)
{
return new CloudPrintJob { success = false, message = ex.Message };
}
}
public CloudPrinters Printers
{
get
{
var printers = new CloudPrinters ();
string authCode;
if (!Authorize (out authCode))
return new CloudPrinters { success = false };
try
{
var request = (HttpWebRequest)WebRequest.Create ("http://www.google.com/cloudprint/search?output=json");
request.Method = "POST";
// Setup the web request
SetupWebRequest (request);
// Add the headers
request.Headers.Add ("X-CloudPrint-Proxy", Source);
request.Headers.Add ("Authorization", "GoogleLogin auth=" + authCode);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = 0;
var response = (HttpWebResponse)request.GetResponse ();
var responseContent = new StreamReader (response.GetResponseStream ()).ReadToEnd ();
var serializer = new DataContractJsonSerializer (typeof (CloudPrinters));
var ms = new MemoryStream (Encoding.Unicode.GetBytes (responseContent));
printers = serializer.ReadObject (ms) as CloudPrinters;
return printers;
}
catch (Exception)
{
return printers;
}
}
}
private bool Authorize (out string authCode)
{
var result = false;
authCode = "";
var queryString = String.Format ("https://www.google.com/accounts/ClientLogin?accountType=HOSTED_OR_GOOGLE&Email={0}&Passwd={1}&service=cloudprint&source={2}",
UserName, Password, Source);
var request = (HttpWebRequest)WebRequest.Create (queryString);
// Setup the web request
SetupWebRequest (request);
var response = (HttpWebResponse)request.GetResponse ();
var responseContent = new StreamReader (response.GetResponseStream ()).ReadToEnd ();
var split = responseContent.Split ('\n');
foreach (var s in split)
{
var nvsplit = s.Split ('=');
if (nvsplit.Length == 2)
{
if (nvsplit[0] == "Auth")
{
authCode = nvsplit[1];
result = true;
}
}
}
return result;
}
private static void SetupWebRequest (HttpWebRequest webRequest)
{
// Get the details
var appSettings = ConfigurationManager.AppSettings;
// Create some credentials
if (!String.IsNullOrWhiteSpace (appSettings["ProxyUsername"]))
{
var cred = new NetworkCredential (appSettings["ProxyUsername"], appSettings["ProxyPassword"],
appSettings["ProxyDomain"]);
// Set the credentials
webRequest.Credentials = cred;
webRequest.Proxy = WebRequest.DefaultWebProxy;
webRequest.Proxy.Credentials = cred;
}
// Set the timeout
webRequest.Timeout = ServiceTimeout;
webRequest.ServicePoint.ConnectionLeaseTimeout = ServiceTimeout;
webRequest.ServicePoint.MaxIdleTime = ServiceTimeout;
// Turn off the 100's
webRequest.ServicePoint.Expect100Continue = false;
}
}
}
using System.Runtime.Serialization;
namespace GoogleCloudPrintServices.DTO
{
[DataContract]
public class CloudPrinter
{
[DataMember (Order = 0)]
public string id { get; set; }
[DataMember (Order = 1)]
public string name { get; set; }
[DataMember (Order = 2)]
public string description { get; set; }
[DataMember (Order = 3)]
public string proxy { get; set; }
[DataMember (Order = 4)]
public string status { get; set; }
[DataMember (Order = 5)]
public string capsHash { get; set; }
[DataMember (Order = 6)]
public string createTime { get; set; }
[DataMember (Order = 7)]
public string updateTime { get; set; }
[DataMember (Order = 8)]
public string accessTime { get; set; }
[DataMember (Order = 9)]
public bool confirmed { get; set; }
[DataMember (Order = 10)]
public int numberOfDocuments { get; set; }
[DataMember (Order = 11)]
public int numberOfPages { get; set; }
}
}
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace GoogleCloudPrintServices.DTO
{
[DataContract]
public class CloudPrinters
{
[DataMember (Order = 0)]
public bool success { get; set; }
[DataMember (Order = 1)]
public List<CloudPrinter> printers { get; set; }
}
}
using System.Runtime.Serialization;
namespace GoogleCloudPrintServices.DTO
{
[DataContract]
public class CloudPrintJob
{
[DataMember (Order = 0)]
public bool success { get; set; }
[DataMember (Order = 1)]
public string message { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace GoogleCloudPrintServices.Support
{
internal class PostData
{
private const String CRLF = "\r\n";
public string Boundary { get; set; }
private List<PostDataParam> _mParams;
public List<PostDataParam> Params
{
get { return _mParams; }
set { _mParams = value; }
}
public PostData ()
{
// Get boundary, default is --AaB03x
Boundary = "----CloudPrintFormBoundary" + DateTime.UtcNow;
// The set of parameters
_mParams = new List<PostDataParam> ();
}
public string GetPostData ()
{
var sb = new StringBuilder ();
foreach (var p in _mParams)
{
sb.Append ("--" + Boundary).Append (CRLF);
if (p.Type == PostDataParamType.File)
{
sb.Append (string.Format ("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"", p.Name, p.FileName)).Append (CRLF);
sb.Append ("Content-Type: ").Append (p.FileMimeType).Append (CRLF);
sb.Append ("Content-Transfer-Encoding: base64").Append (CRLF);
sb.Append ("").Append (CRLF);
sb.Append (p.Value).Append (CRLF);
}
else
{
sb.Append (string.Format ("Content-Disposition: form-data; name=\"{0}\"", p.Name)).Append (CRLF);
sb.Append ("").Append (CRLF);
sb.Append (p.Value).Append (CRLF);
}
}
sb.Append ("--" + Boundary + "--").Append (CRLF);
return sb.ToString ();
}
}
public enum PostDataParamType
{
Field,
File
}
public class PostDataParam
{
public string Name { get; set; }
public string FileName { get; set; }
public string FileMimeType { get; set; }
public string Value { get; set; }
public PostDataParamType Type { get; set; }
public PostDataParam ()
{
FileMimeType = "text/plain";
}
}
}
Just use HTTPS instead of HTTP. Some GCP API has transferred to HTTPS.