Before continuing please familiarize yourself with the API and it's methodology at https://api.sharefile.com/rest
If you would like to download the Nuget Package for this SDK, you can find it here https://www.nuget.org/packages/ShareFile.Api.Client/
All code is licensed under the MIT License.
ShareFile.Api.Client.DotNet.sln
requires Visual Studio 2017 with .NET Core tooling.applicationControlPlane
- Describes the domain that the ShareFile account is available on.sharefile.com
, securevdr.com
, sharefile.eu
, etc.authorizationUrl
- The initial url that should be visited to being web authentication.client_id
- The identifier that is uniquely identifies an OAuth client consumer.client_secret
- This is a shared secret that is required to exchange an OAuthAuthorizationCode
for an OAuthToken
.completionUri
- Alias for redirectUri
. Used primarily in OAuth2AuthenticationHelper
.OAuthAuthorizationCode
- One-time use code that is returned as part of an oauth code
grant request.OAuthToken
- Used to authenticate with ShareFile, specifically using AccessToken - however, this is taken care of for you by the SDK.redirectUri
- Resource that can be used to track when authentication is complete. Generally, this resource is controlled by the OAuth client consumer.state
- Token created by the OAuth consumer to associate an authorization request
with an authorization response.Authentication with ShareFile v3 API makes use of OAuth 2.0 protocol. Some helper methods and classes are provided to make authentication easier for consumers.
Web Authentication
var redirectUri = new Uri("https://secure.sharefile.com/oauth/oauthcomplete.aspx");
// Recommended this value is held on to to verify the authentication response.
var state = Guid.NewGuid().ToString();
var sfClient = new ShareFileClient("https://secure.sf-api.com/sf/v3/");
var oauthService = new OAuthService(sfClient, "[client_id]", "[client_secret]");
var authorizationUrl = oauthService.GetAuthorizationUrl("sharefile.com", "code", "clientId", redirectUri.ToString(),
state);
Open up a web browser control and use authorizationUrl
to load the browser. To assist in tracking when authentication has completed,
create an instance of OAuth2AuthenticationHelper
using redirectUri
as the completionUri
in OAuth2AuthenticationHelper.ctor()
.
var authenticationHelper = new OAuth2AuthenticationHelper(redirectUri);
In the the event raised by your browser control instance for Navigation occurring, check the Uri
that is being loaded.
WebBrowser.Navigating += (sender, args) =>
{
IOAuthResponse oauthResponse;
if (authenticationHelper.IsComplete(args.Uri, out oauthResponse))
{
if (oauthResponse is OAuthError)
{
// handle error
}
if (oauthResponse is OAuthAuthorizationCode)
{
// exchange authorization code for OAuthToken
}
}
};
To exchange an OAuthAuthorizationCode
for an OAuthToken
:
var oauthToken = await oauthService.
ExchangeAuthorizationCodeAsync(oauthAuthorizationCodeInstance);
sfClient.AddOAuthCredentials(oauthToken);
sfClient.BaseUri = oauthToken.GetUri();
Note - If you use your own mechanism for tracking when authentication
is complete (based on redirectUri), it is still advisable to use OAuth2AuthenticationHelper
to translate the Uri
to IOAuthResponse
Password Authentication: Requires the consumer perform ShareFile account discovery,
which is not currently documented. In order to complete this authentication
the consumer will must know username
, password
, subdomain
, and applicationControlPlane
. In the sample below,
these are assumed to have been obtained already.
var sfClient = new ShareFileClient("https://secure.sf-api.com/sf/v3/");
var oauthService = new OAuthService(sfClient, "[clientid]", "[clientSecret]");
var oauthToken = await oauthService.PasswordGrantAsync(username,
password, subdomain, applicationControlPlane);
sfClient.AddOAuthCredentials(oauthToken);
sfClient.BaseUri = oauthToken.GetUri();
SAML Authentication: This authentication support assumes you have a mechanism
for obtaining a SAML assertion, samlAssertion
from the user's IdP.
var sfClient = new ShareFileClient("https://secure.sf-api.com/sf/v3/");
var oauthService = new OAuthService(sfClient, "[clientid]", "[clientSecret]");
var oauthToken = await oauthService.ExchangeSamlAssertionAsync(samlAssertion,
subdomain, applicationControlPlane);
sfClient.AddOAuthCredentials(oauthToken);
sfClient.BaseUri = oauthToken.GetUri();
Refreshing an OAuthToken: Any OAuthToken
that is obtained using a code
grant type can be refreshed. This allows a consumer to silently reauthenticate
with the ShareFile API without needing to prompt the user. This is useful if
you plan on caching the OAuthToken
. The sample below assumes you have already
pulled an instance of OAuthToken
as cachedOAuthToken
from some local cache.
var sfClient = new ShareFileClient(cachedOAuthToken.GetUri());
var oauthService = new OAuthService(sfClient, "[clientid]", "[clientSecret]");
var oauthToken = await oauthService.RefreshOAuthTokenAsync(samlAssertion,
subdomain, applicationControlPlane);
sfClient.AddOAuthCredentials(oauthToken);
sfClient.BaseUri = oauthToken.GetUri();
Once authenticated, getting information from ShareFile is pretty easy.
Below are some samples on what you can do, it assumes there is an instance of
ShareFileClient - sfClient
available.
var session = await sfClient.Session.Login().ExecuteAsync();
var session = await sfClient.Session.Logout().ExecuteAsync();
// Should clean up credentials and cookies if you plan to
// re-use the sfClient instance.
sfClient.ClearCredentialsAndCookies();
A User in ShareFile derives from the Principal
object. For most consumers you
will be interested in User
and AccountUser
. The AccountUser
type designates
the user to be an Employee and will have some additional properties available.
You can also use User.IsEmployee()
, to get the additional properties you will
still need to cast the instance to AccountUser
var user = await sfClient.Users.Get().ExecuteAsync();
This call will return the default folder for the currently authenticated User
.
var folder = (Folder) await sfClient.Items.Get().ExecuteAsync();
var folderContents = await sfClient.Items.GetChildren(folder.url).ExecuteAsync();
// will have the contents an ODataFeed<Item>
// the Feed property will be a List<Item>
// operate over the feed
folderContents.Feed
var parentFolder = (Folder) await sfClient.Items.Get().ExecuteAsync();
var newFolder = new Folder
{
Name = "New Folder 1"
};
newFolder = await sfClient.Items.CreateFolder(parentFolder.url, newFolder).ExecuteAsync();
var searchResults = await sfClient.Items.Search("query").ExecuteAsync();
To browse search results (currently, there is no Uri
returned that points to the Item
):
var itemUri = sfClient.Items.GetAlias(searchResult.ItemID);
var item = await sfClient.Items.Get(itemUri).ExecuteAsync();
There are some folders within ShareFile that are not easily discovered, however
the SDK can help you find them. These aliases are exposed on an enum ItemAlias
.
var itemUri = sfClient.Items.GetAlias(ItemAlias.Top);
var item = await sfClient.Items.Get(itemUri).ExecuteAsync();
var downloader = sfClient.GetAsyncFileDownloader(itemToDownload);
using(var fileStream = File.Open(@"C:\test\newImage.png", FileMode.OpenOrCreate))
{
await downloader.DownloadToAsync(fileStream);
}
var parentFolder = (Folder) await sfClient.Items.Get().ExecuteAsync();
using(var file = File.Open(@"C:\test\image.png", FileMode.OpenOrCreate))
{
var uploadRequest = new UploadSpecificationRequest
{
FileName = file.Name,
FileSize = file.Length,
Details = "Sample details",
Parent = parentFolder.url
};
var uploader = sfClient.GetAsyncFileUploader(uploadRequest, file);
var uploadResponse = await uploader.UploadAsync();
}
ShareFile supports a concept called Shares
which are labeled as Request
and Send
.
If you have a Request Share
, you can fulfill the request by uploading directly
to it via the SDK.
// Assumes you have a Share object or at least a Uri to a Share
using(var file = File.Open(@"C:\test\image.png", FileMode.OpenOrCreate))
{
var uploadRequest = new UploadSpecificationRequest
{
FileName = file.Name,
FileSize = file.Length,
Details = "Sample details",
Parent = shareUri
};
var uploader = sfClient.GetAsyncFileUploader(uploadRequest, file);
var uploadResponse = await uploader.UploadAsync();
}
On any transfer you can be notified of progress. On the instance of the uploader/downloader
you can provide a delegate to OnTransferProgress
.
await sfClient.Items.Delete(file.url).ExecuteAsync();
await sfClient.Items.Delete(folder.url).ExecuteAsync();
StreamId
instead of Id
which is the default identifier used in url
Uri
using ShareFile.Client.Core.Extensions;
...
// Uses the StreamId
await sfClient.Items.Delete(file.GetObjectUri(true)).ExecuteAsync();
Assuming you have the url that points to the Share API resource (ex. https://subdomain.sharefile.com/sf/v3/Shares(s0123456789)
), you can easily access the Items
shared. Depending on the share you may be required to already be authenticated.
var shareUri = new Uri("https://subdomain.sharefile.com/sf/v3/Shares(s0123456789)");
var share = await sfClient.Shares.Get(shareUri);
var shareItems = await sfClient.Shares.GetItems(shareUri, share.AliasID);
Items associated with a Share
cannot be downloaded as you normally might, instead you need to use the Shares
API to download.
// assuming you already have shareItems as noted before
var fileStream = await sfClient.Shares.Download(shareUri, share.AliasID, shareItems.Select(x => x.Id).First());
ShareFile supports the oData protocol which provides standard ways of handling common tasks such as:
Folder.Children
The following Query
will only select the Name property. If you execute this,
all other properties will be their default values. This is convenient for
reducing payloads on the wire.
var folder = (Folder) await sfClient.Items.Get()
.Select("Name")
.ExecuteAsync();
The following Query
will expand Children
. Since we know we are querying for
a Folder
we can ask ShareFile to go ahead and return the list of Children. This
helps reduce the number of round trips required. Note Chlidren
is presented
as a List<Item>
instead of an ODataFeed<Item>
.
var folder = (Folder) await sfClient.Items.Get()
.Expand("Children")
.ExecuteAsync();
// Is now populated.
folder.Children
When working with ODataFeed
responses, you can limit the size of the response
by using Top
and Skip
. The following Query
will return up to 10 Children
and skip the first 10.
var folderContents = await sfClient.Items.GetChildren()
.Top(10)
.Skip(10)
.ExecuteAsync();
To support paging ODataFeed
will also return a nextLink which will compute the
Top and Skip values for you.