V0FBU1VM
V0FBU1VM
CC#
Created by V0FBU1VM on 10/7/2024 in #help
✅ Ef Core unexpected query behaviour
var memberships = await db.OrganizationMembers.AsTracking()
.Include(om => om.Organization)
.Where(om => om.UserId == user.Id && om.InvitationStatus == InvitationStatus.Approved &&
om.Role > MemberRole.None)
.ToListAsync(cancellationToken);
var memberships = await db.OrganizationMembers.AsTracking()
.Include(om => om.Organization)
.Where(om => om.UserId == user.Id && om.InvitationStatus == InvitationStatus.Approved &&
om.Role > MemberRole.None)
.ToListAsync(cancellationToken);
/// <summary>
/// Represents an enumeration of member roles.
/// </summary>
public enum MemberRole
{
/// <summary>
/// Represents the None role.
/// </summary>
None,

/// <summary>
/// Represents the Read role.
/// </summary>
Read,

/// <summary>
/// Represents the Write role.
/// </summary>
Write,

/// <summary>
/// Represents the Administrator role.
/// </summary>
Admin
}
/// <summary>
/// Represents an enumeration of member roles.
/// </summary>
public enum MemberRole
{
/// <summary>
/// Represents the None role.
/// </summary>
None,

/// <summary>
/// Represents the Read role.
/// </summary>
Read,

/// <summary>
/// Represents the Write role.
/// </summary>
Write,

/// <summary>
/// Represents the Administrator role.
/// </summary>
Admin
}
For some reason it's not including MemberRole.admin. It's including MemberRole.Write?
68 replies
CC#
Created by V0FBU1VM on 9/8/2024 in #help
✅ Navigation Property
Any reason as to why I'm getting this message/warning?
The relationship defined by this property contributes to a dependency loop.
The relationship defined by this property contributes to a dependency loop.
20 replies
CC#
Created by V0FBU1VM on 9/3/2024 in #help
Caching?
I have been meaning to ask a question about caching. How do you determine what data to cache and when?
6 replies
CC#
Created by V0FBU1VM on 6/23/2024 in #help
Dublicate Properties in Tables?
I have a table named Users and one named Organizations. The relation between them is many to many. The joining table is called OrganizationMember. I'm wondering whether it would be a good idea, to store certain properties from the User table inside the OrganizationMember. Such as Email, & Full Name and AvatarUrl. The reason being is that OrganizationMember will be used very much. I don't want to modify my queries to include the User every time. Any suggestions would be appreciated.
6 replies
CC#
Created by V0FBU1VM on 5/19/2024 in #help
Query improvement suggestions
/// <summary>
/// Retrieves roles assigned to the user within organizations.
/// </summary>
/// <param name="userId">The ID of the user.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The roles assigned to the user within organizations.</returns>
private async Task<Dictionary<Guid, MemberRole>> GetOrganizationRolesAsync(Guid userId,
CancellationToken cancellationToken)
{
// Get all organizations the user is a member of
var userOrganizations = await db.OrganizationMembers
.Where(om => om.UserId == userId)
.Select(om => om.OrganizationId)
.ToListAsync(cancellationToken);

// Get roles in organizations where the user has a role
var organizationRoles = await db.OrganizationMemberRoles
.Where(omr => omr.OrganizationMember.UserId == userId)
.Select(omr => new { omr.OrganizationId, omr.OrganizationRole.Name })
.ToListAsync(cancellationToken);

// Parse roles and add to dictionary
var parsedRoles = organizationRoles.ToDictionary(
omr => omr.OrganizationId,
omr =>
{
if (Enum.TryParse<MemberRole>(omr.Name, true, out var role))
return role;

throw new InvalidCastException();
});

// For organizations where the user doesn't have a role, add with MemberRole.None
foreach (var orgId in userOrganizations) parsedRoles.TryAdd(orgId, MemberRole.None);

return parsedRoles;
}
/// <summary>
/// Retrieves roles assigned to the user within organizations.
/// </summary>
/// <param name="userId">The ID of the user.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The roles assigned to the user within organizations.</returns>
private async Task<Dictionary<Guid, MemberRole>> GetOrganizationRolesAsync(Guid userId,
CancellationToken cancellationToken)
{
// Get all organizations the user is a member of
var userOrganizations = await db.OrganizationMembers
.Where(om => om.UserId == userId)
.Select(om => om.OrganizationId)
.ToListAsync(cancellationToken);

// Get roles in organizations where the user has a role
var organizationRoles = await db.OrganizationMemberRoles
.Where(omr => omr.OrganizationMember.UserId == userId)
.Select(omr => new { omr.OrganizationId, omr.OrganizationRole.Name })
.ToListAsync(cancellationToken);

// Parse roles and add to dictionary
var parsedRoles = organizationRoles.ToDictionary(
omr => omr.OrganizationId,
omr =>
{
if (Enum.TryParse<MemberRole>(omr.Name, true, out var role))
return role;

throw new InvalidCastException();
});

// For organizations where the user doesn't have a role, add with MemberRole.None
foreach (var orgId in userOrganizations) parsedRoles.TryAdd(orgId, MemberRole.None);

return parsedRoles;
}
Is there a way I can improve this query?
3 replies
CC#
Created by V0FBU1VM on 5/18/2024 in #help
Access Token Expiry date suggestions
What does you guys think, should be the expiry of an access token? I set the expiry of the refresh token to 30 days and the access token to 1 day. Any suggestions would be appreciated. Sincerely.
1 replies
CC#
Created by V0FBU1VM on 3/31/2024 in #help
DeleteBehavior?
I'm always confused which DeleteBehavior to assign when configuring my Entities. Can someone please explain to me?
3 replies
CC#
Created by V0FBU1VM on 3/29/2024 in #help
Project structure
No description
17 replies
CC#
Created by V0FBU1VM on 3/14/2024 in #help
✅ How should I name my ef core migrations?
I'm wondering if there is a good way to name your migrations. I have noticed that, you quickly end-up with a lot of migrations. I'm just wondering if there is a good naming convention.
21 replies
CC#
Created by V0FBU1VM on 2/24/2024 in #help
✅ Npgsql.PostgresException
public class CreatePostHandler(
IHttpContextAccessor contextAccessor,
DatabaseContext db,
ISender mediator,
IValidator<CreatePostCommand> validator)
: RequestHandler(contextAccessor), IRequestHandler<CreatePostCommand, Result<Post>>
{
private const string StorageContainer = "images";

public async Task<Result<Post>> Handle(CreatePostCommand request, CancellationToken cancellationToken)
{
try
{
var validationResult = await ValidateInputAsync(request, cancellationToken);
if (!validationResult.IsValid)
return Result<Post>.Failure("Invalid input received.",
validationResult.ErrorMessages(), 400);

var newBlobName = $"{Guid.NewGuid()}{request.File.GetExtensionType()}";
var uploadResult = await UploadFileAsync(newBlobName, request.File, cancellationToken);

if (!uploadResult.IsSuccessful)
return uploadResult.ToResult(_ => new Post());

var uri = uploadResult.Data;
var nsfwResult = await ClassifyFileAsync(uri, cancellationToken);
if (!nsfwResult.IsSuccessful)
{
await DeleteNewlyUploadedFileAsync(newBlobName, cancellationToken);
return nsfwResult.ToResult<Post>(default!);
}

var post = new Post
{
Caption = request.Caption,
Url = uri.ToString(),
AuthorId = UserId
};

return await CreatePostAsync(post, cancellationToken);
}
catch (Exception e)
{
return Result<Post>.Failure("Something unexpected occurred.", [e.ToString()], 500);
}
}

private async Task<ValidationResult> ValidateInputAsync(CreatePostCommand request,
CancellationToken cancellationToken)
{
return await validator.ValidateAsync(request, cancellationToken);
}

private async Task DeleteNewlyUploadedFileAsync(string blobName, CancellationToken cancellationToken)
{
await mediator.Send(
new DeleteFileFromStorageCommand(blobName, StorageContainer),
cancellationToken);
}

private async Task<Result<Uri>> UploadFileAsync(string blobName, IFormFile file,
CancellationToken cancellationToken)
{
return await mediator.Send(new UploadFileToStorageCommand
{
ContainerName = StorageContainer,
BlobName = blobName,
ContentType = file.ContentType,
Stream = file.OpenReadStream()
}, cancellationToken);
}

private async Task<Result> ClassifyFileAsync(Uri uri, CancellationToken cancellationToken)
{
return await mediator.Send(new ClassifyImageCommand(uri), cancellationToken);
}

private async Task<Result<Post>> CreatePostAsync(Post post, CancellationToken cancellationToken)
{
var hashtags = await mediator.Send(new ExtractHashtagsCommand(post.Caption), cancellationToken);
foreach (var hashtag in hashtags)
post.Hashtags.Add(hashtag);

db.Posts.Add(post);
await db.SaveChangesAsync(cancellationToken);
return Result<Post>.Success(post);
}
}
public class CreatePostHandler(
IHttpContextAccessor contextAccessor,
DatabaseContext db,
ISender mediator,
IValidator<CreatePostCommand> validator)
: RequestHandler(contextAccessor), IRequestHandler<CreatePostCommand, Result<Post>>
{
private const string StorageContainer = "images";

public async Task<Result<Post>> Handle(CreatePostCommand request, CancellationToken cancellationToken)
{
try
{
var validationResult = await ValidateInputAsync(request, cancellationToken);
if (!validationResult.IsValid)
return Result<Post>.Failure("Invalid input received.",
validationResult.ErrorMessages(), 400);

var newBlobName = $"{Guid.NewGuid()}{request.File.GetExtensionType()}";
var uploadResult = await UploadFileAsync(newBlobName, request.File, cancellationToken);

if (!uploadResult.IsSuccessful)
return uploadResult.ToResult(_ => new Post());

var uri = uploadResult.Data;
var nsfwResult = await ClassifyFileAsync(uri, cancellationToken);
if (!nsfwResult.IsSuccessful)
{
await DeleteNewlyUploadedFileAsync(newBlobName, cancellationToken);
return nsfwResult.ToResult<Post>(default!);
}

var post = new Post
{
Caption = request.Caption,
Url = uri.ToString(),
AuthorId = UserId
};

return await CreatePostAsync(post, cancellationToken);
}
catch (Exception e)
{
return Result<Post>.Failure("Something unexpected occurred.", [e.ToString()], 500);
}
}

private async Task<ValidationResult> ValidateInputAsync(CreatePostCommand request,
CancellationToken cancellationToken)
{
return await validator.ValidateAsync(request, cancellationToken);
}

private async Task DeleteNewlyUploadedFileAsync(string blobName, CancellationToken cancellationToken)
{
await mediator.Send(
new DeleteFileFromStorageCommand(blobName, StorageContainer),
cancellationToken);
}

private async Task<Result<Uri>> UploadFileAsync(string blobName, IFormFile file,
CancellationToken cancellationToken)
{
return await mediator.Send(new UploadFileToStorageCommand
{
ContainerName = StorageContainer,
BlobName = blobName,
ContentType = file.ContentType,
Stream = file.OpenReadStream()
}, cancellationToken);
}

private async Task<Result> ClassifyFileAsync(Uri uri, CancellationToken cancellationToken)
{
return await mediator.Send(new ClassifyImageCommand(uri), cancellationToken);
}

private async Task<Result<Post>> CreatePostAsync(Post post, CancellationToken cancellationToken)
{
var hashtags = await mediator.Send(new ExtractHashtagsCommand(post.Caption), cancellationToken);
foreach (var hashtag in hashtags)
post.Hashtags.Add(hashtag);

db.Posts.Add(post);
await db.SaveChangesAsync(cancellationToken);
return Result<Post>.Success(post);
}
}
Any reasons as to why I'm getting this error?
27 replies
CC#
Created by V0FBU1VM on 2/23/2024 in #help
Azure video analyzer
:blue_siren: :blue_siren: Is there any azure service that I can use to analyze a video's content? I want to check whether or not a video contains, nudity or other inappropriate stuff?
5 replies
CC#
Created by V0FBU1VM on 2/10/2024 in #help
✅ Suggestion on file upload?
When uploading file to azure storage. Should I upload the files through the server (api)? or is there another way. The thing that scares me is that if multiple people upload at the same time than we will have a memory issue. The clients in this case are mobile apps? Any insights would be appreciated.
45 replies
CC#
Created by V0FBU1VM on 2/1/2024 in #help
Verify Google Id Token: FormatException
I'm using google sign in on my client. Before authenticating the user I want to Verify the ID Token which I get from the client. On the server side. I'm trying to validate the ID Token (jwt) by using Google.Apis.Auth nuget package. But I'm getting a format exception. Here is the code:
/// <summary>
/// Handler for verifying Google ID tokens.
/// </summary>
public class VerifyGoogleIdTokenHandler(IConfiguration configuration)
: IRequestHandler<VerifyGoogleIdTokenCommand, Result<GoogleJsonWebSignature.Payload>>
{
private readonly GoogleJsonWebSignature.ValidationSettings _settings = new()
{
Audience = new[]
{
configuration[ConfigurationKeys.GoogleWebClientId], configuration[ConfigurationKeys.GoogleAndroidClientId]
}
};

public async Task<Result<GoogleJsonWebSignature.Payload>> Handle(VerifyGoogleIdTokenCommand request,
CancellationToken cancellationToken)
{
try
{
var payload = await GoogleJsonWebSignature.ValidateAsync(request.IdToken, _settings);
if (payload == null)
throw new InvalidJwtException("Invalid ID token");

return Result<GoogleJsonWebSignature.Payload>.Success(payload);
}
catch (Exception ex)
{
return Result<GoogleJsonWebSignature.Payload>.Failure("Invalid ID token", new[] { ex.ToString() }, 400);
}
}
}
/// <summary>
/// Handler for verifying Google ID tokens.
/// </summary>
public class VerifyGoogleIdTokenHandler(IConfiguration configuration)
: IRequestHandler<VerifyGoogleIdTokenCommand, Result<GoogleJsonWebSignature.Payload>>
{
private readonly GoogleJsonWebSignature.ValidationSettings _settings = new()
{
Audience = new[]
{
configuration[ConfigurationKeys.GoogleWebClientId], configuration[ConfigurationKeys.GoogleAndroidClientId]
}
};

public async Task<Result<GoogleJsonWebSignature.Payload>> Handle(VerifyGoogleIdTokenCommand request,
CancellationToken cancellationToken)
{
try
{
var payload = await GoogleJsonWebSignature.ValidateAsync(request.IdToken, _settings);
if (payload == null)
throw new InvalidJwtException("Invalid ID token");

return Result<GoogleJsonWebSignature.Payload>.Success(payload);
}
catch (Exception ex)
{
return Result<GoogleJsonWebSignature.Payload>.Failure("Invalid ID token", new[] { ex.ToString() }, 400);
}
}
}
2 replies
CC#
Created by V0FBU1VM on 1/31/2024 in #help
ASP.NET Core Identity?
Is there a way here I can check if the token has expired or if it already has been used?
/// <summary>
/// Handles the logic for resetting a user's password based on the provided command.
/// </summary>
public class ResetPasswordHandler(UserManager<User> userManager)
: IRequestHandler<ResetPasswordCommand, Result<bool>>, IDisposable
{
public void Dispose()
{
userManager.Dispose();
GC.SuppressFinalize(this);
}

public async Task<Result<bool>> Handle(ResetPasswordCommand request, CancellationToken cancellationToken)
{
// Validate the input using the ResetPasswordValidator.
var validator = new ResetPasswordValidator();
var validationResult = await validator.ValidateAsync(request, cancellationToken);

if (!validationResult.IsValid)
return Result<bool>.Failure("Invalid input received.", 400);

// Find the user by email address.
var user = await userManager.FindByEmailAsync(request.Email);
if (user == null)
return Result<bool>.Failure("User not found.", 404);

// Reset the user's password.
var result = await userManager.ResetPasswordAsync(user, request.Token, request.Password);

// Return the appropriate result based on the reset operation success.
return !result.Succeeded
? Result<bool>.Failure("Unable to reset password.", 500)
: Result<bool>.Success(true);
}
}
/// <summary>
/// Handles the logic for resetting a user's password based on the provided command.
/// </summary>
public class ResetPasswordHandler(UserManager<User> userManager)
: IRequestHandler<ResetPasswordCommand, Result<bool>>, IDisposable
{
public void Dispose()
{
userManager.Dispose();
GC.SuppressFinalize(this);
}

public async Task<Result<bool>> Handle(ResetPasswordCommand request, CancellationToken cancellationToken)
{
// Validate the input using the ResetPasswordValidator.
var validator = new ResetPasswordValidator();
var validationResult = await validator.ValidateAsync(request, cancellationToken);

if (!validationResult.IsValid)
return Result<bool>.Failure("Invalid input received.", 400);

// Find the user by email address.
var user = await userManager.FindByEmailAsync(request.Email);
if (user == null)
return Result<bool>.Failure("User not found.", 404);

// Reset the user's password.
var result = await userManager.ResetPasswordAsync(user, request.Token, request.Password);

// Return the appropriate result based on the reset operation success.
return !result.Succeeded
? Result<bool>.Failure("Unable to reset password.", 500)
: Result<bool>.Success(true);
}
}
If so how do I set the expiration time?
1 replies
CC#
Created by V0FBU1VM on 1/30/2024 in #help
How to tell SwaggerUI to display `Enum` by the name and not integer value?
I want SwaggerUI to display Enum by the name and not integer value. The only problem is that when triggering an action it's sending the name to the pipline.
public class EnumSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema model, SchemaFilterContext context)
{
if (context.Type.IsEnum)
{
model.Enum.Clear();
Enum.GetNames(context.Type)
.ToList()
.ForEach(name => model.Enum.Add(new OpenApiString($"{Convert.ToInt64(Enum.Parse(context.Type, name))} = {name}")));
}
}
}
public class EnumSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema model, SchemaFilterContext context)
{
if (context.Type.IsEnum)
{
model.Enum.Clear();
Enum.GetNames(context.Type)
.ToList()
.ForEach(name => model.Enum.Add(new OpenApiString($"{Convert.ToInt64(Enum.Parse(context.Type, name))} = {name}")));
}
}
}
Is there a way I can tell swagger to only display the enums as their string name? But it should still handle everything by their integer values?
1 replies
CC#
Created by V0FBU1VM on 1/28/2024 in #help
✅ Regex help pls:
^[a-z]+(?:_[a-z]+)?[a-z]+$ how can I check so that there are atleast 4 characters?
13 replies
CC#
Created by V0FBU1VM on 1/18/2024 in #help
Tips on choosing the right database
I'm currently working on a social media project that involves features like comments, replies, following, followers, and posts. I'm in the process of choosing the right database for the project and wanted to reach out to seek valuable insights. Considering the dynamic nature of social media interactions and the need for efficient data retrieval, I'm a bit torn between different database options. Do you guys have any recommendations or insights on which database might be a good fit for managing the complexities of user interactions? I don't have that much experience in other databases. I'm only familiar with SQL.
10 replies
CC#
Created by V0FBU1VM on 7/13/2023 in #help
❔ Linq Query HELP
I have this entity. During deletion, I would like to load all related entities, so that I can delete them also. Here is the entity
/// <summary>
/// Represents a comment entity.
/// </summary>
public class Comment : AbstractEntity, ISuspension
{
public required string Content { get; set; }
public int Depth { get; set; }
public Guid AuthorId { get; set; }
public virtual User Author { get; set; } = default!;
public Guid QuoteId { get; set; }
public virtual Quote Quote { get; set; } = default!;
public Guid? ParentId { get; set; }
public virtual Comment ParentComment { get; set; } = default!;
public virtual ICollection<Comment> Replies { get; set; } = new HashSet<Comment>();
public virtual ICollection<Like<Comment>> Likes { get; set; } = new HashSet<Like<Comment>>();
public virtual ICollection<Dislike<Comment>> Dislikes { get; set; } = new HashSet<Dislike<Comment>>();
public virtual ICollection<Suspension<Comment>> Suspensions { get; set; } = new HashSet<Suspension<Comment>>();
public bool IsSuspended { get; set; }
}
/// <summary>
/// Represents a comment entity.
/// </summary>
public class Comment : AbstractEntity, ISuspension
{
public required string Content { get; set; }
public int Depth { get; set; }
public Guid AuthorId { get; set; }
public virtual User Author { get; set; } = default!;
public Guid QuoteId { get; set; }
public virtual Quote Quote { get; set; } = default!;
public Guid? ParentId { get; set; }
public virtual Comment ParentComment { get; set; } = default!;
public virtual ICollection<Comment> Replies { get; set; } = new HashSet<Comment>();
public virtual ICollection<Like<Comment>> Likes { get; set; } = new HashSet<Like<Comment>>();
public virtual ICollection<Dislike<Comment>> Dislikes { get; set; } = new HashSet<Dislike<Comment>>();
public virtual ICollection<Suspension<Comment>> Suspensions { get; set; } = new HashSet<Suspension<Comment>>();
public bool IsSuspended { get; set; }
}
I have come this far
var comment = await DbContext.Comments
.Include(x => x.Replies)
.ThenInclue(x => x.Likes)
.ThenInclue(x => x.Dislikes)
.ThenInclue(x => x.Suspensions)
.Include(x => x.Likes)
.Include(x => x.Dislikes)
.Include(x => x.Suspensions)
.FirstOrDefaultAsync(x => x.Id == request.Id && x.AuthorId == UserId, cancellationToken);
var comment = await DbContext.Comments
.Include(x => x.Replies)
.ThenInclue(x => x.Likes)
.ThenInclue(x => x.Dislikes)
.ThenInclue(x => x.Suspensions)
.Include(x => x.Likes)
.Include(x => x.Dislikes)
.Include(x => x.Suspensions)
.FirstOrDefaultAsync(x => x.Id == request.Id && x.AuthorId == UserId, cancellationToken);
I would like to load the Replies, and there likes, dislikes, suspensions. I also need to load the replies of replies and there likes, dislikes, suspensions etc. Any help would be appreciated. I don't think this query will do the job.
5 replies
CC#
Created by V0FBU1VM on 7/12/2023 in #help
❔ Will this operation be expensive or not?
During a request, I'm checking whether a user is currently suspended or not. So during each request I'm hitting the database and getting the user
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.Events = new JwtBearerEvents
{
OnTokenValidated = async context =>
{
var claimsPrincipal = context.Principal;
if (claimsPrincipal == null)
{
context.Fail("Access denied");
return;
}

var claim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
if (string.IsNullOrEmpty(claim) || !Guid.TryParse(claim, out _))
{
context.Fail("Access denied.");
return;
}

var userManager = context.HttpContext.RequestServices.GetRequiredService<UserManager<User>>();
var user = await userManager.FindByIdAsync(claim);

if (user == null || user.IsSuspended)
{
context.Fail("Access denied.");
}
}
};
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.Events = new JwtBearerEvents
{
OnTokenValidated = async context =>
{
var claimsPrincipal = context.Principal;
if (claimsPrincipal == null)
{
context.Fail("Access denied");
return;
}

var claim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
if (string.IsNullOrEmpty(claim) || !Guid.TryParse(claim, out _))
{
context.Fail("Access denied.");
return;
}

var userManager = context.HttpContext.RequestServices.GetRequiredService<UserManager<User>>();
var user = await userManager.FindByIdAsync(claim);

if (user == null || user.IsSuspended)
{
context.Fail("Access denied.");
}
}
};
It just feel like this is not the right way?
8 replies
CC#
Created by V0FBU1VM on 5/19/2023 in #help
❔ Upload large files to azure storage!
Does anyone have a method that uploads large files to azure storage efficiently? I'm using
Azure.Storage.Blobs
Azure.Storage.Blobs
Here is the current method
public async Task<Uri?> UploadFileAsync(string containerName, string fileName, Stream stream,
CancellationToken cancellationToken)
{
try
{
var containerClient = _blobService.GetBlobContainerClient(containerName);
await containerClient.CreateIfNotExistsAsync(cancellationToken: cancellationToken);
var blobClient = containerClient.GetBlockBlobClient(fileName);

var options = new BlobUploadOptions
{
TransferOptions = new StorageTransferOptions
{
MaximumConcurrency = 16, // Adjust the concurrency level as needed
MaximumTransferSize = 4 * 1024 * 1024, // 4MB chunk size
},
};

await blobClient.UploadAsync(stream, options, cancellationToken);
return blobClient.Uri;
}
catch (Exception ex)
{
return null;
}
}
public async Task<Uri?> UploadFileAsync(string containerName, string fileName, Stream stream,
CancellationToken cancellationToken)
{
try
{
var containerClient = _blobService.GetBlobContainerClient(containerName);
await containerClient.CreateIfNotExistsAsync(cancellationToken: cancellationToken);
var blobClient = containerClient.GetBlockBlobClient(fileName);

var options = new BlobUploadOptions
{
TransferOptions = new StorageTransferOptions
{
MaximumConcurrency = 16, // Adjust the concurrency level as needed
MaximumTransferSize = 4 * 1024 * 1024, // 4MB chunk size
},
};

await blobClient.UploadAsync(stream, options, cancellationToken);
return blobClient.Uri;
}
catch (Exception ex)
{
return null;
}
}
5 replies