I am working on a Facebook application and I can successfully get the user's info in JSON after authorizing. However, when I refresh the page, I'm redirected to Facebook for OAuth when I thought that the authorization had already taken place. I had understood that I only needed an access token, subsequently.
if (fbData != null)
{
if (fbData.user_id == null)
{
var redirURL = Request.Url.Scheme + "://" + fbAuthURL.Replace("[APPID]", appId).Replace("[REDIRECT]", (Request.Url.Scheme + "://" + canvasPage));
Response.Write("<script type=\"text/javascript\"> " + Environment.NewLine +
"top.location.href=\"" + redirURL + "\";" + Environment.NewLine +
"</script>");
Response.Write("Redirect URL for Authorization : " + redirURL);
}
else
{
if (isReady == true)
{
MyWebRequest userRequest = new MyWebRequest("https://graph.facebook.com/me?access_token=" + accessToken);
string userInfo = userRequest.GetResponse();
//Response.Write(userInfo);
FBAuth fuser = new FBAuth();
UserInfo oUser = fuser.GetUserInfo(userInfo);
}}}
How can I handle it?
Related
The following is a method for sending an Email from a Razor page in ASP.NET Core. I need to use MailKit since System.Net.Mail is not available in ASP.NET Core.
Despite much research, I haven't been able to figure out a way to include the image to the Email. Note that it doesn't have to be an attachment - embedding the image will work.
public ActionResult Contribute([Bind("SubmitterScope, SubmitterLocation, SubmitterItem, SubmitterCategory, SubmitterEmail, SubmitterAcceptsTerms, SubmitterPicture")]
EmailFormModel model)
{
if (ModelState.IsValid)
{
try
{
var emailName= _appSettings.EmailName;
var emailAddress = _appSettings.EmailAddress;
var emailPassword = _appSettings.EmailPassword;
var message = new MimeMessage();
message.From.Add(new MailboxAddress(emailName, emailAddress));
message.To.Add(new MailboxAddress(emailName, emailAddress));
message.Subject = "Record Submission From: " + model.SubmitterEmail.ToString();
message.Body = new TextPart("plain")
{
Text = "Scope: " + model.SubmitterScope.ToString() + "\n" +
"Zip Code: " + model.SubmitterLocation.ToString() + "\n" +
"Item Description: " + model.SubmitterItem.ToString() + "\n" +
"Category: " + model.SubmitterCategory + "\n" +
"Submitted By: " + model.SubmitterEmail + "\n" +
// This is the file that should be attached.
//"Picture: " + model.SubmitterPicture + "\n" +
"Terms Accepted: " + model.SubmitterAcceptsTerms + "\n"
};
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// Note: only needed if the SMTP server requires authentication
client.Authenticate(emailAddress, emailPassword);
client.Send(message);
client.Disconnect(true);
return RedirectToAction("Success");
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + ": " + ex.StackTrace);
return RedirectToAction("Failure");
}
}
else
{
return View();
}
}
This is from the FAQ on Mailkit github repo, and seems to cover the full process.
https://github.com/jstedfast/MailKit/blob/master/FAQ.md#CreateAttachments
var message = new MimeMessage ();
message.From.Add (new MailboxAddress ("Joey", "joey#friends.com"));
message.To.Add (new MailboxAddress ("Alice", "alice#wonderland.com"));
message.Subject = "How you doin?";
// create our message text, just like before (except don't set it as the message.Body)
var body = new TextPart ("plain") {
Text = #"Hey Alice,
What are you up to this weekend? Monica is throwing one of her parties on
Saturday and I was hoping you could make it.
Will you be my +1?
-- Joey
"
};
// create an image attachment for the file located at path
var attachment = new MimePart ("image", "gif") {
ContentObject = new ContentObject (File.OpenRead (path), ContentEncoding.Default),
ContentDisposition = new ContentDisposition (ContentDisposition.Attachment),
ContentTransferEncoding = ContentEncoding.Base64,
FileName = Path.GetFileName (path)
};
// now create the multipart/mixed container to hold the message text and the
// image attachment
var multipart = new Multipart ("mixed");
multipart.Add (body);
multipart.Add (attachment);
// now set the multipart/mixed as the message body
message.Body = multipart;
i want to show full size or any size facebook photo on my page using asp.net
but i am not able to do this by type in url.
here is my code.
public FacebookAlbums GetFacebookAlbums(string userName, string accessToken)
{
string url = "https://graph.facebook.com/" + userName + "/albums?access_token=" + accessToken;
return Tools.CallUrl<FacebookAlbums>(url);
}
public FacebookPhotos GetPhotosOfAlbum(string albumId, string accessToken)
{
string url = "https://graph.facebook.com/" + albumId + "/photos?type=large&access_token=" + accessToken;
return Tools.CallUrl<FacebookPhotos>(url);
}
this is how i am accessing the above class.
public void GetFacebookAlbums()
{
FacebookDetails FBDetail = new FacebookRepository().GetFacebookDetail();
FacebookAlbums FBAlbums = new FacebookRepository().GetFacebookAlbums(FBDetail.FacebookId, FBDetail.FacebookAccessToken);
StringBuilder sbHtml = new StringBuilder();
FBAlbums.data.ForEach(_albums =>
{
sbHtml.Append("<h3>" + _albums.name + "</h3><ul>");
FacebookPhotos fbPhotos = new FacebookRepository().GetPhotosOfAlbum(_albums.id, FBDetail.FacebookAccessToken);
fbPhotos.data.ForEach(_photo =>
{
sbHtml.Append("<li><img src=\"" + _photo.picture + "\" /></li>");
});
sbHtml.Append("</ul> <br>");
});
ltDisplayPhotos.Text = sbHtml.ToString();
}
here i am making the connection with facebook like
string strFBUrl = "https://graph.facebook.com/oauth/authorize?client_id=" + FacebookRepository.FacebookAppID + "&" +
"redirect_uri=http://" + strHostAddress + #"/FBAuthorise.aspx&scope=user_photos,user_videos,publish_stream,offline_access,user_photo_video_tags";
Hello friends I have developed many to many chat application using signal R it is working perfectly fine.But i am getting one problem in developing one thing..that is typing message to the reciever for example:- there are two user online user x and user y.now when user x is typing message..on user y window it should come.."user x is typing message.." but when i send this message to group it is getting displayed on both screen..I want to display it on reciever screen only
This is the code
public void Send(string message, string groupName, string Istypingmessage)
{
if (Clients != null)
{
string[] words = message.Split(':');
string trim = words[0].Trim();
string imagetag = "<img width=\"32px\" height=\"32px\" src=\"userimages/" + trim + ".jpg" + "\"" + "></img> ";
Clients.Group(groupName).addMessage(message, groupName, words[0], imagetag, Istypingmessage);
}
}
where here typing message=0 means normal message and 1 means "user x is typing that message"
This is the key press event
//keypress event of textbbox here..
$(".ChatText").live('keyup', function () {
if($(".ChatText").val().length > 0)
{
var messsage_typing=$("#hdnUserName").val() + " is typing...";
var strGroupName = $(this).parent().attr('groupname');
if (typeof strGroupName !== 'undefined' && strGroupName !== false)
chat.server.send($("#hdnUserName").val() + ' : ' + messsage_typing, $(this).parent().attr('groupname'),"1");
}
});
//end of keypress
and this is add message code
chat.client.addMessage = function (message, groupName,recievername,imagetag,Istypingmessage) {
if ($('div[groupname=' + groupName + ']').length == 0) {
var chatWindow = $("#divChatWindow").clone(true);
$(chatWindow).css('display', 'block');
$(chatWindow).attr('groupname', groupName);
$("#chatContainer").append(chatWindow);
//buggy code do not delete..
//remove all previous li
$('div[groupname=' + groupName + ']').find('ul li').remove();
//replace header tag with new name
$('div[groupname=' + groupName + ']').find('a').html(recievername);
$("#chatContainer").draggable();
$("#chatContainer").css('cursor','move');
}
if(Istypingmessage=="0")
{
var stringParts = message.split(":");
var username = stringParts[0];
var message = stringParts[1];
//this code is for continous message sent
var lastliusername=$('div[groupname=' + groupName + '] ul li').eq(-2).find('div.designnone').html();
if(lastliusername!=null && $.trim(username)==$.trim(lastliusername))
{
$('div[groupname=' + groupName + '] ul li').eq(-2).find('div.designmessage').append("<span class='spansameuser'>" + message + "</span>");
//end of this code is for continous message sent
}
else
{
$('div[groupname=' + groupName + ']').find('ul').append("<li><div class='design'>" + imagetag + "</div><div class='designnone'> " + username + "</div><div class='designmessage'> " + message + " </div></li><li class='cleardivbetweenmsg'></li>");
}
}
else
{
$('div[groupname=' + groupName + ']').find('ul').append("<li><span>Hellos</span></li>");
}
$("#messages").scrollTop($("#messages")[0].scrollHeight);
};
How can i display typing message to my reciever instead of on both screens..please help me out..In short i want to send my message only to reciever of group not to sender of the group
Thanks
If you want to send a message to all clients in a group except for the sender, you can use Clients.OthersInGroup:
Clients.OthersInGroup(groupName).addMessage(/*...*/);
This is the equivalent to passing the sender's connection ID as a second parameter to Clients.Group making it an excluded connection ID.
Clients.Group(groupName, Context.ConnectionId).addMessage(/*...*/);
The method signature for Clients.Group is: public dynamic Group(string groupName, params string[] excludeConnectionIds).
I have implement a simple file-based custom OutputCacheProvider based on samples i found on the Internet.
The code follows:
using System;
using System.Configuration;
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Diagnostics;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
namespace SimpleCachedProvider
{
public class FileCacheProvider : OutputCacheProvider {
private string _cachePath;
void WriteToFile(String filename, String contents) {
FileStream fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter w = new StreamWriter(fs, System.Text.Encoding.GetEncoding(1253));
w.BaseStream.Seek(0, SeekOrigin.Begin);
w.BaseStream.SetLength(0);
w.Write(contents);
w.Flush();
w.Close();
}
void AppendToFile(String filename, String contents) {
if (contents.ToLower().IndexOf("ss2.aspx") >= 0 || contents.ToLower().IndexOf("default.aspx") >= 0) {
FileStream fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter w = new StreamWriter(fs, System.Text.Encoding.GetEncoding(1253));
w.BaseStream.Seek(0, SeekOrigin.End);
w.Write(contents);
w.Flush();
w.Close();
}
}
private string CachePath {
get {
if (!string.IsNullOrEmpty(_cachePath))
return _cachePath;
_cachePath = ConfigurationManager.AppSettings["OutputCachePath"];
var context = HttpContext.Current;
if (context != null) {
_cachePath = context.Server.MapPath(_cachePath);
if (!_cachePath.EndsWith("\\"))
_cachePath += "\\";
}
return _cachePath;
}
}
public override object Add(string key, object entry, DateTime utcExpiry) {
var path = GetPathFromKey(key);
AppendToFile(CachePath + "info.txt", "ADD: " + key + " (" + path + ")\r\n");
if (File.Exists(path)) {
AppendToFile(CachePath + "info.txt", "ADD: " + key + " (" + path + ") already exists. Will be returned.\r\n");
return entry;
}
AppendToFile(CachePath + "info.txt", "ADD: " + key + " (" + path + ") does not exists. Will be created.\r\n");
using (var file = File.OpenWrite(path)) {
var item = new CacheItem { Expires = utcExpiry, Item = entry };
var formatter = new BinaryFormatter();
formatter.Serialize(file, item);
AppendToFile(CachePath + "info.txt", "ADD: " + key + " (" + path + ") saved to disk.\r\n");
}
return entry;
}
public override void Set(string key, object entry, DateTime utcExpiry) {
var item = new CacheItem { Expires = utcExpiry, Item = entry };
var path = GetPathFromKey(key);
AppendToFile(CachePath + "info.txt", "Set: " + key + " (" + path + ") requested.\r\n");
using (var file = File.OpenWrite(path)) {
var formatter = new BinaryFormatter();
formatter.Serialize(file, item);
AppendToFile(CachePath + "info.txt", "Set: " + key + " (" + path + "): " + utcExpiry.ToLocalTime().ToString("dd/MM/yyyy HH:mm:ss") + " saved to disk.\r\n");
}
}
public override object Get(string key) {
var path = GetPathFromKey(key);
AppendToFile(CachePath + "info.txt", "Get: Querying " + key + " (" + path + ")\r\n");
if (!File.Exists(path)) {
AppendToFile(CachePath + "info.txt", "Get: " + key + " (" + path + ") not found.\r\n");
return null;
}
CacheItem item = null;
using (var file = File.OpenRead(path)) {
var formatter = new BinaryFormatter();
item = (CacheItem)formatter.Deserialize(file);
AppendToFile(CachePath + "info.txt", "Get: " + key + " (" + path + ") retrieved.\r\n");
}
if (item == null || item.Expires <= DateTime.Now.ToUniversalTime()) {
AppendToFile(CachePath + "info.txt", "Get: " + key + " (" + path + ") deleted due to expiration.\r\n");
Remove(key);
return null;
}
AppendToFile(CachePath + "info.txt", "Get: " + key + " (" + path + ") retrieved and used\r\n");
return item.Item;
}
public override void Remove(string key) {
var path = GetPathFromKey(key);
AppendToFile(CachePath + "info.txt", "Remove: " + key + " (" + path + ") requested.\r\n");
if (File.Exists(path)) {
AppendToFile(CachePath + "info.txt", "Remove: " + key + " (" + path + ") executed.\r\n");
File.Delete(path);
}
}
private string GetPathFromKey(string key) {
return CachePath + MD5(key) + ".txt";
}
private string MD5(string s) {
MD5CryptoServiceProvider provider;
provider = new MD5CryptoServiceProvider();
byte[] bytes = Encoding.UTF8.GetBytes(s);
StringBuilder builder = new StringBuilder();
bytes = provider.ComputeHash(bytes);
foreach (byte b in bytes)
builder.Append(b.ToString("x2").ToLower());
return builder.ToString();
}
}
}
I have then created an .aspx with the header
<%# OutputCache Duration="3600" Location="Server" VaryByParam="*" %>
I have changed the default output cache provider to my web.config to mine.
The strange behavior is that the page is not cached. Instead this is a sample output from my debugging information. It seems that:
The page is retrieved from tha cache and sent back to ASP.Net
Right after that ASP.Net calls the Remove() method to my page
Finally ASP.Net calls Set() and the page is updated - no effective caching
Get: Querying a2/ss2.aspx (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\7394fd15241e5b7f5c437ddf28dcd0e5.txt)
Get: a2/ss2.aspx (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\7394fd15241e5b7f5c437ddf28dcd0e5.txt) retrieved.
Get: a2/ss2.aspx (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\7394fd15241e5b7f5c437ddf28dcd0e5.txt) retrieved and used
Get: Querying a2/ss2.aspxHQFCNmycustom2VDE (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\3e72454ab3f36e4cfe3964e5063be622.txt)
Get: a2/ss2.aspxHQFCNmycustom2VDE (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\3e72454ab3f36e4cfe3964e5063be622.txt) retrieved.
Get: a2/ss2.aspxHQFCNmycustom2VDE (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\3e72454ab3f36e4cfe3964e5063be622.txt) retrieved and used
Remove: a2/ss2.aspxHQFCNmycustom2VDE (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\3e72454ab3f36e4cfe3964e5063be622.txt) requested.
Remove: a2/ss2.aspxHQFCNmycustom2VDE (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\3e72454ab3f36e4cfe3964e5063be622.txt) executed.
ADD: a2/ss2.aspx (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\7394fd15241e5b7f5c437ddf28dcd0e5.txt)
ADD: a2/ss2.aspx (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\7394fd15241e5b7f5c437ddf28dcd0e5.txt) already exists. Will be returned.
Set: a2/ss2.aspxHQFCNmycustom2VDE (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\3e72454ab3f36e4cfe3964e5063be622.txt) requested.
Set: a2/ss2.aspxHQFCNmycustom2VDE (C:\eShopKey\ASP.Net\Shops\myshoe_dev\Cache\3e72454ab3f36e4cfe3964e5063be622.txt): 30/05/2012 15:07:27 saved to disk.
So my questions:
Why ASP.Net keeps invalidating my page?
When Remove() and Set() methods are called by ASP.Net? I have not found any info regarding that.
If i rename the page and use this variation caching works! This is totally weird.
Note that if i use the default ASP.Net outputcacheprovider caching works as expected.
I found what is going on but unable to fix it:
Let's say i open the page: http://www.mydomain.com/mypage.aspx?param1=1
ASP.Net sends 2 consecutive GET requests to my OutputCacheProvider:
one for the page mypage.aspx
another for the same page but with the querystring parameters attached
It seems to me that the first request is somehow related with the second one, like a header.
As soon as i call consecutively the same page, with the same querystring, caching working as expected.
If i call next the page: http://www.mydomain.com/mypage.aspx?param1=2
then the same, 2 step GET sequence, is initialized. The ASP.Net sends 2 GET requests, one for the page without parameters and one with parameters.
The first GET request (for the page without parameters) is then found on the cache and returned back to ASP.Net. But somehow is unrelated with the second one. It is related to the first variation of the call (param1=1).
So, nevertheless if the second request has been cached before, ASP.Net thinks that the cached page is invalid and ask again for add / set.
To summarize it seems that you can have just one variation of the page to the cache at a given moment. All previous cahed variations will be invalidated as the page will be called again with other parameters.
There is no way to check what the first GET request is related to as ASP.NET uses the same key to retrieve it.
So my new questions:
Why ASP.Net sends 2 requests for every page to the custom output cache provider? Does anybody knows?
How i can overcome this strange behavior?
Is the AspNetInternalProvider has the same behavior?
I found the solution! The problem was on Add method. It has to be written on all providers like below:
public override object Add(string key, object entry, DateTime utcExpiry) {
String vKey = TransformKey(key);
object res = Get(key);
if (res == null) {
Set(key, entry, utcExpiry);
return entry;
}
return res;
}
The TransformKey method just returns a safe string (string without bad characters) based on key (for example the MD5 hash of the key). Look for an implementation on my first posted code.
the first request returns an object System.Web.Caching.CachedVary, and second request returns System.Web.Caching.OutputCacheEntry. According to the name of object, the first one is for OutputCache, and the second one is for the data of page.
if you have any questions, pls send email to shengzhengshan#hotmail.com
Hope it can help you!
Amir Sheng
On a testing server my URL=
http:
//scantdev04:8086/ActivityReport.aspx
I want to prefill a new URL with query data and pass it to the new url:
string sUrl = sRelativePath + "?Organization=" + sOrganization
+ "&&StartDate=" + sStartDate
+ "&&EndDate=" + endDate;
string displayScript = "" +
"window.open('" + sUrl + "', 'DisplayReport', " +
"'width=1200, height=800, toolbar=yes, menubar=yes, resizable=yes, scrollbars=yes')" +
"";
Pretty straight forward.
On dev box, localhost, it is all good.
But in test, the URL spits out like:
http://www.displayreport.aspx/?Organization=Correctional%20Alternatives,%20Inc&&StartDate=09-01-2009&&EndDate=10/6/2009%2012:00:00%20AM
How do I fix the www. that is now there and repeat the "http://scantdev04:8086/"
I would rather not push this to the web.config but will if necessary.
Where does your sRelativePath string come from?
Found this and it seems to work:
old version:
string sRelativePath = Request.ApplicationPath + "/DisplayReport.aspx";
Now changed to :
string sRelativePath = GetWebAppRoot() + "/DisplayReport.aspx";
GetWebRoot() :
string host = (HttpContext.Current.Request.Url.IsDefaultPort) ?
HttpContext.Current.Request.Url.Host : HttpContext.Current.Request.Url.Authority;
host = String.Format("{0}://{1}", HttpContext.Current.Request.Url.Scheme, host);
if (HttpContext.Current.Request.ApplicationPath == "/")
return host;
else
return host + HttpContext.Current.Request.ApplicationPath;