1. SingletonサービスがScopedサービスを解決できないエラー
「Cannot resolve scoped service 'AlgoTag.Models.AlgoContext' from root provider.」というエラーが発生することがあります。これは、ASP.NET Coreの依存関係の注入(DI)におけるライフサイクルの問題です。
通常、ライフサイクルが長いSingletonサービスが、ライフサイクルが短いScopedサービスに依存する場合に発生します。SingletonサービスがScopedサービスを参照すると、そのScopedサービスもSingletonのスコープに引き上げられてしまい、DIコンテナが正しく解決できなくなるためです。
2. IISからLinuxシステムの共有フォルダにアクセスする方法
IISでホストされているASP.NET CoreアプリケーションからLinuxシステムのSamba共有フォルダにアクセスするには、主に2つの方法があります。
一つは、SharpCifsなどのライブラリを利用する方法です。もう一つは、Windows APIを用いてユーザーを偽装する方法です。ここでは、後者の方法を実装するC#コードを示します。
using System;
using System.Runtime.InteropServices;
public class LinuxShareAccessor : IDisposable
{
private IntPtr _tokenHandle;
private bool _disposed = false;
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string userName, string domain, string passWord, int logonType, int logonProvider, ref IntPtr tokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool ImpersonateLoggedOnUser(IntPtr tokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle);
public LinuxShareAccessor(string userName, string passWord, string serverAddress)
{
_tokenHandle = IntPtr.Zero;
if (!LogonUser(userName, serverAddress, passWord, 9, 0, ref _tokenHandle))
{
throw new Exception($"LogonUser failed with error code: {Marshal.GetLastWin32Error()}");
}
if (!ImpersonateLoggedOnUser(_tokenHandle))
{
CloseHandle(_tokenHandle);
throw new Exception($"ImpersonateLoggedOnUser failed with error code: {Marshal.GetLastWin32Error()}");
}
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
RevertToSelf();
if (_tokenHandle != IntPtr.Zero)
{
CloseHandle(_tokenHandle);
}
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
3. AJAXで取得した画像データをjQueryで表示する方法
バックエンドからAJAX経由でimage/jpegなどのバイナリ画像データを取得し、jQueryでページ上に表示するには、`responseType`を`'blob'`に設定する必要があります。取得したBlobオブジェクトを`FileReader`で読み込み、その結果を`background-image`のURLとして設定します。
function loadAndDisplayImage(imageIndex) {
$.ajax({
url: `/Home/GetNextImage/${imageIndex}`,
type: "GET",
xhrFields: {
responseType: 'blob'
},
success: function(imageBlob) {
const targetImageElement = imageIndex === 0 ? $("#topimg") : $("#bottomimg");
const fileReader = new FileReader();
fileReader.onload = function(event) {
targetImageElement.css("background-image", `url(${event.target.result})`);
};
fileReader.readAsDataURL(imageBlob);
},
error: function(xhr, status, error) {
console.error("Image load failed:", error);
}
});
}
もし``タグの`src`属性に直接設定する場合は、以下のようにします。
<img src="/Home/Image" style="background-position:-324px 0px;" width="1800" height="720" />
4. Excelで開くと文字化けするUTF-8 CSVファイルのダウンロード
UTF-8エンコーディングで生成されたCSVファイルをExcelで直接開くと、文字化けが発生することがあります。これは、ExcelがBOM(Byte Order Mark)なしのUTF-8を正しく認識できないためです。この問題を解決するには、ファイルの先頭にBOMを追加してからダウンロードする必要があります。
using System.Text;
public IActionResult DownloadCsvFile()
{
var csvContent = Encoding.UTF8.GetBytes("some data");
var bom = Encoding.UTF8.GetPreamble();
var fileBytes = bom.Concat(csvContent).ToArray();
return new FileContentResult(fileBytes, "text/csv;charset=utf-8")
{
FileDownloadName = "データ一覧.csv"
};
}