/// <summary> /// Gets the logout url. /// </summary> /// <param name="parameters"> /// The parameters. /// </param> /// <returns> /// Returns the logout url. /// </returns> public Uri GetLogoutUrl(IDictionary <string, object> parameters) { // more information on this at http://stackoverflow.com/questions/2764436/facebook-oauth-logout var uriBuilder = new UriBuilder("http://m.facebook.com/logout.php"); var defaultParams = new Dictionary <string, object>(); defaultParams["confirm"] = 1; defaultParams["next"] = RedirectUri ?? new Uri("http://www.facebook.com"); var mergedParameters = FacebookUtils.Merge(defaultParams, parameters); if (mergedParameters["next"] == null) { mergedParameters.Remove("next"); } else { mergedParameters["next"] = mergedParameters["next"].ToString(); } uriBuilder.Query = FacebookUtils.ToJsonQueryString(mergedParameters); return(uriBuilder.Uri); }
/// <summary> /// Gets the login uri. /// </summary> /// <param name="parameters"> /// The parameters. /// </param> /// <returns> /// Returns the facebook login uri. /// </returns> /// <remarks> /// http://developers.facebook.com/docs/reference/dialogs/oauth /// Parameters that can be used: /// client_id : Your application's identifier. This is called client_id instead of app_id for this particular method to be compliant with the OAuth 2.0 specification. Required, but automatically specified by most SDKs. /// redirect_uri : The URL to redirect to after the user clicks a button on the dialog. Required, but automatically specified by most SDKs. /// scope : Optional. A comma-delimited list of permissions. /// state : Optional. An opaque string used to maintain application state between the request and callback. When Facebook redirects the user back to your redirect_uri, this value will be included unchanged in the response. /// response_type : Optional, default is token. The requested response: an access token (token), an authorization code (code), or both (code_and_token). /// display : The display mode in which to render the dialog. The default is page on the www subdomain and wap on the m subdomain. This is automatically specified by most SDKs. (For WP7 builds it is set to touch.) /// </remarks> public Uri GetLoginUrl(IDictionary <string, object> parameters) { Contract.Ensures(Contract.Result <Uri>() != null); var defaultParameters = new Dictionary <string, object>(); defaultParameters["client_id"] = AppId; defaultParameters["redirect_uri"] = RedirectUri ?? new Uri("http://www.facebook.com/connect/login_success.html"); #if WINDOWS_PHONE defaultParameters["display"] = "touch"; #endif var mergedParameters = FacebookUtils.Merge(defaultParameters, parameters); // check if client_id and redirect_uri is not null or empty. if (mergedParameters["client_id"] == null || string.IsNullOrEmpty(mergedParameters["client_id"].ToString())) { throw new ArgumentException("client_id required."); } if (mergedParameters["redirect_uri"] == null || string.IsNullOrEmpty(mergedParameters["redirect_uri"].ToString())) { throw new ArgumentException("redirect_uri required."); } // seems like if we don't do this and rather pass the original uri object, // it seems to have http://localhost:80/csharpsamples instead of // http://localhost/csharpsamples // notice the port number, that shouldn't be there. // this seems to happen for iis hosted apps. mergedParameters["redirect_uri"] = mergedParameters["redirect_uri"].ToString(); var url = "http://www.facebook.com/dialog/oauth/?" + FacebookUtils.ToJsonQueryString(mergedParameters); return(new Uri(url)); }
/// <summary> /// Builds the request post data and request uri based on the given parameters. /// </summary> /// <param name="uri"> /// The request uri. /// </param> /// <param name="parameters"> /// The request parameters. /// </param> /// <param name="httpMethod"> /// The http method. /// </param> /// <param name="requestUrl"> /// The outputted request uri. /// </param> /// <param name="contentType"> /// The request content type. /// </param> /// <returns> /// The request post data. /// </returns> internal static byte[] BuildRequestData(Uri uri, IDictionary <string, object> parameters, HttpMethod httpMethod, out Uri requestUrl, out string contentType) { Contract.Requires(uri != null); Contract.Requires(parameters != null); var requestUrlBuilder = new UriBuilder(uri); // Set the default content type contentType = "application/x-www-form-urlencoded"; byte[] postData = null; string queryString = string.Empty; if (httpMethod == HttpMethod.Get) { queryString = FacebookUtils.ToJsonQueryString(parameters); } else { if (parameters.ContainsKey("access_token")) { queryString = string.Concat("access_token=", parameters["access_token"]); parameters.Remove("access_token"); } else if (parameters.ContainsKey("oauth_token")) { queryString = string.Concat("oauth_token=", parameters["oauth_token"]); parameters.Remove("oauth_token"); } var containsMediaObject = parameters.Where(p => p.Value is FacebookMediaObject).Count() > 0; if (containsMediaObject) { string boundary = DateTime.Now.Ticks.ToString("x", CultureInfo.InvariantCulture); postData = BuildMediaObjectPostData(parameters, boundary); contentType = String.Concat("multipart/form-data; boundary=", boundary); } else { postData = Encoding.UTF8.GetBytes(FacebookUtils.ToJsonQueryString(parameters)); } } requestUrlBuilder.Query = queryString; requestUrl = requestUrlBuilder.Uri; return(postData); }
/// <summary> /// Gets the login url. /// </summary> /// <param name="parameters"> /// The parameters. /// </param> /// <returns> /// Returns the Facebook login url. /// </returns> /// <remarks> /// http://developers.facebook.com/docs/reference/dialogs/oauth /// Parameters that can be used: /// client_id : Your application's identifier. This is called client_id instead of app_id for this particular method to be compliant with the OAuth 2.0 specification. Required, but automatically specified by most SDKs. /// redirect_uri : The URL to redirect to after the user clicks a button on the dialog. Required, but automatically specified by most SDKs. /// scope : Optional. A comma-delimited list of permissions. /// state : Optional. An opaque string used to maintain application state between the request and callback. When Facebook redirects the user back to your redirect_uri, this value will be included unchanged in the response. /// response_type : Optional, default is token. The requested response: an access token (token), an authorization code (code), or both (code token). /// display : The display mode in which to render the dialog. The default is page on the www subdomain and wap on the m subdomain. This is automatically specified by most SDKs. (For WP7 builds it is set to touch.) /// </remarks> public virtual Uri GetLoginUrl(IDictionary <string, object> parameters) { var defaultParameters = new Dictionary <string, object>(); defaultParameters["client_id"] = AppId; defaultParameters["redirect_uri"] = RedirectUri ?? new Uri("http://www.facebook.com/connect/login_success.html"); #if WINDOWS_PHONE defaultParameters["display"] = "touch"; #endif var mergedParameters = FacebookUtils.Merge(defaultParameters, parameters); // check if client_id and redirect_uri is not null or empty. if (mergedParameters["client_id"] == null || string.IsNullOrEmpty(mergedParameters["client_id"].ToString())) { throw new ArgumentException("client_id required."); } if (mergedParameters["redirect_uri"] == null || string.IsNullOrEmpty(mergedParameters["redirect_uri"].ToString())) { throw new ArgumentException("redirect_uri required."); } // seems like if we don't do this and rather pass the original uri object, // it seems to have http://localhost:80/csharpsamples instead of // http://localhost/csharpsamples // notice the port number, that shouldn't be there. // this seems to happen for iis hosted apps. mergedParameters["redirect_uri"] = mergedParameters["redirect_uri"].ToString(); var url = "http://www.facebook.com/dialog/oauth/?" + FacebookUtils.ToJsonQueryString(mergedParameters); // In order to be compliant with the OAuth spec Facebook have made changes to their auth APIs. // As part of this update, they will be deprecating 'code_and_token' and need developers // to use 'code%20token'. Everything is identical, just replace '_and_' with encoded // <space> '%20'. // url = url.Replace("response_type=code+token", "response_type=code%20token"); return(new Uri(url)); }
/// <summary> /// Converts the facebook batch to POST parameters. /// </summary> /// <param name="batchParameter"> /// The batch parameter. /// </param> /// <returns> /// The post parameters. /// </returns> protected IDictionary <string, object> ToParameters(FacebookBatchParameter batchParameter) { Contract.Requires(batchParameter != null); Contract.Ensures(Contract.Result <IDictionary <string, object> >() != null); IDictionary <string, object> returnResult = null; var defaultParameters = new Dictionary <string, object>(); defaultParameters["method"] = FacebookUtils.ConvertToString(batchParameter.HttpMethod); IDictionary <string, object> parameters = null; if (batchParameter.Parameters == null) { parameters = new Dictionary <string, object>(); } else { if (batchParameter.Parameters is IDictionary <string, object> ) { parameters = (IDictionary <string, object>)batchParameter.Parameters; } else { parameters = FacebookUtils.ToDictionary(batchParameter.Parameters); } } var path = FacebookUtils.ParseQueryParametersToDictionary(batchParameter.Path, parameters); string queryString = string.Empty; if (batchParameter.HttpMethod == HttpMethod.Get) { queryString = FacebookUtils.ToJsonQueryString(parameters); } else { defaultParameters["body"] = FacebookUtils.ToJsonQueryString(parameters); } var relativeUrl = new StringBuilder(path); if (!string.IsNullOrEmpty(queryString)) { relativeUrl.AppendFormat("?{0}", queryString); } defaultParameters["relative_url"] = relativeUrl.ToString(); var data = batchParameter.Data; if (data == null) { returnResult = defaultParameters; } else { if (!(data is IDictionary <string, object>)) { data = FacebookUtils.ToDictionary(batchParameter.Data); } returnResult = FacebookUtils.Merge(defaultParameters, (IDictionary <string, object>)data); } return(returnResult); }