Uploading files to OneDrive from a .NET Core application is a common requirement when building document workflows, backup systems, or enterprise integrations.
Recently, I needed to add OneDrive upload functionality into an existing .NET Core repository — without breaking the current architecture.
In this article, I'll walk you through:
- Setup OneDrive API access
- Integrating upload logic into an existing .NET Core project
- Writing clean and maintainable upload code
- Common mistakes and best practices
Why Use OneDrive Upload in .NET Core?
Before jumping into code, here's why developers often integrate OneDrive:
- Centralized cloud storage
- Secure file access via Microsoft identity
- Easy integration with enterprise apps
- Works well with background services and APIs
- Instead of building your own storage service, OneDrive gives you a ready-to-use infrastructure.
Prerequisites: —
Make sure you have:
- .NET Core Web API or MVC project
- Azure App Registration
- OneDrive or Microsoft 365 account
- Existing repository where you want to add upload functionality
Step 1 — Register an App in Azure: —
First, create an application registration.
- Go to Azure Portal
- Navigate to App registrations
- Create a new registration
- Add API permissions: Files.ReadWriteAll
After creation, note these details
- Client ID
- Tenant ID
- Client Secret
Step 2 — Install Required Packages
Inside your existing .NET Core project install Microsoft Graph:
dotnet add package Microsoft.Graph
dotnet add package Microsoft.Identity.ClientThese packages allow authentication and OneDrive API access.
Step 3 — Add Configuration to appsettings.json
"AzureAd": {
"ClientId": "YOUR_CLIENT_ID",
"TenantId": "YOUR_TENANT_ID",
"ClientSecret": "YOUR_SECRET"
}Keep secrets secure — don't commit them to Git.
Step 4 — Create a OneDrive Service Class
Instead of mixing upload logic into controllers, create a service. This keeps your existing repo clean.
public class OneDriveService
{
private readonly IConfiguration _config;
public OneDriveService(IConfiguration config)
{
_config = config;
}
private async Task<GraphServiceClient> GetClient()
{
var clientId = _config["AzureAd:ClientId"];
var tenantId = _config["AzureAd:TenantId"];
var clientSecret = _config["AzureAd:ClientSecret"];
var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
return new GraphServiceClient(credential, new[] { "https://graph.microsoft.com/.default" });
}
public async Task UploadFileAsync(Stream fileStream, string oneDrivePath)
{
string userEmail = "youremail";
var driveInfo = await GetClient()
.Users[userEmail]
.Drive
.GetAsync();
var uploadedItem = await graphClient
.Drives[driveInfo.Id]
.Root
.ItemWithPath(oneDrivePath)
.Content
.PutAsync(fileStream);
}
}Step 5 — Inject the Service Into Existing Controllers
Register the service in Program.cs:
builder.Services.AddScoped<OneDriveService>();Now use it inside your controller:
[HttpPost("upload")]
public async Task<IActionResult> Upload(IFormFile file,
[FromServices] OneDriveService oneDrive)
{
using var stream = file.OpenReadStream();
await oneDrive.UploadFileAsync(stream, $"Upload/{file.FileName}");
return Ok("File uploaded successfully");
}This approach avoid rewriting your repository structure.
Step 6 — Handling Large Files (Important)
The simple upload works well for small files. For files larger than 4MB, you should use chunked uploads.
Why?
- Prevents memory issues
- Supports resumable uploads
- Works better in production environments
Microsoft Graph provides upload sessions for this.
Common Mistakes Developers Make
Here are some things I learned while integrating into an existing repo:
- Mixing upload logic into controllers
Keep it in services to maintain clean architecture.
- Hardcoding tokens
Always use Azure authentication flow.
- Ignoring async streams
- Forgetting permissions
Best Practices for Existing Repositorie
If you're adding this into a mature codebase:
- Create a separate Infrastructure layer for Graph API
- Use Dependency Injection
- Add retry policies for network failures
- Log upload responses for debugging
Final Thoughts
Adding OneDrive upload to a .NET Core project becomes easy once authentication is set up.
The important part is keeping your code organized, especially in an existing project. By putting the Graph API logic into a separate service and using dependency injection you can add new features without affecting your current code.
Thanks for reading
Please Follow me on
If you enjoyed this article and would like to receive more content like this, please subscribe to my newsletter by clicking here. You'll be the first to know when I publish new articles, and you can unsubscribe at any time.