POST request for Youtube direct upload from Wp8 - c#

While googling for a solution to upload videos on youtube from my windows phone 8 app i was brought to YouTube API v2.0 – Direct Uploading. I followed the article and coded as follows.
private void UploadVideoYoutube(byte[] byteArr, string isoVideoFileName)
{
Uri uri = new Uri("http://uploads.gdata.youtube.com/feeds/api/users/default/uploads");
Dictionary<string, string> post_params = new Dictionary<string, string>();
Dictionary<string, string> extra_headers = new Dictionary<string, string>();
RESTSuccessCallback success_callback = new RESTSuccessCallback(Success);
RESTErrorCallback error_callback = new RESTErrorCallback(Error);
try
{
HttpWebRequest request = WebRequest.CreateHttp(uri);
//we could move the content-type into a function argument too.
//request.ContentType = "application/atom+xml; charset=UTF-8";
//request.ContentType = "application/x-www-form-urlencoded";
request.ContentType = "video/mp4";
request.Method = "POST";
//provide parameters
post_params.Add("Authorization", "<ClientID>");
//this might be helpful for APIs that require setting custom headers...
if (extra_headers != null)
try
{
foreach (String header in extra_headers.Keys)
request.Headers[header] = extra_headers[header];
}
catch (Exception) { }
request.BeginGetRequestStream((IAsyncResult result) =>
{
HttpWebRequest preq = result.AsyncState as HttpWebRequest;
if (preq != null)
{
Stream postStream = preq.EndGetRequestStream(result);
//allow for dynamic spec of post body
StringBuilder postParamBuilder = new StringBuilder();
if (post_params != null)
foreach (String key in post_params.Keys)
postParamBuilder.Append(String.Format("{0}={1}", key, post_params[key]));
Byte[] requestByteArray = Encoding.UTF8.GetBytes(postParamBuilder.ToString());
//guess one could just accept a byte[] [via function argument] for arbitrary data types - images, audio,...
postStream.Write(requestByteArray, 0, requestByteArray.Length);
postStream.Close();
preq.BeginGetResponse((IAsyncResult final_result) =>
{
HttpWebRequest req = final_result.AsyncState as HttpWebRequest;
if (req != null)
{
try
{
//we call the success callback as long as we get a response stream
WebResponse response = req.EndGetResponse(final_result);
success_callback(response.GetResponseStream());
}
catch (WebException e)
{
//otherwise call the error/failure callback
error_callback(e.Message);
return;
}
}
}, preq);
}
}, request);
}
catch (Exception ex)
{
AppHelper.ErrorOccured(ex);
}
}
But it returned following error, please guide me.
Also please let me know if there is any youtube library for windows phones.
Thanks
The remote server returned an error: NotFound.

Related

I get error remote server not found with a request to https url

I am developing a windows phone 8 application that gets video feeds from youtube data api. I make a httpWebRequest to https://gdata.youtube.com/feeds/api/videos?max-results=10&v=2&alt=jsonc&q=fondoflamenco but I get Error remote Server: Not Found. I have the windows phone 8 devices connected to the same network.
this is the source code:
Uri targetUri = new Uri("https://gdata.youtube.com/feeds/api/videos?max-results=10&v=2&alt=jsonc&q=fondoflamenco");
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(targetUri);
request.Method = "GET";
request.BeginGetResponse(new AsyncCallback(ReadWebRequestCallback), request);
the code for ReadWebRequestCallback is:
private void ReadWebRequestCallback(IAsyncResult callBackResult)
{
HttpWebRequest myRequest = (HttpWebRequest)callBackResult.AsyncState;
try
{
HttpWebResponse myResponse = (HttpWebResponse)myRequest.EndGetResponse(callBackResult);
using (StreamReader httpwebStreamReader = new StreamReader(myResponse.GetResponseStream()))
{
var results = httpwebStreamReader.ReadToEnd();
JObject jsonObject = JObject.Parse(results);
JArray items = JArray.FromObject(jsonObject["items"]);
List<Video> videos = new List<Video>();
foreach (var item in items)
{
Video video = new Video();
video.descripcion = item["description"].ToString();
if (item["player"]["mobile"] != null)
{
video.url = item["player"]["mobile"].ToString();
}
video.imagen = new System.Windows.Media.Imaging.BitmapImage(new Uri(item["thumbnail"]["sqDefault"].ToString()));
videos.Add(video);
}
Dispatcher.BeginInvoke(delegate()
{
MediaList.ItemsSource = videos;
});
}
}
catch (WebException ex)
{
//Dispatcher.BeginInvoke(delegate() { DescriptionBox.Text = ex.Message; });
throw;
}
}
What is wrong I am doing to get Remote Server error: Not Found
I just resolved it adding empty credentials to https requests, like this
myRequest.Credentials = new NetworkCredential("", "");
here he explains it better
http://blog.toetapz.com/2010/11/15/windows-phone-7-and-making-https-rest-api-calls-with-basic-authentication/

Multiple POST using WebRequest

I am able to send the first request working fine, however I can't get my head round why it stalls on getting the Stream os = smsRequest.GetRequestStream() the second time.
I am aware that you can't write to a Request more than once that is why a new instance is created each time.
public void SendSMS(Dictionary<double, IList<string>> texts)
{
if (CreateWebRequest())
{
foreach (double mpn in texts.Keys)
{
foreach (string sms in texts[mpn])
{
string formParams = string.Format("sendTo=0{0}&selectText=Please+Select...&textMessage={1}&x=28&y=10", mpn, sms);
byte[] encodedParams = Encoding.UTF8.GetBytes(formParams);
HttpWebRequest smsRequest = CreateSMSRequest(encodedParams);
using (Stream os = smsRequest.GetRequestStream())
{
os.Write(encodedParams, 0, encodedParams.Length);
os.Close();
}
}
}
}
}
private HttpWebRequest CreateSMSRequest(byte[] encodedParams)
{
HttpWebRequest smsRequest = (HttpWebRequest)WebRequest.Create(PostUrl);
smsRequest.Method = WebRequestMethods.Http.Post;
smsRequest.ContentType = "application/x-www-form-urlencoded";
smsRequest.ContentLength = encodedParams.Length;
smsRequest.AllowAutoRedirect = false;
smsRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
smsRequest.Headers.Add(HttpRequestHeader.Cookie, _cookieData);
return smsRequest;
}
I think your answer is the same as this one:
HttpWebRequest getRequestStream hangs on multiple runs
After your using statement put:
var response = smsRequest.GetResponse() as HttpWebResponse;

Posting score to Facebook app

I've been trawling the answers in SO concerning posting a score to a Facebook app, and I still can't get it to work. The code I'm using is here -
private const string FACEBOOK_POST_SCORE_URL = "https://graph.facebook.com/me/scores?access_token={0}";
public void PostScoreAsync(Action<FacebookResponse> response, FacebookScore score)
{
try
{
// Append the user's access token to the URL
Uri fullUri = new Uri(string.Format(FACEBOOK_POST_SCORE_URL, AccessToken));
string json = JsonConvert.SerializeObject(score);
var request = (HttpWebRequest)WebRequest.Create(fullUri);
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(json);
}
request.BeginGetResponse(WebRequestCallback, new FacebookResult
{
Request = request,
Response = response
});
}
catch (ThreadAbortException)
{
throw;
}
catch (WebException ex)
{
if (response != null)
response(FacebookResponse.NetworkError);
}
catch (Exception ex)
{
if (response != null)
response(FacebookResponse.OtherError);
}
}
We're using webViews rather than iOS / Android Facebook SDKs, as we're building a cross-platform app in Mono.
Obviously I have the access token & the app appears to have full permissions to do what I want to do, which I allowed after login. Any thoughts appreciated!
I eventually found out (from a colleague) that the Facebook graph api won't take json encoded parameters, so we sorted it like so -
string parameters = "score=" + score.Score;
var request = (HttpWebRequest)WebRequest.Create(fullUri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(parameters);
}
Now it works fine - hopefully this'll help someone else not have the same problem.

Why do I receive this error: The remote server returned an error: (417) Expectation Failed

A friend show me this sample code to implement HTTP POST in C# and did work out in a WINFORM App:
http://www.terminally-incoherent.com/blog/2008/05/05/send-a-https-post-request-with-c/
And implemented in a METRO APP:
// this is what we are sending
string post_data = "user=user#example.com&pass=example123";
// this is where we will send it
string uri = "http://app.proceso.com.mx/win8/login";
// create a request
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
// turn our request string into a byte stream
byte[] postBytes = Encoding.UTF8.GetBytes(post_data);
// this is important - make sure you specify type this way
request.ContentType = "application/x-www-form-urlencoded";
Stream requestStream = await request.GetRequestStreamAsync();
// now send it
requestStream.Write(postBytes, 0, postBytes.Length);
// grab te response and print it out to the console along with the status code
WebResponse response = await request.GetResponseAsync();
//var a = new StreamReader(response.GetResponseStream()).ReadToEnd();
StreamReader requestReader = new StreamReader(response.GetResponseStream());
String webResponse = requestReader.ReadToEnd();
I realized, HttpWebRequest does not contain ProtocolVersion and is throwing me this error in this line:
WebResponse response = await request.GetResponseAsync();
// ERROR: The remote server returned an error: (417) Expectation Failed.
I guess the last property is the solution. How can I solve this problem?
Thanks in advance
I recently wrote a small function to handle the posting of trivial data to a server.
private struct HttpPostParam
{
private string _key;
private string _value;
public string Key { get { return HttpUtility.UrlEncode(this._key); } set { this._key = value; } }
public string Value { get { return HttpUtility.UrlEncode(this._value); } set { this._value = value; } }
public HttpPostParam(string key, string value)
{
this._key = key;
this._value = value;
}
};
private static string PostTrivialData(Uri page, HttpPostParam[] parameters)
{
string pageResponse = string.Empty;
try
{
var request = (HttpWebRequest)WebRequest.Create(page); //create the initial request.
request.Method = WebRequestMethods.Http.Post; //set the method
request.AllowAutoRedirect = true; //couple of settings I personally prefer.
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";
//create the post data.
byte[] bData = Encoding.UTF8.GetBytes(string.Join("&", Array.ConvertAll(parameters, kvp => string.Format("{0}={1}", kvp.Key, kvp.Value))));
using (var reqStream = request.GetRequestStream())
reqStream.Write(bData, 0, bData.Length); //write the data to the request.
using (var response = (HttpWebResponse)request.GetResponse()) //attempt to get the response.
if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.NotModified) //check for a valid status (should only return 200 if successful)
using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
pageResponse = reader.ReadToEnd();
}
catch (Exception e)
{
/* todo: any error handling, for my use case failing gracefully was all that was needed. */
}
return pageResponse;
}
Essentially it posts the value pairs defined in the "parameters" argument. Will require a reference and import of the System.Web namespace to compile.
I just tested it with your website and got a response back:
HttpPostParam[] httpparams = {
new HttpPostParam("user", "censored#email.com"),
new HttpPostParam("pass", "example123")
};
string response = PostTrivialData(new Uri("http://app.proceso.com.mx/win8/login"), httpparams);
Let me know if there's any issues.

Google Translate V2 cannot hanlde large text translations from C#

I've implemented C# code using the Google Translation V2 api with the GET Method.
It successfully translates small texts but when increasing the text length and it takes 1,800 characters long ( including URI parameters ) I'm getting the "URI too large" error.
Ok, I burned down all the paths and investigated the issue across multiple pages posted on Internet. All of them clearly says the GET method should be overriden to simulate a POST method ( which is meant to provide support to 5,000 character URIs ) but there is no way to find out a code example to of it.
Does anyone has any example or can provide some information?
[EDIT] Here is the code I'm using:
String apiUrl = "https://www.googleapis.com/language/translate/v2?key={0}&source={1}&target={2}&q={3}";
String url = String.Format(apiUrl, Constants.apiKey, sourceLanguage, targetLanguage, text);
Stream outputStream = null;
byte[] bytes = Encoding.ASCII.GetBytes(url);
// create the http web request
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.KeepAlive = true;
webRequest.Method = "POST";
// Overrride the GET method as documented on Google's docu.
webRequest.Headers.Add("X-HTTP-Method-Override: GET");
webRequest.ContentType = "application/x-www-form-urlencoded";
// send POST
try
{
webRequest.ContentLength = bytes.Length;
outputStream = webRequest.GetRequestStream();
outputStream.Write(bytes, 0, bytes.Length);
outputStream.Close();
}
catch (HttpException e)
{
/*...*/
}
try
{
// get the response
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
if (webResponse.StatusCode == HttpStatusCode.OK && webRequest != null)
{
// read response stream
using (StreamReader sr = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))
{
string lista = sr.ReadToEnd();
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(TranslationRootObject));
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(lista));
TranslationRootObject tRootObject = (TranslationRootObject)serializer.ReadObject(stream);
string previousTranslation = string.Empty;
//deserialize
for (int i = 0; i < tRootObject.Data.Detections.Count; i++)
{
string translatedText = tRootObject.Data.Detections[i].TranslatedText.ToString();
if (i == 0)
{
text = translatedText;
}
else
{
if (!text.Contains(translatedText))
{
text = text + " " + translatedText;
}
}
}
return text;
}
}
}
catch (HttpException e)
{
/*...*/
}
return text;
}
Apparently using WebClient won't work as you cannot alter the headers as needed, per the documentation:
Note: You can also use POST to invoke the API if you want to send more data in a single request. The q parameter in the POST body must be less than 5K characters. To use POST, you must use the X-HTTP-Method-Override header to tell the Translate API to treat the request as a GET (use X-HTTP-Method-Override: GET).
You can use WebRequest, but you'll need to add the X-HTTP-Method-Override header:
var request = WebRequest.Create (uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("X-HTTP-Method-Override", "GET");
var body = new StringBuilder();
body.Append("key=SECRET");
body.AppendFormat("&source={0}", HttpUtility.UrlEncode(source));
body.AppendFormat("&target={0}", HttpUtility.UrlEncode(target));
//--
body.AppendFormat("&q={0}", HttpUtility.UrlEncode(text));
var bytes = Encoding.ASCII.GetBytes(body.ToString());
if (bytes.Length > 5120) throw new ArgumentOutOfRangeException("text");
request.ContentLength = bytes.Length;
using (var output = request.GetRequestStream())
{
output.Write(bytes, 0, bytes.Length);
}
The accepted answer appears to be out of date. You can now use the WebClient (.net 4.5) successfully to POST to the google translate API making sure to set the X-HTTP-Method-Override header.
Here is some code to show you how.
using (var webClient = new WebClient())
{
webClient.Headers.Add("X-HTTP-Method-Override", "GET");
var data = new NameValueCollection()
{
{ "key", GoogleTranslateApiKey },
{ "source", "en" },
{ "target", "fr"},
{ "q", "<p>Hello World</p>" }
};
try
{
var responseBytes = webClient.UploadValues(GoogleTranslateApiUrl, "POST", data);
var json = Encoding.UTF8.GetString(responseBytes);
var result = JsonConvert.DeserializeObject<dynamic>(json);
var translation = result.data.translations[0].translatedText;
}
catch (Exception ex)
{
loggingService.Error(ex.Message);
}
}
? What? it is trivial to post using C# - it is right there in the documentation.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
{
// Set type to POST
request.Method = "POST";
From there on you bascially put the data into fom fields into the content stream.
This is not "simulate a post meethod", it is fully doing a post request as per specifications.
Btw. hwhere does json enter here? You say "in C#". There is no need to use json?

Categories

Resources