engineertdog
engineertdog
CC#
Created by engineertdog on 6/27/2024 in #help
Update configuration in memory
I have the class below where I'm trying to provide default values if a user doesn't configure them in appsettings. Supposedly, this is supposed to work, but it's not working in practices. Do you have any recommendations to either fix this, or to just use default values regardless and screw the config?
c#
public static class MainelyLog {
private readonly static IConfigurationRoot _configuration;
private readonly static string _appDirectory = AppDomain.CurrentDomain.BaseDirectory;

static MainelyLog() {
_configuration = new ConfigurationBuilder()
.SetBasePath(_appDirectory)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
}

public static void SetupLogging(string defaultLogPath) {
IConfigurationSection? logConfig = _configuration.GetSection("Serilog:WriteTo")
.GetChildren()
.FirstOrDefault(c => c["Name"] == "File");

if (logConfig != null && !Path.IsPathFullyQualified(logConfig["Args:path"])) {
string logPath = logConfig["Args:path"] ?? defaultLogPath;
if (logPath.StartsWith(".\\")) { logPath = logPath[2..]; }
logConfig["Args:path"] = Path.Combine(_appDirectory, logPath);
}

Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(_configuration)
.CreateLogger();
}
}
c#
public static class MainelyLog {
private readonly static IConfigurationRoot _configuration;
private readonly static string _appDirectory = AppDomain.CurrentDomain.BaseDirectory;

static MainelyLog() {
_configuration = new ConfigurationBuilder()
.SetBasePath(_appDirectory)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
}

public static void SetupLogging(string defaultLogPath) {
IConfigurationSection? logConfig = _configuration.GetSection("Serilog:WriteTo")
.GetChildren()
.FirstOrDefault(c => c["Name"] == "File");

if (logConfig != null && !Path.IsPathFullyQualified(logConfig["Args:path"])) {
string logPath = logConfig["Args:path"] ?? defaultLogPath;
if (logPath.StartsWith(".\\")) { logPath = logPath[2..]; }
logConfig["Args:path"] = Path.Combine(_appDirectory, logPath);
}

Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(_configuration)
.CreateLogger();
}
}
The purpose of doing this is to account for relative paths not being correct when running interactively vs as a service.
80 replies
CC#
Created by engineertdog on 6/26/2024 in #help
Uncaught exception
I have the following code as part of a class I'm building for impersonation. It works, but the UnauthorizedAccessException is being marked as unhandled. If I hit continue, it all works as expected. But why is it unhandled and how can I address that?
c#
try {
WindowsIdentity.RunImpersonated(_safeAccessTokenHandle, () => {
// This will throw if the impersonation fails
//string impersonatedUser = WindowsIdentity.GetCurrent().Name;
//Console.WriteLine("Impersonation successful, current user: " + impersonatedUser);

try {
string securePath = "";
if (!Directory.Exists(securePath)) {
throw new UnauthorizedAccessException($"Access to {securePath} was denied.");
}
} catch {
throw;
}
});
} catch (Exception ex) {
Console.WriteLine($"Impersonation validation failed: {ex.Message}");
Dispose();
// Re-throw to ensure the exception is handled by the caller
throw;
}
c#
try {
WindowsIdentity.RunImpersonated(_safeAccessTokenHandle, () => {
// This will throw if the impersonation fails
//string impersonatedUser = WindowsIdentity.GetCurrent().Name;
//Console.WriteLine("Impersonation successful, current user: " + impersonatedUser);

try {
string securePath = "";
if (!Directory.Exists(securePath)) {
throw new UnauthorizedAccessException($"Access to {securePath} was denied.");
}
} catch {
throw;
}
});
} catch (Exception ex) {
Console.WriteLine($"Impersonation validation failed: {ex.Message}");
Dispose();
// Re-throw to ensure the exception is handled by the caller
throw;
}
13 replies
CC#
Created by engineertdog on 6/25/2024 in #help
✅ .net8 impersonate
c#
bool returnValue = LogonUser("", "", "",
LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT,
out safeAccessTokenHandle);

WindowsIdentity.RunImpersonated(
safeAccessTokenHandle,
// User action
() => {
// Check the identity.
Console.WriteLine("During impersonation: " + WindowsIdentity.GetCurrent().Name);
}
);
c#
bool returnValue = LogonUser("", "", "",
LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT,
out safeAccessTokenHandle);

WindowsIdentity.RunImpersonated(
safeAccessTokenHandle,
// User action
() => {
// Check the identity.
Console.WriteLine("During impersonation: " + WindowsIdentity.GetCurrent().Name);
}
);
This logs the current user and not the identity that's impersonated. I need to be able to execute certain tasks as users. Is this just not reasonable with net8? Nevermind, the current identity lied. That was code taken from the MS docs website. If I do an action, then it does use that context. Misleading that the current identity isn't correct.
1 replies
CC#
Created by engineertdog on 6/24/2024 in #help
✅ Content would exceed Content-Length
I have this code to add files to an HttpClient to send API requests to an external API.
c#
public void AddFile(string filePath, string fileName) {
// Open the file stream
FileStream fileStream = new(filePath, FileMode.Open, FileAccess.Read);
_fileStreams.Add(fileStream);

// Create stream content and add it to the form data.
StreamContent streamContent = new(fileStream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
_formData.Add(streamContent, "file", fileName);
}
c#
public void AddFile(string filePath, string fileName) {
// Open the file stream
FileStream fileStream = new(filePath, FileMode.Open, FileAccess.Read);
_fileStreams.Add(fileStream);

// Create stream content and add it to the form data.
StreamContent streamContent = new(fileStream);
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
_formData.Add(streamContent, "file", fileName);
}
The problem I have, is that I am getting the error Unable to write content to request stream; content would exceed Content-Length. Now, in some cases, the automated Content-Length value being set was incorrect. I have tried manually setting the content length with streamContent.Headers.ContentLength = fileStream.Length and while this does correctly set the size, I still get the same error that it would exceed the length. I'm not sure why that's occurring.
3 replies
CC#
Created by engineertdog on 2/24/2024 in #help
EF6 Relationships
I have two classes built in EF Core, that I used to scaffold the database and use in the frontend Blazor app.
c#
public class StreamPointListenerStep {
public Guid Id { get; set; } = Guid.NewGuid();
//....
public StreamPointIntegrationELogger? StreamPointIntegrationELogger { get; set; } = null;
}

public class StreamPointIntegrationELogger {
public Guid Id { get; set; } = Guid.NewGuid();

[ForeignKey(nameof(StreamPointListenerStep))]
public Guid StepId { get; set; }
public StreamPointListenerStep? StreamPointListenerStep { get; set; } = null;
//...
}
c#
public class StreamPointListenerStep {
public Guid Id { get; set; } = Guid.NewGuid();
//....
public StreamPointIntegrationELogger? StreamPointIntegrationELogger { get; set; } = null;
}

public class StreamPointIntegrationELogger {
public Guid Id { get; set; } = Guid.NewGuid();

[ForeignKey(nameof(StreamPointListenerStep))]
public Guid StepId { get; set; }
public StreamPointListenerStep? StreamPointListenerStep { get; set; } = null;
//...
}
Now, building and using this in Blazor is fine. However, I also need the table in a .NET Framework app. So I've ported the DB model to EF6 just to simply use the context for accessing the database and the models without writing the queries manually. However, EF6 refuses to work with this due to the relationship. It throws an error for Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'. What solutions are there for getting around this? I have to use .NET Framework, and building an API is overhead that's just not needed.
115 replies
CC#
Created by engineertdog on 2/23/2024 in #help
C# 8 logging
No description
6 replies
CC#
Created by engineertdog on 2/22/2024 in #help
Best way to model different options in EF Core
I have a class that's used to define the integration parameters for a particular process. Now, I have integration options A,B,C, etc each of which correspond to different tables with different IDs I need to populate on my class. ex
c#
public class myclass {
public string MyParam1 { get; set; }
public string MyParam2 { get; set; }
public string MyParam3 { get; set; }

// Integration A
public Guid PackageId { get; set; }
public Guid LocationId { get; set; }
public Guid ScreenElementId { get; set; }
// Integration B
public Guid PackageId { get; set; }
public Guid LocationId { get; set; }
public Guid ScreenElementId { get; set; }
// etc
}
c#
public class myclass {
public string MyParam1 { get; set; }
public string MyParam2 { get; set; }
public string MyParam3 { get; set; }

// Integration A
public Guid PackageId { get; set; }
public Guid LocationId { get; set; }
public Guid ScreenElementId { get; set; }
// Integration B
public Guid PackageId { get; set; }
public Guid LocationId { get; set; }
public Guid ScreenElementId { get; set; }
// etc
}
Now, only 1 integration is supported for each instance of myclass. I could in theory define each available integration's FK references in this table, but there must be a better way to do this?
c#
public class myclass {
public string MyParam1 { get; set; }
public string MyParam2 { get; set; }
public string MyParam3 { get; set; }

// Integration
public IntegrationType Integration { get; set; } // A,B,C,etc
public Guid IntegrationId { get; set; } // But wouldn't this just then be a table with all references, like in the previous example?
}
c#
public class myclass {
public string MyParam1 { get; set; }
public string MyParam2 { get; set; }
public string MyParam3 { get; set; }

// Integration
public IntegrationType Integration { get; set; } // A,B,C,etc
public Guid IntegrationId { get; set; } // But wouldn't this just then be a table with all references, like in the previous example?
}
5 replies
CC#
Created by engineertdog on 2/8/2024 in #help
Variable type passed to generic
Is there any way to get around this being an error?
c#
Type type = Type.GetType("OSIsoft.PI.Net, PIThreadInfo");

return powershell.Invoke<type>()
c#
Type type = Type.GetType("OSIsoft.PI.Net, PIThreadInfo");

return powershell.Invoke<type>()
33 replies
CC#
Created by engineertdog on 2/7/2024 in #help
C# executed in NodeJS
I have a 3rd party vendor SDK that's written in .NET Framework. They're working on a NET Core version, but I'd still like to look at the possible usage with NodeJS. Are there any performance or other issues to worry about? The main reason I look to use the vendor's SDK instead of their API is performance between the technologies they offer, where the API is based on the SDK and is much slower to use.
10 replies
CC#
Created by engineertdog on 2/5/2024 in #help
.HasPrincipalKey -> Specify different column name
I need to use .HasPrincipalKey in Fluent, but I need the resulting column to be named differently from what the Fluent API wants to use. I don't see an option to override the column name to something different?
5 replies
CC#
Created by engineertdog on 2/5/2024 in #help
FK on Guid
I have the following two classes
c#
public class PiCollectiveIdentity {
public Guid Id { get; set; } = new Guid();
public long IdentityId { get; set; }
public required string Name { get; set; }
[ForeignKey("IdentityName")]
public IList<PiCollectiveIdentityMapping> Mappings { get; set; } = new List<PiCollectiveIdentityMapping>();
}

public class PiCollectiveIdentityMapping{
public Guid Id { get; set; } = new Guid();
public DateTime CollectionDate { get; set; } = DateTime.UtcNow;
public required string IdentityName { get; set; }
public PiCollectiveIdentity ? Identity { get; set; } = null;
}
c#
public class PiCollectiveIdentity {
public Guid Id { get; set; } = new Guid();
public long IdentityId { get; set; }
public required string Name { get; set; }
[ForeignKey("IdentityName")]
public IList<PiCollectiveIdentityMapping> Mappings { get; set; } = new List<PiCollectiveIdentityMapping>();
}

public class PiCollectiveIdentityMapping{
public Guid Id { get; set; } = new Guid();
public DateTime CollectionDate { get; set; } = DateTime.UtcNow;
public required string IdentityName { get; set; }
public PiCollectiveIdentity ? Identity { get; set; } = null;
}
Where each database record will have it's own unique ID, but the relationship between the two records is based on name (due to pulling the data from a 3rd party system). However, this throws an error when attempting to migrate for 'PiCollectiveIdentityMapping.Mappings' with foreign key properties {'IdentityName' : string} cannot target the primary key {'Id' : Guid} because it is not compatible What is the proper way to build the relationship?
7 replies
CC#
Created by engineertdog on 12/21/2023 in #help
Persist data between Quartz Execution
I need to be able to persist data between instance executions. I have to tie two separate jobs together through a common identifier. The approach below does not work. From my understanding, I will need to create a new schedule based off the old one in order to persist data?
c#
public virtual async Task Execute(IJobExecutionContext context) {
JobDataMap dataMap = context.MergedJobDataMap;
long count = dataMap.GetLong("jobIterationNumber");
count++;
dataMap.Put("jobIterationNumber", count);
Execute();

// Instead, build a new schedule based on the old one?
var oldMap = oldTrigger.JobDataMap;
oldMap["jobIterationNumber"] = count;

var oldTrigger = context.Trigger;
var newTrigger = TriggerBuilder.Create()
.WithIdentity(oldTrigger.Key.Name, oldTrigger.Key.Group)
.UsingJobData(oldTrigger.JobDataMap)
.WithSchedule(oldTrigger.GetScheduleBuilder())
.Build();
await context.Scheduler.ScheduleJob(newTrigger);
}
c#
public virtual async Task Execute(IJobExecutionContext context) {
JobDataMap dataMap = context.MergedJobDataMap;
long count = dataMap.GetLong("jobIterationNumber");
count++;
dataMap.Put("jobIterationNumber", count);
Execute();

// Instead, build a new schedule based on the old one?
var oldMap = oldTrigger.JobDataMap;
oldMap["jobIterationNumber"] = count;

var oldTrigger = context.Trigger;
var newTrigger = TriggerBuilder.Create()
.WithIdentity(oldTrigger.Key.Name, oldTrigger.Key.Group)
.UsingJobData(oldTrigger.JobDataMap)
.WithSchedule(oldTrigger.GetScheduleBuilder())
.Build();
await context.Scheduler.ScheduleJob(newTrigger);
}
1 replies
CC#
Created by engineertdog on 12/15/2023 in #help
✅ Convert 3rd party Dictionary to usable variable
No description
4 replies
CC#
Created by engineertdog on 12/14/2023 in #help
SqlBulkCopy IList
What frameworks are available for performing bulk copy using an IList as the input? There's DataTable and FastMember. I have used FastMember, but it's outdated and I'd rather use something current.
5 replies
CC#
Created by engineertdog on 12/13/2023 in #help
What version of PowerShell.Create() is created?
PowerShell ps = PowerShell.Create().AddCommand("$PSVersionTable.PSVersion");
ps.Invoke();
PowerShell ps = PowerShell.Create().AddCommand("$PSVersionTable.PSVersion");
ps.Invoke();
This throws an error, stating that $PSVersionTable is not a function. I have PowerShell 7 installed where the code is running, and I've verified the commands still work there. So what is the SDK creating behind the scenes that's not compatible?
24 replies
CC#
Created by engineertdog on 12/12/2023 in #help
Standard library usage problem
No description
4 replies
CC#
Created by engineertdog on 12/12/2023 in #help
Send message from one app to another
What's the easiest method for sharing data between applications? MessageQueue looked promising, but it doesn't appear available in Core. I need to be able to send data between different applications that are using both Core & Framework. So, Core<->Core, Core<->Framework communication. Can't use cloud services, although RabbitMQ could be used if there's nothing well supported natively or current on Nuget.
14 replies
CC#
Created by engineertdog on 12/8/2023 in #help
Get output of PowerShell into IList<class>
No description
3 replies
CC#
Created by engineertdog on 12/5/2023 in #help
Raw SQL Query Question
I have a raw SQL query that I need to execute against a database that's external to my application. The query is expected to return >5,000,000 records. Therefore, returning the records in memory (list) causes the application to crash due to running out of memory, even on a server with 122GB. Is it possible to enumerate over the records instead, so that I don't have to deal with them all in memory?
c#
public IList<R> GetExternalResults(string con) {
using (DbContext tempContext = new DbContext(con)) {
return tempContext.Database.SqlQuery<R>("SELECT * FROM xx").ToList();
}
}

Parallel.ForEach(GetExternalResults(con), record => {
this.AddRow(record);
this.AddBulkRecords(record); // if batch > xx, then save the record using SQL Bulk Copy
});
c#
public IList<R> GetExternalResults(string con) {
using (DbContext tempContext = new DbContext(con)) {
return tempContext.Database.SqlQuery<R>("SELECT * FROM xx").ToList();
}
}

Parallel.ForEach(GetExternalResults(con), record => {
this.AddRow(record);
this.AddBulkRecords(record); // if batch > xx, then save the record using SQL Bulk Copy
});
19 replies
CC#
Created by engineertdog on 11/29/2023 in #help
Publish .NET Framework App
When publishing a .NET Framework Console app, I get setup.exe, <app-name>.application, and then the Application Files folder with the information for that version. 1. How do I include another project (static files) in the output? 2. Do I only need to provide end-users with the setup.exe, or do I need to give them all of the files from the latest version under Application Files?
1 replies