Closed HeidiCJ closed 12 years ago
FacebookMediaObject is recommended only for small files because it loads the entire file as byte[]
.
Can you try using FacebookMediaStream
which was introduced in v6. You can learn how to use it at http://csharpsdk.org/docs/making-synchronous-requests.html I would also recommend to use the PostAsync
or PostTaskAsync
rather then Post
.
Hi and many thanks for your prompt response.
I have modified my code to use the FacebookMediaStream as suggested. PostAsync doesn't appear to exist and I can't use the PostTaskAsync method as it appears to require the "await" command and this was only intrduced in .Net 4.5. I'm using Visual Studio 2010 Premium with .Net 4.0. (please see my modified code at the end of this post)
My code is still failing in the same place:
dynamic result = fb.Post("/me/videos", parameters);
...and is generating the same error:
"System.Net.WebException: The request was aborted: The request was canceled. ---> System.IO.IOException: Cannot close stream until all bytes are written."
Do you have any other suggestions?
Thanks, Heidi
public void PostAVideo(string Token)
{
FacebookClient fb = new FacebookClient(Token);
string VideoFile = @"C:\Videos\Wildlife.wmv";
dynamic parameters = new ExpandoObject();
FacebookMediaStream fbms = new FacebookMediaStream
{
ContentType = "video/wmv",
FileName = System.IO.Path.GetFileName(VideoFile)
};
fbms.SetValue(System.IO.File.OpenRead(VideoFile));
//Set the parameters:
parameters.source = fbms;
parameters.title = "Wildlife Video";
parameters.description = "What a lovely video";
parameters.method = "video.upload";
//Post the video - This will be posted into the apps sub folder
dynamic result = fb.Post("/me/videos", parameters);
}
PostAsync is available but hidden from the intellisense.
You don't need .net 4.5 to use TPL. It returns Task<object>
, so use ContinueWith.
fb.PostTaskAsync("me/videos", parameters)
.ContinueWith(t=> Console.WriteLine(t.Result.ToString());
Here is a full sample code on using TPL with Facebook C# SDK. http://blog.prabir.me/post/Facebook-CSharp-SDK-and-Silverlight-5.aspx
and also please format your code before posting.
press m
to see the markdown cheetsheet.
Hi again,
I implemented the PostTaskAsync call using ContinueWith to call a method that runs when the task has finished (see code sample at the end of this post) and it works a treat. Takes a while to upload (took 30 mins for a 25MB video) but it does work. Many thanks for your help.
I have just one more question. When a task is completed, I need to update my database to say if it was successful or if it there was an error, so when the ContinueWith method is called, I need to be able to identify the post that called it.
Is the a parameter I can set on the dynamic parameters object that gets passed to the PostTaskAsync() call that will then get returned when the task has finished?
Hope this makes sense.
Regards, Heidi
public void PostAVideo(string Token)
{
FacebookClient fb = new FacebookClient(Token);
string VideoFile = @"C:\Videos\Wildlife.wmv";
dynamic parameters = new ExpandoObject();
//Create and configure the media stream object
FacebookMediaStream fbms = new FacebookMediaStream
{
FileName = Path.GetFileName(VideoFile),
ContentType = String.Format("video/{0}",Path.GetExtension(VideoFile))
};
fbms.SetValue(File.OpenRead(VideoFile));
//Set the parameters:
parameters.source = fbms;
parameters.title = String.Format("{0} My Video", DateTime.Now.ToString());
parameters.description = String.Format("{0} What a lovely video", DateTime.Now.ToString());
parameters.method = "video.upload";
//make an async post and manage the task it returns
Action<object> action = RunCompletedAction;
var task = fb.PostTaskAsync("/me/videos", parameters);
task.ContinueWith(action); //This will cause the RunCompletedAction mthod to run
}
private void RunCompletedAction(object data)
{
dynamic d = data;
if (d.Result != null)
Console.WriteLine(d.Result.ToString());
}
XTaskAsync methods returns Task<object>
so you can continue to use the normal TPL stuffs, I would recommend you to read the TPL docs.
task.ContinueWith(t => {
if(t.IsCancelled) {
// cancelled
} else if (t.IsFaulted) {
// exception occurred
t.Wait(); // propagate the exception to the caller.
} else {
dynamic result = t.Result;
var id = result.id;
}
});
OK, thanks for the advice. I'm going to go and have a propper read of the TPL and Lambda docs. I have tried your previous TPL samples but every time I do I get this error:
Error 120 Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type.
Always on this part of the code (I get a red squiggle under the t):
t =>
Any idea why?
Hi,
Do you have a working example of the PostTaskAsync.ContinueWith using a lambda expression ? (as per your last post)
I've tried all the examples you've provided and I just can't get it working. My last attempt uses a delegate but I'm still having no joy. I've searched the internet and can't find any working examples. It's really holding me up now.
Thanks in advance, Heidi
var fb = new FacebookClient("access_token");
var file = new FacebookMediaStream
{
ContentType = "video/x-ms-wmv",
FileName = "Wildlife.wmv"
}.SetValue(new FileStream(@"C:\Users\Public\Videos\Sample Videos\Wildlife.wmv", FileMode.Open, FileAccess.Read));
fb
.PostTaskAsync("me/videos", new { file, title = "video upload", description = "desc" })
.ContinueWith(t =>
{
// make sure to manually dispose the stream correctly.
file.Dispose();
if (t.IsCanceled)
{
// handle cancelled
}
else if (t.IsFaulted)
{
t.Wait(); // propagate exceptions to the caller
}
else
{
dynamic result = t.Result;
var id = result.id;
// make sure to update in the right thread
Console.WriteLine(id.ToString());
}
});
does it work before I close this issue?
Hi,
I don't work weekends so I haven't tried it yet. I'll check this morning and let you know.
Regards, Heidi
Hi,
Thanks so much for your help Prabir, it works a treat!
Regards, Heidi
Just wanted to say I think I know what the problem was.
This line works perfectly...
.PostTaskAsync("me/videos", new { file, title = "video upload", description = "desc" })
This line gives me an error...
.PostTaskAsync("me/videos", parameters)
The above line gives me the lambda error (below) and a red squiggly underline under "t =>"
Error 120 Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type.
The lambda expression in the ContinueWith call clearly doesn't like the use of a dynamic parameter.
Regards, Heidi
That is one of the limitations of c#, dynamic does not work with lambdas. If you parameter is dynamic cast it to object.
PostTaskAsync("me/videos", (object)parameters);
Hi,
I’m writing a windows app in Visual Studio 2010 Premium using the Facebook C# SDK ver 6.0.10.0. My OS is Windows 7 Ultimate. I have used the sample code for uploading a video and the token I’m using has publish_stream permission.
My code (which I’ve included below) works fine for very short videos; however, it fails for larger ones. When it fails, it takes it’s time on the following line of code:
…and finally it generates the following exception:
It’s not a Facebook exception, it’s raised by the call to the SDK Post method. Is there some kind of configurable limit in the C# SDK that restricts the size of the file being uploaded? The file I’m uploading is a “wmv” file, 25MB and runs for 30 seconds. I have checked the Facebook documentation here (http://developers.facebook.com/docs/reference/api/video/) and there should be no problems uploading this file.
Can you please help?
Regards, Heidi