kopuo
kopuo
CC#
Created by kopuo on 11/10/2023 in #help
❔ Validation of appsettings configuration before running the application
Hello. I would like to validate entries in the appsettings configuration at application startup to check whether all required entries are set. I'm trying to do this with services.ValidateOnStart():
builder.Services
.AddOptions<ServiceBusSettings>()
.Bind(builder.Configuration.GetSection("Infrastructure:ServiceBus"))
.Validate(options =>
{
var properties = typeof(ServiceBusSettings).GetProperties();
foreach (var property in properties)
{
if (property.GetValue(options) == null)
return false;
}
return true;
}, $"None of the {typeof(ServiceBusSettings).Name} properties can be empty")
.ValidateOnStart();
builder.Services
.AddOptions<ServiceBusSettings>()
.Bind(builder.Configuration.GetSection("Infrastructure:ServiceBus"))
.Validate(options =>
{
var properties = typeof(ServiceBusSettings).GetProperties();
foreach (var property in properties)
{
if (property.GetValue(options) == null)
return false;
}
return true;
}, $"None of the {typeof(ServiceBusSettings).Name} properties can be empty")
.ValidateOnStart();
The problem here is that when building the application I use, among others: setting the AzureServiceBus host
...
cfg.Host(serviceBusConnectionString) //here it throws ArgumentNullException
...
cfg.Host(serviceBusConnectionString) //here it throws ArgumentNullException
I would like validation to be performed first, and if ServiceBusConnectionString is not set, return the appropriate validation message and not exceptions in other configuration places. Do you know any methods for such initial validation?
6 replies
CC#
Created by kopuo on 6/2/2023 in #help
❔ How to recognize the client that connects to me in the API?
I have a WebApi service that 2 other APIs are connecting to. How in the first one can I recognize which API is making a request to me? HttpContext.Request points to the address of the current Host, not the client
3 replies
CC#
Created by kopuo on 3/1/2023 in #help
❔ Calling extensions method in linq query
Hi, is there any way to use my own extension method in a linq to query? With the approach below, it throws me an exception about the method not being able to be translated to SQL. If I add ..AsEnumerable().Select(...).AsQueryable() will it be a correct solution?
var productsQuery = _dbContext.Products.AsNoTracking().Select(p => new ProductModel
{
Name = p.Name,
Quantity = p.Quantity.MyExtensionMethod(), // p.Quantity == null ? "None" : p.Quantity.ToString()
Price = p.Price
});
var productsQuery = _dbContext.Products.AsNoTracking().Select(p => new ProductModel
{
Name = p.Name,
Quantity = p.Quantity.MyExtensionMethod(), // p.Quantity == null ? "None" : p.Quantity.ToString()
Price = p.Price
});
9 replies
CC#
Created by kopuo on 12/8/2022 in #help
❔ How to use BeginTransaction in repository from infrastructure
I have this code in CommandHandler (Application layer):
using var transaction = _ProductRepository.BeginTransaction();
using var transaction = _ProductRepository.BeginTransaction();
Repository (Infrastructure layer):
public IDbContextTransaction BeginTransaction()
{
return _dbContext.Database.BeginTransaction();
}
public IDbContextTransaction BeginTransaction()
{
return _dbContext.Database.BeginTransaction();
}
Interface repo (Domain layer):
public interface IProductRepository
{
...
IDbContextTransaction BeginTransaction();
}
public interface IProductRepository
{
...
IDbContextTransaction BeginTransaction();
}
I don't want to use IDbContextTransaction in the domain layer because it uses a reference to Microsoft.EntityFrameworkCore.Storage and I would like to avoid such in this layer. Is there any neat way to use BeginTransaction in some repository? I also don't want to directly apply dbContext in my CommandHandler, but do this by infrastructure layer
3 replies
CC#
Created by kopuo on 11/10/2022 in #help
❔ EntityFramework does not track changes for the select projection
Hey, With Select (), I only extracted the data I needed, which I want to update later. However, after SaveChanges () is executed, the value in DB does not change.
var product = await _dbContext.Products
.Include(x => x.Additionals)
.Where(p => p.Id == Id)
.Select(x => new Product { Id = x.Id, Name = x.Name, Additionals = x.Additionals })
.SingleOrDefaultAsync();

product.Name = "ChangedName";
await _dbContext.SaveChangesAsync(); //no database changes
var product = await _dbContext.Products
.Include(x => x.Additionals)
.Where(p => p.Id == Id)
.Select(x => new Product { Id = x.Id, Name = x.Name, Additionals = x.Additionals })
.SingleOrDefaultAsync();

product.Name = "ChangedName";
await _dbContext.SaveChangesAsync(); //no database changes
On the other hand, with such a code, the change already appears correctly
var product = await _dbContext.Products
.Include(x => x.Additionals).SingleOrDefaultAsync(p => p.Id == Id);

product.Name = "ChangedName";
await _dbContext.SaveChangesAsync(); //correct changes
var product = await _dbContext.Products
.Include(x => x.Additionals).SingleOrDefaultAsync(p => p.Id == Id);

product.Name = "ChangedName";
await _dbContext.SaveChangesAsync(); //correct changes
Can I somehow make changes to the truncated retrieved data like in the first code?
10 replies
CC#
Created by kopuo on 11/9/2022 in #help
❔ How to Select Data with Included nested objects?
When extracting data from the database for the main object, I want to extract only the necessary data. My code now:
_dbContext.Units // I need only two fields from here, not whole object
.Include(p => p.Shops)
.ThenInclude(p => p.Department)
.ThenInclude(p => p.Products.Where(i => i.Availability == available))
.AsNoTracking()
.SingleOrDefaultAsync(p => p.UnitId == unitId);
_dbContext.Units // I need only two fields from here, not whole object
.Include(p => p.Shops)
.ThenInclude(p => p.Department)
.ThenInclude(p => p.Products.Where(i => i.Availability == available))
.AsNoTracking()
.SingleOrDefaultAsync(p => p.UnitId == unitId);
I want something like this:
_dbContext.Units
.Select(x => new
{
UnitId = x.UnitId,
Name = x.Name
})
.Include(p => p.Shops)
.ThenInclude(p => p.Department)
.ThenInclude(p => p.Products.Where(i => i.Availability == available))
.AsNoTracking()
.SingleOrDefaultAsync(p => p.UnitId == unitId);
_dbContext.Units
.Select(x => new
{
UnitId = x.UnitId,
Name = x.Name
})
.Include(p => p.Shops)
.ThenInclude(p => p.Department)
.ThenInclude(p => p.Products.Where(i => i.Availability == available))
.AsNoTracking()
.SingleOrDefaultAsync(p => p.UnitId == unitId);
3 replies
CC#
Created by kopuo on 9/19/2022 in #help
ResponseCache duration in minutes instead seconds
Can I set or convert values from seconds to minutes for the [ResponseCache (Duration = 3600)] attribute? I would like to eventually save something like [ResponseCache (Duration = 60)] where 60 is minutes.
13 replies
CC#
Created by kopuo on 9/14/2022 in #help
❔ Using the output cache in a web api
I have a method to get a pdf file and want to use output cache on it. The [OutputCache] attribute only works for Mvc methods but I use API set to .Net 6. Is there any way to use the output cache or do I need to write a custom attribute to handle it?
2 replies
CC#
Created by kopuo on 9/5/2022 in #help
How to use custom DateTimeConverter for selected endpoints?
I have the following converter which is responsible for reading and returning dates in UTC format:
public class DateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dateTime = DateTime.Parse(reader.GetString());

return dateTime.ToUniversalTime();
}

public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(DateTime.SpecifyKind(value, DateTimeKind.Utc));
}
}
public class DateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dateTime = DateTime.Parse(reader.GetString());

return dateTime.ToUniversalTime();
}

public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(DateTime.SpecifyKind(value, DateTimeKind.Utc));
}
}
I am currently using it in program.cs as follows:
.AddJsonOptions(options =>
{ options.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
});
.AddJsonOptions(options =>
{ options.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
});
But this causes the converter to be used throughout the system. I would like only in selected enpoints. How can I use it like this?
3 replies
CC#
Created by kopuo on 9/1/2022 in #help
receiving, saving and returning UTC DateTime
Hi. In Api I get a DateTime from the client in UTC format - with "Z" at the end of the string. I want to save this date in UTC format in the database and then also return it in response in UTC format. I used such a converter on input and output:
public class DateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dateTime = DateTime.Parse(reader.GetString());

return DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
}

public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(DateTime.SpecifyKind(value, DateTimeKind.Utc));
}
}
public class DateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dateTime = DateTime.Parse(reader.GetString());

return DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
}

public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(DateTime.SpecifyKind(value, DateTimeKind.Utc));
}
}
I use it in program.cs:
AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
});
AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
});
Is this action sufficient to save the incoming date in UTC format to the database? Incoming DateTime have Kind = UTC, as do outgoing ones with 'Z' at the end.
1 replies
CC#
Created by kopuo on 8/30/2022 in #help
How to get the date from the database as UTC?
hi. In my api I add dates to the database in UTC format, but when I take them out of the database and want to return, they are not in UTC format (no 'Z' at the end). Is it possible to get them some UTC without conversion?
8 replies
CC#
Created by kopuo on 8/22/2022 in #help
DbContext.SaveChangesAsync has no effect on the collection of changed objects
Hi. I get products collection from dbContext, change some values and want to save it in the database, but after SaveChangesAsync () is done in the database there are no changes. When previewing objects from dbContext at the end, I also cannot see the edited fields:
var products = await _dbContext.Products.AsEnumerableAsync()

foreach(var p in products)
{
if(p.Price == 0)
p.Price = 10
}

await _dbContext.AddRangeAsync(products);

await _dbContext.SaveChangesAsync();
var products = await _dbContext.Products.AsEnumerableAsync()

foreach(var p in products)
{
if(p.Price == 0)
p.Price = 10
}

await _dbContext.AddRangeAsync(products);

await _dbContext.SaveChangesAsync();
Product is an entity btw.
8 replies
CC#
Created by kopuo on 8/18/2022 in #help
Creating a new view or using unnecessary data?
Hi. I have a view made and used that returns 15 data fields to me. This view is already in use on the system in many places:
var productData = await dbContext.ApiProductsView.AsNoTracking()
.ToListAsync(cancellationToken);
var productData = await dbContext.ApiProductsView.AsNoTracking()
.ToListAsync(cancellationToken);
Now I need to return 4 data fields that this view has. And the question is, will it be more optimal to use this ready view and remap only the necessary fields, or to create a new view only for these 4 data? And would the following usage be correct and optimal?
var productData = await dbContext.ApiProductsView.AsNoTracking()
.Select(x => new ProductInfo
{
field1 = x.field1,
field2 = x.field2,
field3 = x.field3,
field3 = x.field3
})
.ToListAsync(cancellationToken);
var productData = await dbContext.ApiProductsView.AsNoTracking()
.Select(x => new ProductInfo
{
field1 = x.field1,
field2 = x.field2,
field3 = x.field3,
field3 = x.field3
})
.ToListAsync(cancellationToken);
1 replies