Google Code Prettify

EF Core 的 SqlQueryRaw 更多的使用說明及使用範例

SqlQueryRaw 是 Entity Framework Core 提供的一個方法,用於執行原生 SQL 查詢並返回實體或無實體的結果。使用 SqlQueryRaw 可以讓你在使用 EF Core 時,依然可以方便地執行原生 SQL 查詢,這對於需要執行複雜查詢或者使用一些特定的 SQL 特性時非常有用。

基本用法
下面是一些 SqlQueryRaw 的使用範例和說明:

1. 返回實體類型的查詢
假設你有一個 Product 類型對應於資料庫中的 Products 表:

csharp
public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}



你可以使用 SqlQueryRaw 來執行一個簡單的 SELECT 查詢:

csharp
using (var context = new MyDbContext())
{
    var products = context.Products.FromSqlRaw("SELECT * FROM Products").ToList();
}



2. 返回無實體類型的查詢
如果查詢的結果不對應於現有的實體類型,你可以使用無實體查詢來返回一個匿名類型或者自定義的 DTO:

csharp
public class ProductDTO
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

using (var context = new MyDbContext())
{
    var products = context.Set().FromSqlRaw("SELECT Name, Price FROM Products").ToList();
}



3. 使用參數化查詢
避免 SQL 注入的最佳方法是使用參數化查詢。你可以通過傳遞參數來實現這一點:

csharp
using (var context = new MyDbContext())
{
    var productName = "Product1";
    var products = context.Products.FromSqlRaw("SELECT * FROM Products WHERE Name = {0}", productName).ToList();
}



或者使用 SqlParameter:

csharp
using (var context = new MyDbContext())
{
    var productName = new SqlParameter("@name", "Product1");
    var products = context.Products.FromSqlRaw("SELECT * FROM Products WHERE Name = @name", productName).ToList();
}



進階用法

4. 使用 DbSet 進行查詢
如果查詢結果對應於一個實體,你應該使用 DbSet 來進行查詢。這樣可以確保查詢結果會被正確地追蹤:

csharp
using (var context = new MyDbContext())
{
    var products = context.Products.FromSqlRaw("SELECT * FROM Products WHERE Price > 10").ToList();
}



5. 使用無實體查詢
無實體查詢通常用於返回 DTO 或者當查詢結果不直接映射到現有實體時:

csharp
using (var context = new MyDbContext())
{
    var products = context.Set().FromSqlRaw("SELECT Name, Price FROM Products WHERE Price > 10").ToList();
}



6. 內嵌 SQL 的執行
如果需要執行一些內嵌 SQL,像是執行存儲過程或其他非查詢操作,可以使用 ExecuteSqlRaw 方法:

csharp
using (var context = new MyDbContext())
{
    context.Database.ExecuteSqlRaw("EXECUTE dbo.MyStoredProcedure @param1, @param2", parameters);
}



注意事項
確保安全性:使用原生 SQL 查詢時,務必避免 SQL 注入。使用參數化查詢是防止 SQL 注入的最佳方法。
跟蹤與無跟蹤:如果你不需要跟蹤查詢結果(例如,查詢結果僅供讀取),可以使用 AsNoTracking 方法提高性能:

csharp
var products = context.Products.FromSqlRaw("SELECT * FROM Products").AsNoTracking().ToList();



性能考量:儘量避免頻繁使用原生 SQL 查詢,因為這可能會導致數據庫耦合和難以維護的代碼。應優先考慮使用 EF Core 的 LINQ 查詢。


這些範例和注意事項應該可以幫助你更好地理解和使用 SqlQueryRaw 進行原生 SQL 查詢。希望這對你有所幫助!

ASP.NET Core 8 安裝到 IIS10 要如何設定 SSL/TLS

要將 ASP.NET Core 8 應用程序安裝到 IIS 10 並設定 SSL/TLS,請按照以下步驟進行:

1. 安裝 IIS 和必要的擴展

首先,確保已在 Windows 10 或 Windows Server 上安裝 IIS 及其必要的擴展:

  1. 打開 "控制面板" > "程序和功能" > "啟用或關閉 Windows 功能"。
  2. 確保已選中以下項目:
    • Internet Information Services
    • Web 管理工具
    • World Wide Web 服務
    • 應用開發功能(選中 ASP.NET 和其他需要的功能)

2. 安裝 ASP.NET Core Hosting Bundle

在目標機器上安裝 ASP.NET Core Hosting Bundle,這樣可以確保 IIS 可以運行 ASP.NET Core 應用程序。

下載 ASP.NET Core Hosting Bundle

3. 部署應用程序到 IIS

  1. 使用 Visual Studio 或命令行(dotnet publish)將 ASP.NET Core 應用程序發布到文件夾中。
  2. 在 IIS 中創建新的網站或應用程序:
    • 打開 IIS 管理器。
    • 右鍵單擊 "站點",選擇 "添加網站"。
    • 設置網站名稱、物理路徑和端口號。

4. 配置網站使用 HTTPS

獲取和安裝 SSL 憑證

您可以使用以下選項之一獲取 SSL 憑證:

  • 從受信任的憑證颁发机构(CA)購買 SSL 憑證。
  • 使用 Let's Encrypt 免費獲取 SSL 憑證。
  • 在測試環境中使用自簽名憑證。

將 SSL 憑證安裝到 IIS 伺服器上:

  1. 打開 "IIS 管理器"。
  2. 選擇伺服器節點,然後打開 "伺服器憑證"。
  3. 點擊右側操作窗格中的 "導入" 或 "創建自簽名憑證"(如果使用自簽名憑證)。

綁定 HTTPS

  1. 在 IIS 管理器中選擇您的網站。
  2. 在右側操作窗格中,點擊 "綁定"。
  3. 點擊 "添加",選擇 "https" 作為類型,然後選擇已安裝的 SSL 憑證。

5. 配置 ASP.NET Core 應用程序支持 HTTPS

在 Program.cs 中配置 Kestrel 以支持 HTTPS

在 Program.cs 文件中配置 Kestrel 以支持 HTTPS:


 csharp
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup();
            });
}

6. 強制使用 HTTPS

在 ASP.NET Core 應用程序中強制使用 HTTPS,可以在 Startup.cs 文件中配置:


csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    // 配置強制 HTTPS
    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
        options.HttpsPort = 443;
    });

    // 配置 HSTS
    services.AddHsts(options =>
    {
        options.Preload = true;
        options.IncludeSubDomains = true;
        options.MaxAge = TimeSpan.FromDays(60);
    });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

7. 驗證設置

啟動 IIS,訪問網站以驗證 HTTPS 是否正確配置。打開瀏覽器並導航到 https://yourdomain.com 以確保 SSL/TLS 配置正確。

這些步驟應該可以幫助您在 IIS 10 中正確設置 ASP.NET Core 8 應用程序的 SSL/TLS。



ASP.NET Core 8 出現下列錯誤, The SSL connection could not be established, see inner exception.

在 ASP.NET Core 8 中遇到 "The SSL connection could not be established, see inner exception" 錯誤通常是因為 HTTPS 設置問題或 SSL 憑證無法驗證。以下是一些解決此問題的步驟:


1. 檢查本地開發憑證
確認開發憑證已安裝
在本地開發環境中,您需要確保已安裝並信任 ASP.NET Core 開發憑證。可以使用以下命令檢查並安裝憑證:

bash
dotnet dev-certs https --check
dotnet dev-certs https --trust



2. 忽略 SSL 憑證驗證錯誤
在開發環境中,您可以選擇忽略 SSL 憑證驗證錯誤,但這不建議在生產環境中使用。您可以在配置 HttpClient 時忽略 SSL 憑證錯誤:

csharp
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

var handler = new HttpClientHandler
{
    ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; }
};

var client = new HttpClient(handler);



3. 檢查 SSL 憑證
確保您正在使用的 SSL 憑證是有效的,並且已正確安裝。如果是自簽名憑證,請確保它已添加到受信任的根憑證颁发机构。


4. 配置 Kestrel
如果您使用 Kestrel 作為 Web 伺服器,請確保正確配置了 HTTPS:

csharp
public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup();
            })
            .ConfigureKestrel(options =>
            {
                options.Listen(IPAddress.Any, 5001, listenOptions =>
                {
                    listenOptions.UseHttps("path/to/your/certificate.pfx", "yourpassword");
                });
            });
}



5. 檢查網絡設置
如果您在企業網絡或使用 VPN,有時會遇到 SSL/TLS 問題。請檢查您的網絡設置並嘗試在不同的網絡環境中運行應用程式。


6. 查看內部異常信息
檢查內部異常的詳細信息以獲取更多線索:

csharp
try
{
    var client = new HttpClient();
    var response = await client.GetAsync("https://yourapiendpoint");
    response.EnsureSuccessStatusCode();
}
catch (HttpRequestException ex)
{
    Console.WriteLine($"Request error: {ex.Message}");
    if (ex.InnerException != null)
    {
        Console.WriteLine($"Inner exception: {ex.InnerException.Message}");
    }
}



7. 設置 SSL 協議版本
確保您的應用程式配置了正確的 SSL/TLS 協議版本:

csharp
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;



總結
以上步驟應該能幫助您解決 SSL 連接建立失敗的問題。根據實際情況調整配置,特別是在開發和生產環境之間的 SSL 設置。如果問題依然存在,請提供更多詳細信息以便進一步診斷。


在 ASP.NET Core 8 中如何正確安裝及設定Microsoft jQuery Unobtrusive Ajax 庫的使用

在 ASP.NET Core 8 中使用 Microsoft jQuery Unobtrusive Ajax 库,可以简化通过 Ajax 进行无刷新更新的实现。以下是正确安装和设置 Microsoft jQuery Unobtrusive Ajax 库的步骤:


1. 安装库
首先,确保你已经通过 NuGet 安装了 Microsoft.jQuery.Unobtrusive.Ajax 包。

在 Visual Studio 中,打开 “工具” -> “NuGet 包管理器” -> “程序包管理控制台”,然后输入以下命令来安装它:

powershell
Install-Package Microsoft.jQuery.Unobtrusive.Ajax


2. 引入库到项目中
确保在你的项目中正确引用了 jQuery 和 Unobtrusive Ajax 库。打开你的 _Layout.cshtml 文件,并添加以下脚本引用:

html
<!DOCTYPE html>
<html lang="en">
<head>
    <!-- 其他头部内容 -->
</head>
<body>
    <!-- 其他主体内容 -->
    
    <!-- jQuery 引用 -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    <!-- Unobtrusive Ajax 引用 -->
    <script src="~/lib/jquery-unobtrusive-ajax/jquery.unobtrusive-ajax.min.js"></script>

    <!-- 验证脚本引用 -->
    <script src="~/lib/jquery-validation/jquery.validate.min.js"></script>
    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

    @RenderSection("Scripts", required: false)
</body>
</html>



3. 配置 Ajax 表单
在你的视图中,创建一个表单并使用 data-ajax 属性来启用 Ajax 提交。以下是一个示例:

html
@model YourNamespace.YourViewModel

<form asp-action="YourAction" asp-controller="YourController" data-ajax="true" data-ajax-method="post" data-ajax-update="#result">
    @Html.AntiForgeryToken()
    <div class="form-group">
        <label asp-for="YourProperty" class="control-label"></label>
        <input asp-for="YourProperty" class="form-control" />
        <span asp-validation-for="YourProperty" class="text-danger"></span>
    </div>
    <button type="submit" class="btn btn-primary">提交</button>
</form>

<div id="result"></div>




4. 配置控制器和操作方法
在控制器中,确保你的操作方法能够返回一个部分视图或 JSON 响应。以下是一个示例:

csharp
using Microsoft.AspNetCore.Mvc;
using YourNamespace.Models;

public class YourController : Controller
{
    [HttpPost]
    public IActionResult YourAction(YourViewModel model)
    {
        if (ModelState.IsValid)
        {
            // 处理你的表单数据

            return PartialView("_YourPartialView", model); // 返回部分视图
        }

        return PartialView("_YourPartialView", model); // 返回包含验证错误的部分视图
    }
}



5. 创建部分视图
确保你有一个与上述部分视图名称匹配的视图。比如 _YourPartialView.cshtml:

html
@model YourNamespace.YourViewModel

<div>
    <h2>结果:</h2>
    <p>你的属性值: @Model.YourProperty</p>
</div>




6. 启用验证(可选)
如果你需要在表单中启用验证,请确保你的视图中包含以下脚本引用:

html
@section Scripts {
    <script src="~/lib/jquery-validation/jquery.validate.min.js"></script>
    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
}




总结
通过以上步骤,你应该能够在 ASP.NET Core 8 中正确安装和配置 Microsoft jQuery Unobtrusive Ajax 库,以便实现无刷新表单提交和部分视图更新。确保你的视图、控制器和脚本文件都正确配置,并且所有必要的脚本文件都已正确引用。


出現錯誤如下: 415 (Unsupported Media Type)

错误 415 (Unsupported Media Type) 表示服务器拒绝了请求,因为请求的媒体类型不被支持。在 ASP.NET Core 中,这通常意味着你的请求头的 Content-Type 设置不正确或者不匹配服务器期望的格式。


原因及解决方法
在你的 AJAX 请求中,确保 Content-Type 正确设置为 application/x-www-form-urlencoded,因为你使用 serialize() 方法来序列化表单数据。


修改 AJAX 请求
确保你的 Content-Type 设置正确:

javascript
function postPartialView(act, ctl, data) {
    var url = '/' + ctl + '/' + act;
    console.log(url + ' ' + data);
    $.ajax({
        url: url,
        data: data,
        type: 'POST',
        contentType: 'application/x-www-form-urlencoded; charset=UTF-8',  // 设置正确的 Content-Type
        success: function (result) {
            $('#main').html(result);
        },
        error: function (xhr, status, error) {
            console.error('Error loading partial view:', status, error);
        }
    });
}

// 示例数据对象
var data = {
    funSn: 'B12F87CD-B17E-499E-91F1-DF1C9446B062',
    funIsuse: true,
    funSyssn: 'E0FFD7B3-8CF2-462B-A90F-6DB79849FAB4',
    funUpsn: '',
    funNo: 99,
    funName: '99',
    funLeavel: 1,
    funPagename: '122',
    __RequestVerificationToken: $('[name="__RequestVerificationToken"]').val()
};


postPartialView('Update', 'YourController', $.param(data)); // 使用 $.param(data) 序列化数据
确保表单的序列化正确
在你的 HTML 中,确保表单序列化正确:

html
<form id="updateForm" method="post">
    @Html.AntiForgeryToken()
    <input type="text" name="funSn" value="B12F87CD-B17E-499E-91F1-DF1C9446B062" />
    <input type="checkbox" name="funIsuse" checked />
    <input type="text" name="funSyssn" value="E0FFD7B3-8CF2-462B-A90F-6DB79849FAB4" />
    <input type="text" name="funUpsn" value="" />
    <input type="number" name="funNo" value="99" />
    <input type="text" name="funName" value="99" />
    <input type="number" name="funLeavel" value="1" />
    <input type="text" name="funPagename" value="122" />
    <button type="button" onclick="submitForm()">Submit</button>
</form>

<script>
    function submitForm() {
        var formData = $('#updateForm').serialize();
        postPartialView('Update', 'YourController', formData);
    }
</script>


后端控制器
确保控制器方法能够正确处理表单数据:

csharp
[HttpPost]
public async Task Update(EddFunction eddFun) {
    VmdViewmodel vModel = new VmdViewmodel();
    try {
        if (!ModelState.IsValid) {
            throw new Exception($"請確認填寫的資料無誤,然後再次儲存!");
        }
        // 日志调试
        _cLog.WriteEventLog($"funSn: {eddFun.funSn}");
        
        if (string.IsNullOrEmpty(eddFun.funSn)) {
            // 处理逻辑
        } else {
            // 处理逻辑
        }
    } catch (Exception ex) {
        vModel.error_message = "儲存失敗! 請確認填寫的資料.";
        _cLog.WriteEventLog(ex);
        return PartialView(vModel);
    }
    return RedirectToAction("Index", "Function");
}


总结

通过以上方法,确保你的 AJAX 请求头正确设置 Content-Type,并且表单数据序列化为 URL 编码格式发送到服务器。这样可以避免 415 错误,并确保服务器能够正确接收到数据。

在部分檢視中為何document.getElementsByTagName 只能取得undefined

在部分視圖(Partial View)中使用 document.getElementsByTagName 無法正確獲取元素時,可能的原因有以下幾種:

DOM 還未準備好:如果你嘗試在 DOM 尚未完全加載時訪問元素,可能會出現 undefined。
範圍問題:在 AJAX 加載部分視圖時,新的元素可能尚未添加到 DOM 中,導致選擇器無法找到它們。
元素不存在:確保你的部分視圖包含了你想要選擇的元素。
要解決這些問題,可以使用 jQuery 的 ready 方法或在 AJAX 請求完成後運行你的 JavaScript 代碼。以下是一個完整的範例:



1. HTML 和 JavaScript
假設我們有一個部分視圖 _PartialView.cshtml,其中包含一些元素:

_PartialView.cshtml
html
<div id="partial-content">
    <p>部分視圖的內容</p>
    <p>更多內容</p>
</div>




主視圖 (Index.cshtml) 在主視圖中,我們有一個按鈕,用於觸發 AJAX 加載部分視圖,並在成功加載後操作部分視圖中的元素: html
@{
    ViewData["Title"] = "Home Page";
}

<!DOCTYPE html>
<html>
<head>
    <title>@ViewData["Title"]</title>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</head>
<body>
    <h1>首頁</h1>
    <button id="load-partial" class="btn btn-primary">加載部分視圖</button>
    <div id="main-content"></div>

    <script>
        $(document).ready(function () {
            $('#load-partial').click(function () {
                $.ajax({
                    url: '@Url.Action("GetPartialView", "Home")',
                    type: 'GET',
                    success: function (result) {
                        $('#main-content').html(result);

                        // 確保在部分視圖加載完成後運行代碼
                        var paragraphs = document.getElementsByTagName('p');
                        console.log(paragraphs); // 應該能夠正確獲取元素

                        // 如果要使用 jQuery
                        // var paragraphs = $('#main-content').find('p');
                        // console.log(paragraphs);
                    },
                    error: function (xhr, status, error) {
                        console.error('Error loading partial view:', status, error);
                    }
                });
            });
        });
    </script>
</body>
</html>



2. 控制器 (HomeController.cs)
確保控制器返回部分視圖:

csharp
using Microsoft.AspNetCore.Mvc;

public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    [HttpGet]
    public IActionResult GetPartialView()
    {
        return PartialView("_PartialView");
    }
}



總結
這樣做可以確保在部分視圖加載完成後,元素存在於 DOM 中,並且 JavaScript 可以正確地選擇和操作這些元素。使用 jQuery 的 success 回調來運行代碼,可以確保操作僅在部分視圖完全加載並添加到 DOM 中後進行。

document.getElementsByTagName 取回的資料要如何區分識別

document.getElementsByTagName 返回的是一個 HTMLCollection,這個集合可以通過索引訪問到特定的元素。要區分和識別從 document.getElementsByTagName 返回的元素,可以使用以下幾種方法:

使用索引:可以通過索引直接訪問 HTMLCollection 中的元素。
檢查元素的屬性:如 id、class 等屬性,這些屬性可以幫助識別特定的元素。
使用 for 迴圈或 Array.prototype.forEach:迭代 HTMLCollection,並根據元素的屬性進行操作。
以下是一個具體範例:

範例 HTML 和部分視圖

_PartialView.cshtml
<div id="partial-content">
    <p id="para1">第一個段落</p>
    <p class="highlight">第二個段落</p>
    <p id="para3">第三個段落</p>
</div>




主視圖 (Index.cshtml)
在主視圖中,我們加載部分視圖並在成功加載後區分和識別段落元素:

html
@{
    ViewData["Title"] = "Home Page";
}

<!DOCTYPE html>
<html>
<head>
    <title>@ViewData["Title"]</title>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</head>
<body>
    <h1>首頁</h1>
    <button id="load-partial" class="btn btn-primary">加載部分視圖</button>
    <div id="main-content"></div>

    <script>
        $(document).ready(function () {
            $('#load-partial').click(function () {
                $.ajax({
                    url: '@Url.Action("GetPartialView", "Home")',
                    type: 'GET',
                    success: function (result) {
                        $('#main-content').html(result);

                        // 獲取所有段落元素
                        var paragraphs = document.getElementsByTagName('p');

                        // 使用 for 迴圈遍歷所有段落
                        for (var i = 0; i < paragraphs.length; i++) {
                            var paragraph = paragraphs[i];
                            console.log(paragraph);

                            // 根據 id 進行操作
                            if (paragraph.id === 'para1') {
                                paragraph.style.color = 'red';
                            } else if (paragraph.classList.contains('highlight')) {
                                paragraph.style.color = 'blue';
                            } else {
                                paragraph.style.color = 'green';
                            }
                        }
                    },
                    error: function (xhr, status, error) {
                        console.error('Error loading partial view:', status, error);
                    }
                });
            });
        });
    </script>
</body>
</html>




分析
按索引訪問:可以通過索引直接訪問 HTMLCollection 中的元素,如 paragraphs[0] 代表第一個段落。
檢查屬性:使用 id 和 class 屬性來區分和識別元素。在這個例子中,我們使用了 id 屬性來改變第一個段落的顏色,使用了 class 屬性來改變具有 highlight 類的段落的顏色。
使用迴圈:使用 for 迴圈遍歷 HTMLCollection 中的所有段落,並根據元素的屬性進行不同的操作。
這樣可以確保在部分視圖加載完成後,能夠正確地區分和識別特定的元素並進行操作。