VB.NET Upload Photos to Facebook using Graph API - vb.net

Looking for some code to upload a photo to facebook using the Graph API in VB.NET. I have the Facebook C# SDK, but it doesn't support uploading photos as far as I can tell.
Accessing the photos works fine and I can send other content to Facebook fine as well. Just not photos.
The facebook documentation talks about attaching the file as a form-multipart request, but I have no idea how to do that. To say that its not very well documented is to put it lightly. Even the guys I hire to do this kind of thing couldn't get it to work.
I've found this: Upload Photo To Album with Facebook's Graph API, but it only describes how to do it in PHP.
I've also seen varying method from different sites about passing the URL of the photo as a part of the HTTP request, but after trying local or remote URLs several times I kept getting a bad url error or something like that.
Any thoughts?

You need to pass the Image in a POST request to the Graph API (Need publish_stream permission). What is mentioned in Facebook Documentation is correct. Following is the example code that may do the work. use it inside a method. (Code is in C#)
Legend
<content> : you need to provide the info.
Update
Please post comments to improve the code.
string ImageData;
string queryString = string.Concat("access_token=", /*<Place your access token here>*/);
string boundary = DateTime.Now.Ticks.ToString("x", CultureInfo.InvariantCulture);
StringBuilder sb = String.Empty;
sb.Append("----------").Append(boundary).Append("\r\n");
sb.Append("Content-Disposition: form-data; filename=\"").Append(/*<Enter you image's flename>*/).Append("\"").Append("\r\n");
sb.Append("Content-Type: ").Append(String.Format("Image/{0}"/*<Enter your file type like jpg, bmp, gif, etc>*/)).Append("\r\n").Append("\r\n");
using (FileInfo file = new FileInfo("/*<Enter the full physical path of the Image file>*/"))
{
ImageData = file.OpenText().ReadToEnd();
}
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sb.ToString());
byte[] fileData = Encoding.UTF8.GetBytes(ImageData);
byte[] boundaryBytes = Encoding.UTF8.GetBytes(String.Concat("\r\n", "----------", boundary, "----------", "\r\n"));
var postdata = new byte[postHeaderBytes.Length + fileData.Length + boundaryBytes.Length];
Buffer.BlockCopy(postHeaderBytes, 0, postData, 0, postHeaderBytes.Length);
Buffer.BlockCopy(fileData, 0, postData, postHeaderBytes.Length, fileData.Length);
Buffer.BlockCopy(boundaryBytes, 0, postData, postHeaderBytes.Length + fileData.Length, boundaryBytes.Length);
var requestUri = new UriBuilder("https://graph.facebook.com/me/photos");
requestUri.Query = queryString;
var request = (HttpWebRequest)HttpWebRequest.Create(requestUri.Uri);
request.Method = "POST";
request.ContentType = String.Concat("multipart/form-data; boundary=", boundary);
request.ContentLength = postData.Length;
using (var dataStream = request.GetRequestStream())
{
dataStream.Write(postData, 0, postData.Length);
}
request.GetResponse();

Related

How change base url in image tag?

I have many images in site. All images stay on site and use as static files. But I need change base url to cdn. I have middleware which verify images are exist. Then it reads image and write to context
// HttpContext contex;
byte[] fileContent = File.ReadAllBytes(staticFilePath);
context.Response.ContentType = MimeKit.MimeTypes.GetMimeType(staticFilePath);
await context.Response.Body.WriteAsync(fileContent, 0, fileContent.Length);
I make download images from cdn but I think it isn`t good idea:
using (var webClient = new WebClient())
{
byte[] fileContent = webClient.DownloadData(staticFilePath);
context.Response.ContentType = MimeKit.MimeTypes.GetMimeType(staticFilePath);
await context.Response.Body.WriteAsync(fileContent, 0, fileContent.Length);
}
Any help would be greatly appreciated.
Maybe can I write url in context.Response.Body?

How to get microsoft account profile photo after login with application in mvc

With the help of claimprincipal, I'm able to get the details of signedin user as below but its not giving any pic related information as google does:
https://apis.live.net/v5.0/{USER_ID}/picture?type=large
which says The URL contains the path '{user_id}', which isn't supported.
Even tried
https://graph.microsoft.com/v1.0/me/photo/$value
which is asking for access token, but I am not sure what have to be passed
string userName = ClaimsPrincipal.Current.FindFirst("name").Value;
string userEmail = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
Wanted an image which was added in any outlook account
For Image to show.. We have to use beared token and have to convert the image into memory stream and then have to used it.. I have done it in below ways. Hope this help ...
var client = new RestClient("https://login.microsoftonline.com/common/oauth2/token");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", $"code={code}&client_id={OutClientId}&client_secret={SecretKey}&redirect_uri={OutRedirectUrl}&grant_type=authorization_code", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Token jsonContent = JsonConvert.DeserializeObject<Token>(response.Content);
var Token = jsonContent.AccessToken;
var TokenType = jsonContent.TokenType;
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Token);
HttpResponseMessage response1 = await httpClient.GetAsync("https://graph.microsoft.com/v1.0/me/photos/96x96/$value");
if (response1.StatusCode == HttpStatusCode.OK)
{
using (Stream responseStream = await response1.Content.ReadAsStreamAsync())
{
MemoryStream ms = new MemoryStream();
responseStream.CopyTo(ms);
byte[] buffer = ms.ToArray();
string result = Convert.ToBase64String(buffer);
HttpContext.Session[AppConstants.UserImage] = String.Format("data:image/gif;base64,{0}", result);
responseStream.Close();
}
}
Is there any reason you are using the live.net apis? Instead of the Microsoft Graph APIs? Microsoft Graph APIs are the future for all user data within Microsoft 365 consumer and commercial accounts.
You can get the Users photo very easily as described here https://learn.microsoft.com/en-us/graph/api/profilephoto-get?view=graph-rest-1.0
GET /me/photo/$value
As you are using ASP.NET MVC, there is an SDK you can use that makes this very easy too.
https://learn.microsoft.com/en-us/graph/sdks/sdks-overview?context=graph%2Fapi%2F1.0&view=graph-rest-1.0

Attaching an Image to Work item in Visual Studio Team Services (was Visual Studio Online)

I'm sending an attachment through the Visual Studio Team Services API and it all look like its fine, until I look at the attachment on the work item.
The attachment should be a picture, but it a little black box with a white cross.
Has anyone had this issue and does anyone know what I've done wrong?
I get the image and convert it to a 64 Base string
FileInfo info = new FileInfo(attachment.Path);
byte[] bytes = File.ReadAllBytes(info.FullName);
String file = Convert.ToBase64String(bytes);
Then I send it to the API. This returns a message saying its been successful.
using (System.Net.Http.HttpClient client = new System.Net.Http.HttpClient())
{
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(getConnectionDetails())));
using (System.Net.Http.HttpResponseMessage response = client.PostAsync(SetURL(url),
new StringContent(binaryString,Encoding.UTF8,"application/json")).Result)
{
response.EnsureSuccessStatusCode();
responseString = await response.Content.ReadAsStringAsync();
}
}
I think its something small, that I'm missing!
This is the link to the document, I have used.
API document
Try it this way:
...
string uri = "https://xxxxxx.visualstudio.com/_apis/wit/attachments?fileName=test.jpg&api-version=1.0";
string filepath = "C:\\images\\test.jpg";
FileStream files = new FileStream(filepath,FileMode.Open);
StreamContent streamcontent = new StreamContent(files);
...
HttpResponseMessage response = hc.PostAsync(uri, streamcontent).Result;
...

Crawl Wikipedia using ASP.NET HttpWebRequest

I am new to Web Crawling, and I am using HttpWebRequest to crawl data from sites.
As of now I was successfully able to crawl and get data from my wordpress site. This data was a simple user profile data. (like name, email, AIM id etc...)
Now as an exercise I want to crawl wikipedia, where I will search using the value entered into textbox at my end and then crawl wikipedia with the search value and get the appropriate title(s) from the search.
Now I have the following doubts/difficulties.
Firstly, is this even possible ? I have heard that wiki has robot.txt setup to block this. Though I have heard this only from a friend and hence not sure.
I am using the same procedure I used earlier, but I am not getting the required results.
Thanks !
Update :
After some explanation and help from #svick, I tried the below code, but still not able to get any value (see last line of code, there I am expecting an html markup of the search result page)
string searchUrl = "http://en.wikipedia.org/w/index.php?search=Wikipedia&title=Special%3ASearch";
var postData = new StringBuilder();
postData.Append("search=" + model.Query);
postData.Append("&");
postData.Append("title" + "Special:Search");
byte[] data2 = Crawler.GetEncodedData(postData.ToString());
var webRequest = (HttpWebRequest)WebRequest.Create(searchUrl);
webRequest.Method = "POST";
webRequest.UserAgent = "Crawling HW (http://yassershaikh.com/contact-me/)";
webRequest.AllowAutoRedirect = false;
ServicePointManager.Expect100Continue = false;
Stream requestStream = webRequest.GetRequestStream();
requestStream.Write(data2, 0, data2.Length);
requestStream.Close();
var responseCsv = (HttpWebResponse)webRequest.GetResponse();
Stream response = responseCsv.GetResponseStream();
// Todo Parsing
var streamReader = new StreamReader(response);
string val = streamReader.ReadToEnd();
// val is empty !! <-- this is my problem !
and here is my GetEncodedData method defination.
public static byte[] GetEncodedData(string postData)
{
var encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(postData);
return data;
}
Pls help me on this.
You probably don't need to use HttpWebRequest. Using WebClient (or HttpClient if you're on .Net 4.5) will be much easier for you.
robots.txt doesn't actually block anything. If something doesn't support it (and .Net doesn't support it), it can access anything.
Wikipedia does block requests that don't have their User-Agent header set. And you should use an informative User-Agent string with your contact information.
A better way to access Wikipedia is to use its API, rather than scraping. This way, you will get an answer that's specifically meant to be read by a custom applications, formatted as XML or JSON. There are also dumps containing all information from Wikipedia available for download.
EDIT: The problem with your newly posted code is that your query returns a 302 Moved Temporarily response to the searched article, if it exists. Either remove the line that forbids AllowAutoRedirect, or add &fulltext=Search to your query, which will mean you won't get redirected.

Why am I getting a "double response" from HttpWebResponse?

The follow code (running in ASP.Net 2.0) displays the contents of the requested URL twice. I only want it to display the contents of the requested URL once. I can't figure out what I'm doing wrong. The URL requested is returning XML and if I visit the URL directly, it works fine.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
byte[] postDataBytes = Encoding.UTF8.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/xml";
request.ContentLength = postDataBytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(postDataBytes, 0, postDataBytes.Length);
requestStream.Close();
// get response and write to console
response = (HttpWebResponse) request.GetResponse();
StreamReader responseReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
try {
Response.Write(responseReader.ReadToEnd());
}
finally {
responseReader.Close();
}
response.Close();
Your code looks good, so I don't think the problem is there... but what I would suggest is the following:
1) Maybe the error is on the URL's other end... so try hitting Google and see if the returned content is good or not.
2) Put a breakpoint at the "responseReader.ReadToEnd()" spot, and see if what's coming out of there is good.
3) If this code above is in an ASPX page... are you making sure to call "Response.End();" after you're last line of code? (not "resposne.close()", but "Response.End()").
I found the problem. It's not with the above code at all, but with the page being called. The page I was calling was inherited from a class whose Page_OnInit method contained the following line: "MyBase.OnLoad(e)", which caused the Page_OnLoad method to be executed twice. Obviously, it should have been MyBase.OnInit(e) instead. I didn't catch it because when I tested the page directly I had to temporarily remove the inheritance from the class because of some other code that would've have prevented me from testing the page directly.
I will now put on my "Dunce" hat and retreat to the corner for a time out. Thanks anyway for the help.