public virtual Uri GetLoginUrl(IDictionary<string, object> parameters) { var defaultParameters = new Dictionary<string, object>(); defaultParameters["client_id"] = ClientId; defaultParameters["redirect_uri"] = RedirectUri; var mergedParameters = FluentHttpRequest.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 ArgumentNullException("parameters", "client_id requried."); if (mergedParameters["redirect_uri"] == null || string.IsNullOrEmpty(mergedParameters["redirect_uri"].ToString())) throw new ArgumentNullException("parameters", "redirect_uri requried."); // seems like if we don't do this and rather pass the original uri object, // it seems to have http://localhost:80/ instead of // http://localhost/ // 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 request = new FluentHttpRequest() .BaseUrl("https://github.com/login/oauth/authorize") .QueryStrings(qs => qs.Add(mergedParameters)); return new Uri(request.BuildRequestUrl()); }