protected void UpdateLink()
    {
        if (FlightEntry != null)
        {
            lnkFBAdd.Visible     = FlightEntry.CanPost;
            lnkFBAdd.NavigateUrl = "~/member/FBPost.aspx".ToAbsoluteURL(Request).ToString() + "?id=" + FlightEntry.FlightID.ToString(System.Globalization.CultureInfo.InvariantCulture);

            if (!AddMetaTagHints)
            {
                return;
            }

            // Set facebook meta tags
            string szDescription = FlightEntry.SocialMediaComment;
            AddMeta("og:title", szDescription);
            AddMeta("og:type", "website");
            AddMeta("og:description", szDescription);
            AddMeta("og:url", Request.Url.AbsoluteUri);
            AddMeta("fb:app_id", MFBFacebook.FACEBOOK_API_KEY);

            MyFlightbook.Image.MFBImageInfo mfbii = FlightEntry.SocialMediaImage();
            if (mfbii != null && mfbii.URLFullImage != null && !String.IsNullOrEmpty(mfbii.URLFullImage.ToAbsoluteURL(Request).ToString()))
            {
                bool fVideo = mfbii.ImageType == MyFlightbook.Image.MFBImageInfo.ImageFileType.S3VideoMP4;

                string absolutePath = mfbii.ResolveFullImage();
                if (fVideo)
                {
                    string absoluteThumb = mfbii.UriS3VideoThumbnail.ToString();
                    AddMeta("og:image", absoluteThumb);
                    AddMeta("og:image:secure_url", absoluteThumb);
                    AddMeta("og:video", absolutePath);
                    AddMeta("og:video:secure_url", absolutePath);
                    AddMeta("og:video:type", "video/mp4");
                }
                else
                {
                    AddMeta("og:image", absolutePath);
                    AddMeta("og:image:secure_url", absolutePath);
                    AddMeta("og:image:type", "image/jpeg");
                }

                double ratio = (mfbii.WidthThumbnail == 0) ? 1.0 : ((double)mfbii.HeightThumbnail / (double)mfbii.WidthThumbnail);

                const int nominalDimension = 400;
                int       nominalWidth     = (int)((ratio < 1) ? nominalDimension : nominalDimension / ratio);
                int       nominalHeight    = (int)((ratio < 1) ? nominalDimension * ratio : nominalDimension);
                AddMeta(fVideo ? "og:video:width" : "og:image:width", nominalWidth.ToString(System.Globalization.CultureInfo.InvariantCulture));
                AddMeta(fVideo ? "og:video:height" : "og:image:height", nominalHeight.ToString(System.Globalization.CultureInfo.InvariantCulture));
            }
        }
    }
        public bool PostToSocialMedia(IPostable o, string szUser, string szHost = null)
        {
            if (o == null)
            {
                throw new ArgumentNullException("o");
            }

            if (!o.CanPost)
            {
                return(false);
            }

            if (String.IsNullOrEmpty(szUser))
            {
                throw new ArgumentNullException("szUser");
            }

            if (String.IsNullOrEmpty(szHost))
            {
                szHost = Branding.CurrentBrand.HostName;
            }

            Profile pf = Profile.GetUser(szUser);

            // Check for user not configured
            if (pf.FacebookAccessToken == null || String.IsNullOrEmpty(pf.FacebookAccessToken.AccessToken))
            {
                return(false);
            }

            // NOTE: We need to update the version code below periodically as the API updates
            const string szUrl = "https://graph.facebook.com/v2.10/me/feed";

            MultipartFormDataContent form = new MultipartFormDataContent();

            Uri uriItem = o.SocialMediaItemUri(szHost);

            MyFlightbook.Image.MFBImageInfo img = o.SocialMediaImage(szHost);

            // Add in the main parameters:
            Dictionary <string, string> dictParams = new Dictionary <string, string>()
            {
                { "access_token", pf.FacebookAccessToken.AccessToken },
                { "message", string.Empty }
            };

            if (uriItem != null)
            {
                dictParams.Add("link", uriItem.AbsoluteUri);
            }

            if (img != null)
            {
                dictParams.Add("picture", img.URLFullImage.ToAbsoluteURL("http", Branding.CurrentBrand.HostName).ToString());
            }

            foreach (string key in dictParams.Keys)
            {
                StringContent sc = new StringContent(dictParams[key]);
                sc.Headers.ContentDisposition = (new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
                {
                    Name = key
                });
                sc.Headers.ContentType        = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain")
                {
                    CharSet = "ISO-8859-1"
                };
                form.Add(sc);
            }

            // The remainder can run on a background thread, since we don't do anything that requires a result from here.
            new System.Threading.Thread(() =>
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    try
                    {
                        HttpResponseMessage response = httpClient.PostAsync(new Uri(szUrl), form).Result;
                        string szResult = response.Content.ReadAsStringAsync().Result;

                        if (response.IsSuccessStatusCode)
                        {
                            // do a refresh, to extend as much as possible
                            if (MFBFacebook.ExchangeToken(pf.FacebookAccessToken))
                            {
                                pf.FCommit();
                            }
                        }
                        else
                        {
                            HandleFBFailure(szUser, szResult);
                        }
                    }
                    catch (MyFlightbookException) { }
                    catch (System.ArgumentNullException) { }
                    finally
                    {
                        form.Dispose();
                    }
                }
            }).Start();

            return(true);
        }