no >> body
no >> body
CC#
Created by no >> body on 7/18/2024 in #help
✅ EF core transactions in PostgreSQL
I have a custom extension method for running operations on DbContext. One is for running operations in transactions with a specific isolation level, and the second one is for retry logic. The problem I just spotted is that isolation doesn't work properly, despite having enough retries and time to process transactions. I have an entity called WalletBalance that contains a property Amount. And here is my job for testing:
[DisallowConcurrentExecution]
public class TestJob(ILogger<TestJob> logger, MasterDbContext masterDbContext, IServiceScopeFactory factory) : IJob
{
private Guid WalletBalanceId { get; set; }

public async Task Execute(IJobExecutionContext context)
{
WalletBalanceId = masterDbContext.WalletBalances.First(x => x.Amount == 0).Id;

var tasks = new List<Task>
{
UpdateBalance(100, 100),
UpdateBalance(-100, 100),
UpdateBalance(100, 100),
UpdateBalance(-100, 100)
};

await Task.WhenAll(tasks);
}

private async Task UpdateBalance(int amount, int times)
{
using IServiceScope scope = factory.CreateScope();
MasterDbContext context = scope.ServiceProvider.GetRequiredService<MasterDbContext>();

for (var i = 0; i < times; i++)
{
await context.ExecuteInCustomStrategyAsync(
async _ =>
{
await context.ExecuteInTransactionAsync(
async _ =>
{
WalletBalance walletBalance = (await context.WalletBalances.FindAsync(WalletBalanceId))!;
walletBalance.Amount += amount;
});
});
}
}
}
[DisallowConcurrentExecution]
public class TestJob(ILogger<TestJob> logger, MasterDbContext masterDbContext, IServiceScopeFactory factory) : IJob
{
private Guid WalletBalanceId { get; set; }

public async Task Execute(IJobExecutionContext context)
{
WalletBalanceId = masterDbContext.WalletBalances.First(x => x.Amount == 0).Id;

var tasks = new List<Task>
{
UpdateBalance(100, 100),
UpdateBalance(-100, 100),
UpdateBalance(100, 100),
UpdateBalance(-100, 100)
};

await Task.WhenAll(tasks);
}

private async Task UpdateBalance(int amount, int times)
{
using IServiceScope scope = factory.CreateScope();
MasterDbContext context = scope.ServiceProvider.GetRequiredService<MasterDbContext>();

for (var i = 0; i < times; i++)
{
await context.ExecuteInCustomStrategyAsync(
async _ =>
{
await context.ExecuteInTransactionAsync(
async _ =>
{
WalletBalance walletBalance = (await context.WalletBalances.FindAsync(WalletBalanceId))!;
walletBalance.Amount += amount;
});
});
}
}
}
I expect the amount to be 0 after all the transactions have been run. But in fact Amount has random numbers after each run of the job. My implementation of ExecuteInCustomStrategyAsync and ExecuteInTransactionAsync below
17 replies
CC#
Created by no >> body on 2/15/2024 in #help
OpenID Connect with SPA login page
I'm looking for some advice about implementing a login page with a separate SPA application. Currently, we have the next configuration: 1. OpenID Connect-based Auth server (ASP.NET Core + OpenIddict) 2. A bunch of UI applications (React) 3. A bunch of API backend services (ASP.NET Core) Our auth server contains a login page written with Razor Pages. It also includes Google authentication with the ability to use 2FA with an authenticator. For all authorizations, we use Authorization Code Flow with PKCE. Now we have a business requirement to create a login page for one of our react apps. The user should be able to provide credentials inside the React app and log in to the system. Additionally, the user should be able to log in via Google in this React application. I'm concerned about the security aspect of this requirement. And trying to figure out if I should raise my concerns to other developers and managers. Do you see any problems with this requirement? Is it possible to achieve this without breaking OpenID Connect flows and best practices?
1 replies
CC#
Created by no >> body on 7/26/2023 in #help
❔ WebApplicationFactory and integration tests
I've run into an issue with my integration tests and I'm looking for some insight. I'm using WebApplicationFactory and trying to set up a configuration inside it. Here's what it looks like:
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
// Setting up an in-memory collection for my database configuration here
builder.ConfigureAppConfiguration(
(context, config) =>
{
config.AddInMemoryCollection(
new Dictionary<string, string>
{
[$"{DatabaseConfiguration.SectionName}:{nameof(DatabaseConfiguration.MasterConnectionString)}"] =
connectionString,
[$"{DatabaseConfiguration.SectionName}:{nameof(DatabaseConfiguration.ReplicaConnectionString)}"] =
connectionString
});
// Adding more services and authentication schemes
});
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
// Setting up an in-memory collection for my database configuration here
builder.ConfigureAppConfiguration(
(context, config) =>
{
config.AddInMemoryCollection(
new Dictionary<string, string>
{
[$"{DatabaseConfiguration.SectionName}:{nameof(DatabaseConfiguration.MasterConnectionString)}"] =
connectionString,
[$"{DatabaseConfiguration.SectionName}:{nameof(DatabaseConfiguration.ReplicaConnectionString)}"] =
connectionString
});
// Adding more services and authentication schemes
});
}
Now, I have a separate setup in my Program.cs file, where I am adding some services including DbContexts. Here's how it looks:
WebApplicationBuilder builder = WebApplication.CreateBuilder();
// Some services and localization stuff
// ...
builder.Host
.AddDbContexts<MasterDbContext, ReplicaDbContext>(true, true)
.AddOpenIddict()
.AddKafkaProducer<AuditLogProducer>();
WebApplicationBuilder builder = WebApplication.CreateBuilder();
// Some services and localization stuff
// ...
builder.Host
.AddDbContexts<MasterDbContext, ReplicaDbContext>(true, true)
.AddOpenIddict()
.AddKafkaProducer<AuditLogProducer>();
My AddDbContexts method is actually adding contexts using UseNpgsql and it takes the connection string from my configuration.
3 replies
CC#
Created by no >> body on 7/19/2023 in #help
❔ Localization behavior in tests
I've been facing an issue with xUnit integration tests for my ASP.NET Core application and I'm struggling to find a solution. We use localization in our app for translating various responses. Everything works perfectly fine when I run the tests on my local machine. However, when I try to run them in our CI/CD pipeline on GitLab, the tests fail. Initially, I encountered a System.Globalization.CultureNotFoundException with a message about the invariant culture being the only supported one in globalization-invariant mode. I managed to solve this issue by adding <InvariantGlobalization>false</InvariantGlobalization> to my test project file. The current problem I'm facing is a System.ArgumentException in a method where we use IStringLocalizer. The error message states: A message must be specified when calling WithMessage. Here is a code where this error happens:
LocalizedString enumRangeErrorMessage = errorMessagesLocalizer[$"{ErrorMessageIdentifiers.ValidatorSection}:{ErrorMessageIdentifiers.EnumRange}"];
RuleFor(x => x.OrderBy)
.Must(x => EnumHelper.TryParseWithMemberName<PaymentSystemAccountOrderBy>(x, out _))
.WithMessage(enumRangeErrorMessage)
.When(x => !string.IsNullOrEmpty(x.OrderBy));
LocalizedString enumRangeErrorMessage = errorMessagesLocalizer[$"{ErrorMessageIdentifiers.ValidatorSection}:{ErrorMessageIdentifiers.EnumRange}"];
RuleFor(x => x.OrderBy)
.Must(x => EnumHelper.TryParseWithMemberName<PaymentSystemAccountOrderBy>(x, out _))
.WithMessage(enumRangeErrorMessage)
.When(x => !string.IsNullOrEmpty(x.OrderBy));
Where errorMessagesLocalizer is just IStringLocalizer. The odd part is that this exception only occurs in the pipeline. The tests run successfully on my local machine. I've checked that the paths to my resources are correct and that they are included in the build output. I've tried replicating the CI/CD environment locally to debug the issue, but I can't reproduce it. I'm running out of ideas here. Does anyone have any suggestions on what could be going wrong or what else I could try?
2 replies
CC#
Created by no >> body on 6/6/2023 in #help
❔ Incremental Generator compilation error
9 replies
CC#
Created by no >> body on 4/24/2023 in #help
❔ ASP.NET Core authorization server in Kubernetes environment
I have an authorization server created on OpenIddict library. After removing
options.DisableTransportSecurityRequirement();
options.DisableTransportSecurityRequirement();
I've started getting errors. For example, when I want to check "https://auth.domain.com/.well-known/openid-configuration" I'm getting this:
2023-04-24 07:14:57.098 Information - Request starting HTTP/1.1 GET http://auth.domain.com/.well-known/openid-configuration - -
2023-04-24 07:14:57.098 Debug - The request is insecure. Skipping HSTS header.
2023-04-24 07:14:57.098 Debug - The request path /.well-known/openid-configuration does not match a supported file type
2023-04-24 07:14:57.099 Debug - No candidates found for the request path '/.well-known/openid-configuration'
2023-04-24 07:14:57.099 Debug - Request did not match any endpoints
2023-04-24 07:14:57.102 Information - The response was successfully returned as a JSON document: {
"error": "invalid_request",
"error_description": "This server only accepts HTTPS requests.",
"error_uri": "https://documentation.openiddict.com/errors/ID2083"
}.
2023-04-24 07:14:57.102 Information - Request finished HTTP/1.1 GET http://auth.domain.com/.well-known/openid-configuration - - - 400 168 application/json;charset=UTF-8 4.5390ms
2023-04-24 07:14:57.098 Information - Request starting HTTP/1.1 GET http://auth.domain.com/.well-known/openid-configuration - -
2023-04-24 07:14:57.098 Debug - The request is insecure. Skipping HSTS header.
2023-04-24 07:14:57.098 Debug - The request path /.well-known/openid-configuration does not match a supported file type
2023-04-24 07:14:57.099 Debug - No candidates found for the request path '/.well-known/openid-configuration'
2023-04-24 07:14:57.099 Debug - Request did not match any endpoints
2023-04-24 07:14:57.102 Information - The response was successfully returned as a JSON document: {
"error": "invalid_request",
"error_description": "This server only accepts HTTPS requests.",
"error_uri": "https://documentation.openiddict.com/errors/ID2083"
}.
2023-04-24 07:14:57.102 Information - Request finished HTTP/1.1 GET http://auth.domain.com/.well-known/openid-configuration - - - 400 168 application/json;charset=UTF-8 4.5390ms
Just for context: I have such services as Traefik and Linkerd, so they also can be involved in causing this problem. I know it is almost impossible to say what I did wrong based on the provided description, but I would be glad for any tips on how I can debug it and find out the reason of this problem.
18 replies
CC#
Created by no >> body on 3/14/2023 in #help
❔ ASP.NET Core Identity OTP creation date
So, currently, I have an authentication server (not with IdentityServer4/Duende). I have enabled two-factor authentication, and I want users to be able to send sms with otp only once per 60 seconds. From what I see, there is no information in AspNetUserTokens about the date it was generated. So I have an idea to expand this table with an additional column with a time stamp, so I can track when otp was created and prevent user from sending a new one if it was created recently. I've added a new migration and recreated a database, and now table AspNetUserTokens contains a new row which indicates creation date. Now I'm trying to figure out how to make Identity use my new class with a Created property. I'm also wondering if I'm in a right direction or it should be implemented in the different way. Would be glad to hear any ideas/advices.
5 replies
CC#
Created by no >> body on 1/9/2023 in #help
✅ Replacing Linq.Dynamic
I am trying to replace the System.Linq.Dynamic.Core package with regular LINQ in my ASP.NET Core application. I have a method that applies filtering, sorting, and pagination to a queryable collection of entities, using the System.Linq.Dynamic.Core package. Here is the code from my method:
if (!string.IsNullOrEmpty(filter))
{
var filterVal = (JObject)JsonConvert.DeserializeObject(filter);
var t = new T();
foreach (var f in filterVal)
if (t.GetType().GetProperty(f.Key)?.PropertyType == typeof(string))
entityQuery = entityQuery.Where($"{f.Key}.Contains(@0)", f.Value.ToString());
else
entityQuery = entityQuery.Where($"{f.Key} == @0", f.Value.ToString());
}

var count = entityQuery.Count();

if (!string.IsNullOrEmpty(sort))
{
var sortVal = JsonConvert.DeserializeObject<List<string>>(sort);
var condition = sortVal.First();
var order = sortVal.Last() == "ASC" ? "" : "descending";
entityQuery = entityQuery.OrderBy($"{condition} {order}");
}
if (!string.IsNullOrEmpty(filter))
{
var filterVal = (JObject)JsonConvert.DeserializeObject(filter);
var t = new T();
foreach (var f in filterVal)
if (t.GetType().GetProperty(f.Key)?.PropertyType == typeof(string))
entityQuery = entityQuery.Where($"{f.Key}.Contains(@0)", f.Value.ToString());
else
entityQuery = entityQuery.Where($"{f.Key} == @0", f.Value.ToString());
}

var count = entityQuery.Count();

if (!string.IsNullOrEmpty(sort))
{
var sortVal = JsonConvert.DeserializeObject<List<string>>(sort);
var condition = sortVal.First();
var order = sortVal.Last() == "ASC" ? "" : "descending";
entityQuery = entityQuery.OrderBy($"{condition} {order}");
}
I'm tried something like this
entityQuery = entityQuery.OrderBy(e => e.GetType().GetProperty(condition).GetValue(e));
entityQuery = entityQuery.OrderBy(e => e.GetType().GetProperty(condition).GetValue(e));
But this obviously doesn't work. Is there a way to sort a queryable collection of entities based on a property, using regular LINQ and Entity Framework Core? Downloading all entities to the memory and sorting them in the asp.net core app is not an option.
9 replies
CC#
Created by no >> body on 12/20/2022 in #help
✅ ASP.NET Core form with two submit buttons
I have a form
<form asp-route="MultiFactorAuthenticate">
<div class="space-y-7">
<div class="text-lg">
Enter 6-digit verification code sent to your mobile
</div>
<input type="hidden" asp-for="@Model.Command.RedirectTo"/>
<input type="hidden" asp-for="@Model.IsRegistrationVerification"/>

<div id="otp-section" class="form-group text-center mb-5">
<input asp-for="@Model.Command.OtpString"
type="text"
title="Otp"
placeholder=""
autocomplete="one-time-code"
maxLength="6"
inputmode="numeric"
autofocus
class="form-input text-xl appearance-none numeric-plain"/>
</div>
<div class="text-center mb-5">
<button id="verify" type="submit" class="btn-control with-loader">
Verify
</button>
</div>
<div class="text-center font-lg">
Didn't receive the code?<br/>
<button type="submit" class="font-medium text-blue-500 hover:text-blue-400" asp-page-handler="ResendCode">Send code again</button><br/>
</div>
</div>
</form>
<form asp-route="MultiFactorAuthenticate">
<div class="space-y-7">
<div class="text-lg">
Enter 6-digit verification code sent to your mobile
</div>
<input type="hidden" asp-for="@Model.Command.RedirectTo"/>
<input type="hidden" asp-for="@Model.IsRegistrationVerification"/>

<div id="otp-section" class="form-group text-center mb-5">
<input asp-for="@Model.Command.OtpString"
type="text"
title="Otp"
placeholder=""
autocomplete="one-time-code"
maxLength="6"
inputmode="numeric"
autofocus
class="form-input text-xl appearance-none numeric-plain"/>
</div>
<div class="text-center mb-5">
<button id="verify" type="submit" class="btn-control with-loader">
Verify
</button>
</div>
<div class="text-center font-lg">
Didn't receive the code?<br/>
<button type="submit" class="font-medium text-blue-500 hover:text-blue-400" asp-page-handler="ResendCode">Send code again</button><br/>
</div>
</div>
</form>
The problem with this code is next: 1. I'm trying to log in, login requires sms code. The application sends me a code 2. I click "Send code again", and application generates a new code and sends it to me 3. I enter the second code and click Verify button, but the application calls ResendCode handler and sends me a new code again. Any idea why it can happen?
5 replies
CC#
Created by no >> body on 12/12/2022 in #help
✅ Iteration through a list in csproj
26 replies
CC#
Created by no >> body on 11/26/2022 in #help
❔ IAsyncEnumerable and IQueriable unit testing
I have an interface of the repository, which has a method Query<T>. This method should return IQueryble<T> Now I wrote a service where I use this method to get some data from a database. In this service, I'm doing something like that.
var items = repository.Query<MyItem>().Where(x => blah blah).ToListAsync();
var items = repository.Query<MyItem>().Where(x => blah blah).ToListAsync();
So now I need to write a unit test for it. And this is a problem because I'm dealing with IAsyncEnumerables here. I have a mock setup
var items = new List<MyItem> { ... };
repositoryMock.Setup(x => x.Query<MyItem>()).Returns(items.AsQueryable());
var items = new List<MyItem> { ... };
repositoryMock.Setup(x => x.Query<MyItem>()).Returns(items.AsQueryable());
But it doesn't work because List<T> obviously doesn't implement IAsyncEnumerable. Any ideas on how to make it work?
3 replies
CC#
Created by no >> body on 11/3/2022 in #help
OnAppendCookie callback doesn't work
I have an ASP.NET Core project, which uses IdentityServer4. In my configuration I have CookiePolicyOptions which contains the next setup:
services.Configure<CookiePolicyOptions>(
option =>
{
option.MinimumSameSitePolicy = SameSiteMode.None;
option.HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always;
option.OnAppendCookie = cookieContext =>
{
Console.WriteLine("Cookie appended: " + cookieContext.CookieName);
};
option.OnDeleteCookie = context =>
{
Console.WriteLine("Cookie deleted: " + context.CookieName);
};
});
services.Configure<CookiePolicyOptions>(
option =>
{
option.MinimumSameSitePolicy = SameSiteMode.None;
option.HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always;
option.OnAppendCookie = cookieContext =>
{
Console.WriteLine("Cookie appended: " + cookieContext.CookieName);
};
option.OnDeleteCookie = context =>
{
Console.WriteLine("Cookie deleted: " + context.CookieName);
};
});
For some reason, I can't reach the code from the OnAppendCooie and OnDeleteCookie. I've also added a custom filter to append a new cookie to the response. The behavior was still the same - OnAppendCookie and OnDeleteCookie were not called.
6 replies
CC#
Created by no >> body on 10/27/2022 in #help
IdentityServer antiforgery token bypass
I have an Identity Server instance. One of the application need's to render an identity server pages (login, forgot password, 2fa window, etc.) in the iframe. The problem is that I use an anti-forgery token that prevents all calls since the URL differs. So I'm thinking about having something like a white list of domains that can bypass forgery token validation. Are there any built-in solutions for that? Or would appreciate advice about how to implement this logic.
8 replies
CC#
Created by no >> body on 9/1/2022 in #help
dotnet restore to ignore packages
I have several projects in my solution: 1. Web API 2. Worker service 3. Application layer and many others Web API and Wonder service have a reference to the application layer. The application layer project contains dependencies from an external package source, which I use only with the Worker service. Now I need to create a docker image for WebAPI, and to do that, I need to call 'dotnet restore' in my Dockerfile. Is it possible to ignore packages from external package sources if I don't need them in the project I want to build? Because now, to build an image, I need to provide a key for the NuGet source, which I will not use with WebAPI.
2 replies
CC#
Created by no >> body on 8/29/2022 in #help
dotnet format and jetbrains rules
I'm wondering if it is possible for dotnet format to include ReSharper rules from .editconfig. I have .editconfig with a mixture of standard and JetBrains rules in my project. So, for example, I have the rule:
resharper_max_initializer_elements_on_line = 4
resharper_max_initializer_elements_on_line = 4
And I have an object with 4 initializers in a row. When I run dotnet format --verify-no-changes, it shows me I need to move all initializations on the separated lines.
\Tests\Queries\GetProcessingStatusTests.cs(26,43): error WHITESPACE: Fix whitespace formatting. Replace 1 characters with '\r\n\s\s\s\s\s\s\s\s\s\s\s\s\s\s\s\s'.
\Tests\Queries\GetProcessingStatusTests.cs(26,43): error WHITESPACE: Fix whitespace formatting. Replace 1 characters with '\r\n\s\s\s\s\s\s\s\s\s\s\s\s\s\s\s\s'.
2 replies