You might see that the Dropbox Community team have been busy working on some major updates to the Community itself! So, here is some info on what’s changed, what’s staying the same and what you can expect from the Dropbox Community overall.
Forum Discussion
dhodges351
10 months agoExplorer | Level 4
Integrate Dropbox with .Net Core 6 web application
Dear Community Experts,
I have created a .NET Core 6 web application for my husband's stamp collecting hobby [SNIP] and I would like to display some of his stamp images in the application from his Dropbox folder "Gourmet Philatelist". I went through all the samples in the .NET SDK for Dropbox in my Dropbox Api Test application, but I cannot get it to work in the stamp collecting web application. Here are the results of my attempts:
1. Using PKCEOAuthFlow();
var OAuthFlow = new PKCEOAuthFlow();
var redirect = OAuthFlow.GetAuthorizeUri(OAuthResponseType.Code,
AppKey,
RedirectUri.ToString(),
state: state,
tokenAccessType: TokenAccessType.Offline,
scopeList: scopeList,
includeGrantedScopes: IncludeGrantedScopes.None);
AcquireAccessToken: blows up trying to process the authorizeUri. I have tried registering many, many, different redirect urls using localhost with different ports like (https://localhost:7184/authorize and https://localhost:7184/gallery/auth) in the App center, but I cannot get it to work. (There is a file in the web application "index.html" like in the PKCEOAuthFlow sample). I also have the handler methods in the code.
// var state = Guid.NewGuid().ToString("N");
// var OAuthFlow = new PKCEOAuthFlow();
// var authorizeUri = OAuthFlow.GetAuthorizeUri(OAuthResponseType.Code, AppKey, null, state: state, tokenAccessType: TokenAccessType.Offline, scopeList: scopeList, includeGrantedScopes: includeGrantedScopes);
// var http = new HttpListener();
// http.Prefixes.Add(LoopbackHost);
// http.Start();
// System.Diagnostics.Process.Start(authorizeUri.ToString()); BLOWS UP HERE
// // Handle OAuth redirect and send URL fragment to local server using JS.
// await HandleOAuth2Redirect(http);
// // Handle redirect from JS and process OAuth response.
// var redirectUri = await HandleJSRedirect(http);
// Console.WriteLine("Exchanging code for token");
// var tokenResult = await OAuthFlow.ProcessCodeFlowAsync(redirectUri, AppKey, RedirectUri.ToString(), state);
// Console.WriteLine("Finished Exchanging Code for Token");
2.) Using PKCEOAuthFlow() with /Gallery/Auth redirect Url instead of url fragment in the index.html file.
I do get the AccessToken and the RefreshToken, but when I call dbx.Sharing.CreateSharedLinkWithSettingsAsync using the RefreshToken I get an error saying it is an invalid token.
3.) Tried again using DropboxOAuth2Helper - BLOWS UP HERE: SaveGalleryItem() - await dbx.Sharing.CreateSharedLinkWithSettingsAsync
ERROR: Invalid Grant
private string RedirectUri
{
get
{
var host = _httpContextAccessor.HttpContext.Request.Host;
var port = _httpContextAccessor.HttpContext.Request.Host.Port;
if (host.Host.ToLower(CultureInfo.InvariantCulture) == "localhost")
{
return "https://localhost:7184/Gallery/Auth";
}
var builder = new UriBuilder(
Uri.UriSchemeHttps,
host.Host);
builder.Path = "/Gallery/Auth";
return builder.ToString();
}
}
var state = Guid.NewGuid().ToString("N");
string[] scopeList = new string[4] { "files.metadata.read", "files.content.read", "sharing.read", "sharing.write" };
var redirect = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Code,
AppKey,
RedirectUri,
state: state,
tokenAccessType: TokenAccessType.Offline,
scopeList: scopeList,
includeGrantedScopes: IncludeGrantedScopes.None);
return Redirect(redirect.ToString());
[Authorize]
public async Task<ActionResult> AuthAsync(string code, string state)
{
try
{
var response = await DropboxOAuth2Helper.ProcessCodeFlowAsync(
code,
AppKey,
AppSecret,
RedirectUri);
TempData["AuthToken"] = response.AccessToken;
TempData["TokenExpires"] = response.ExpiresAt;
TempData["RefreshToken"] = response.RefreshToken;
_refreshToken = response.RefreshToken;
string? refUrl = TempData["Referrer"]?.ToString();
string? galleryItemId = TempData["GalleryItemId"]?.ToString();
if (!string.IsNullOrEmpty(refUrl) && refUrl.Contains("Add"))
{
return RedirectToAction("AddGalleryItem", "Gallery");
}
else if (!string.IsNullOrEmpty(refUrl) && refUrl.Contains("Edit"))
{
return RedirectToAction("EditGalleryItem", "Gallery", new { galleryItemId = galleryItemId });
}
return RedirectToAction("Index", "Home");
}
catch (Exception e)
{
var message = e.Message;
return RedirectToAction("Index");
}
}
SaveGalleryItem() - blows up on this call: await dbx.Sharing.CreateSharedLinkWithSettingsAsync
error: Invalid Grant
if (TempData != null && TempData.ContainsKey("RefreshToken"))
{
refreshToken = TempData["RefreshToken"]?.ToString();
}
using (var dbx = new DropboxClient(refreshToken))
{
var sharedLinkUrl = string.Empty;
var sharedLink = await dbx.Sharing.CreateSharedLinkWithSettingsAsync($"/Gourmet Philatelist/{ItemUrl}");
//(ItemUrl is the file name in the Dropbox folder).
if (sharedLink != null)
{
sharedLinkUrl = sharedLink.Url;
model.ImageUrl = sharedLinkUrl.Replace("dl=0", "raw=1");
}
}
I have been trying to do this for 3 days now with no success. I emailed Dropbox Support and they told me to try to find help in the Dropbox Community. Any help you can provide is greatly appreciated. Thank you.
Best Regards,
Debra Hodges for Bob Hodges Dropbox
From the code you shared, it looks like you're working from the OAuthPKCE example included with the .NET SDK. That's meant as an example of a client-side application though. Since you're building a server-side web app, the SimpleBlogDemo example would be more relevant.
I suggest running that SimpleBlogDemo example as provided first to see how that works. There's setup instructions here, but I suggest not otherwise modifying that code to make sure that example runs successfully for you. Once you have that working as an example, use that as a reference for building your web app.
If either the example or your app aren't working, please print out and share the exact/entire error output and the corresponding piece of code.
- Greg-DBDropbox Staff
From the code you shared, it looks like you're working from the OAuthPKCE example included with the .NET SDK. That's meant as an example of a client-side application though. Since you're building a server-side web app, the SimpleBlogDemo example would be more relevant.
I suggest running that SimpleBlogDemo example as provided first to see how that works. There's setup instructions here, but I suggest not otherwise modifying that code to make sure that example runs successfully for you. Once you have that working as an example, use that as a reference for building your web app.
If either the example or your app aren't working, please print out and share the exact/entire error output and the corresponding piece of code.
- dhodges351Explorer | Level 4
Greg - Thank you so much for answering my post and for the great tips you gave for how to get my .NET Core 6 web application to work with Dropbox client. I finally accomplished it by using the SimpleBlogDemo example as you suggested. I added a Dropbox Chooser control and some code to check the expiration date of the online token and regenerate the token if it was expired. Below is the code which worked that created shared urls for displaying Dropbox images in the views.
_GalleryLayout:
<script>
var options = {// Required. Called when a user selects an item in the Chooser.
success: function(files) {
//console.log("Here's the file link: " + files[0].link)
//console.log("Here's the file name: " + files[0].name)
$("#ItemUrl").val(files[0].name);
},Add/Edit Views -
<div style="display:none;">
<input id="ItemUrl" name="ItemUrl">
@Html.ActionLink(
linkText: "Connect",
actionName: "Connect",
routeValues: new { referrer = "Add", galleryItemId = 0 },
htmlAttributes: new { ID="btnConnect", Class = "btn btn-lg btn-primary" })
</div>IF (!TempData.ContainsKey("TokenOk"))
{
<script type="text/javascript">
document.getElementById("btnConnect").click();
</script>
}Gallery Controller -
public IActionResult Connect(string referrer, string galleryItemId)
{
TempData["Referrer"] = referrer;
TempData["GalleryItemId"] = galleryItemId;
Uri redirect = null;string? authToken = TempData["AuthToken"]?.ToString();
if (!TempData.ContainsKey("AuthToken") || string.IsNullOrEmpty(authToken))
{
redirect = GetDropboxAuthUrl();return Redirect(redirect.ToString());
}if (TempData.ContainsKey("TokenExpires"))
{
string? tokenExpires = TempData["TokenExpires"]?.ToString();
CultureInfo culture = new CultureInfo("en-US");
DateTime? tempDate = Convert.ToDateTime(tokenExpires, culture);
if (!tempDate.HasValue || tempDate.HasValue && DateTime.Now > tempDate)
{
redirect = GetDropboxAuthUrl();return Redirect(redirect.ToString());
}
}TempData["TokenOk"] = true;
TempData.Keep("TokenOk");if (referrer == "Add")
{
return RedirectToAction("AddGalleryItem", "Gallery");
}
else
{
return RedirectToAction("EditGalleryItem", "Gallery", new { galleryItemId = galleryItemId});
}
}public Uri GetDropboxAuthUrl()
{
var state = Guid.NewGuid().ToString("N");
string[] scopeList = new string[4] { "files.metadata.read", "files.content.read", "sharing.read", "sharing.write" };var redirect = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Code,
AppKey,
RedirectUri,
state: state,
tokenAccessType: TokenAccessType.Online,
scopeList: scopeList,
includeGrantedScopes: IncludeGrantedScopes.None);return redirect;
}[Authorize]
public async Task<ActionResult> AuthAsync(string code, string state)
{
try
{
var response = await DropboxOAuth2Helper.ProcessCodeFlowAsync(
code,
AppKey,
AppSecret,
RedirectUri);TempData["AuthToken"] = response.AccessToken;
TempData["TokenExpires"] = response.ExpiresAt;string? refUrl = TempData["Referrer"]?.ToString();
string? galleryItemId = TempData["GalleryItemId"]?.ToString();if (!string.IsNullOrEmpty(refUrl) && refUrl.Contains("Add"))
{
return RedirectToAction("AddGalleryItem", "Gallery");
}
else if (!string.IsNullOrEmpty(refUrl) && refUrl.Contains("Edit"))
{
return RedirectToAction("EditGalleryItem", "Gallery", new { galleryItemId = galleryItemId });
}return RedirectToAction("Index", "Home");
}
catch (Exception e)
{
var message = e.Message;
return RedirectToAction("Index");
}
}SaveGalleryItem method
[Authorize]
[HttpPost]
public async Task<IActionResult> SaveGalleryItem(GalleryItemModel model)
{
if (TempData.ContainsKey("Referrer") && TempData["Referrer"].ToString().Contains("Add"))
{
model.GalleryItemSequenceId = model.GetLastGalleryItemSequenceId(_galleryItemService, model.CategoryId) + 1;
if (model.GalleryItemSequenceId == 0)
{
model.GalleryItemSequenceId = 1;
}
}if (Upload != null)
{
if (User.Identity.IsAuthenticated)
{
var fileName = Upload.FileName;var file = Path.Combine(_environment.WebRootPath, "assets\\images", Upload.FileName);
using var fileStream = new FileStream(file, FileMode.Create);
await Upload.CopyToAsync(fileStream);
if (model.CategoryId == 4)
{
if (!string.IsNullOrEmpty(model.ImageUrl))
{
model.ImageUrl += ",assets/images/" + fileName;
}
else
{
model.ImageUrl = "assets/images/" + fileName;
}
}
else
{
model.ImageUrl = "assets/images/" + fileName;
}
}
}
else
{
if (!string.IsNullOrEmpty(ItemUrl))
{
model.ImageUrl = ItemUrl;
}
}if (User.Identity.IsAuthenticated)
{
var authToken = string.Empty;if (TempData != null && TempData.ContainsKey("AuthToken"))
{
authToken = TempData["AuthToken"]?.ToString();
}if (!string.IsNullOrEmpty(authToken) && !string.IsNullOrEmpty(ItemUrl) && !ItemUrl.Contains("https"))
{
using (var dbx = new DropboxClient(authToken))
{
var sharedLinkUrl = string.Empty;
var sharedLink = await dbx.Sharing.CreateSharedLinkAsync($"/Gourmet Philatelist/{ItemUrl}");
if (sharedLink != null)
{
sharedLinkUrl = sharedLink.Url;
model.ImageUrl = sharedLinkUrl.Replace("dl=0", "raw=1");
}
}
}
await model.AddUpdateGalleryItem(_galleryItemService, _categoryItemService, model);
}if (TempData != null && TempData.ContainsKey("TokenOk"))
{
TempData.Remove("TokenOk");
}
return RedirectToAction("ManageGalleryItems", "Gallery");
}
About Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.
5,888 PostsLatest Activity: 19 hours agoIf you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X or Facebook.
For more info on available support options for your Dropbox plan, see this article.
If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!