2021年10月26日 星期二

使用異步延遲進行同步等待

await Task.Delay(1000);

※避免使用 Thread.Sleep 以免阻塞執行緒,且在 windows 表單程式造成 UI 無回應


2021年10月18日 星期一

使用 SignalR 讓 server 主動推播資料給 client (Asp.Net Core)

c#
1. startup.cs 加入signalr
public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSignalR();
    services.AddCors(options =>
                options.AddDefaultPolicy(builder => builder.WithOrigins("https://localhost:44331").AllowAnyHeader().AllowAnyMethod().AllowCredentials())); // 針對跨網域呼叫加入來源白名單
}
public void Configure(IApplicationBuilder application)
{
    application.UseRouting();
    application.UseCors(); // 處理跨網域呼叫
    application.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/hub");
    });
    ....
}

2. 建立hub class
using Microsoft.AspNetCore.SignalR;
    public class ChatHub : Hub
    {
        // 接收通知
        public Task ClientMessage(string name,string message)
        {
           ...
        }
    }


3. 發送通知
private readonly Microsoft.AspNetCore.SignalR.IHubContext<ChatHub> _hubContext;
public xxxController(Microsoft.AspNetCore.SignalR.IHubContext<ChatHub> hubContext) {
    _hubContext = hubContext;
}
public async Task<IActionResult> xxx() {
   await _hubContext.Clients.All.SendCoreAsync("訂單異動", new object?[] { 訂單編號});
}

----

js
1. 安裝 signalr : npm install @microsoft/signalr
2. 引入 node_modules\@microsoft\signalr\dist\browser\signalr.min.js
3. 設定SignalR的連線資訊
var connection = new signalR.HubConnectionBuilder().withUrl("https://xxx/hub").withAutomaticReconnect().build();
4. 與Server建立連線
async function start() {
    try {
        await connection.start({ transport: 'webSockets' });
        console.log("SignalR Connected.");
    } catch (err) {
        console.log(err);
        setTimeout(start, 5000);
    }
};
// Start the connection.
start();
5. 接收通知
connection.on("訂單成立", function (message) {
    console.log(message);
});
6. 發送通知
connection.invoke("ClientMessage", 'ReceiveMessage', 'hihihi').catch(function (err) {
    return console.error(err.toString());
});

2021年10月13日 星期三

focus 用法注意

若搭配vue 等前端框架動態產生dom,有時會有時間差,必須確定已產生dom再呼叫focus
ex:
var interval = setInterval(function () {
                                let elem = $('div[name=div組合商品明細').first().find('input').first();
                                if (elem) {
                                    $(elem).focus();
                                    clearInterval(interval);
                                }
                            }, 100);  

2021年10月8日 星期五

asp.net core 應用程式 SSL 設定

1.開發環境啟用 SSL



2.發佈設定調整
修改 .pubxml 加入
<AllowUntrustedCertificate>True</AllowUntrustedCertificate>

※若同時有非 core 專案,必須一併改為啟用SSL,否則會無法啟動偵錯,因為 IIS 啟用SSL 後無法同時處理 http



2021年10月4日 星期一

BootstrapVue 利用 b-row 實作響應式設計


例如若為筆電或桌機則用一列顯示兩個選單,若為手機則一列顯示一個選單
<b-row>
  <b-col class="col-12 col-lg-6">
                    尺寸:<b-form-select v-model="規格" :options="規格s" style=" width: 8em; display: inline-block " value-field="value" text-field="text">
                    </b-form-select>
  </b-col>
  <b-col class="col-12 col-lg-6" style="display: flex; align-items: center;">
                    品名:<b-form-select v-model="商品類別" :options="商品類別s" style=" width: 10em; display: inline-block " value-field="value" text-field="text">
                    </b-form-select>
  </b-col>
</b-row>

※b-col 中若同時包含文字跟input、select,則要加上 style="display: flex; align-items: center;" 會比較美觀,否則文字會偏上沒有置中對齊很醜!

Entity Framework 建立新物件並儲存後馬上取得關聯資料

使用 CreateProxy 建立物件,不要直接 new var newmodel = _contextXXX.CreateProxy<yyy>(); ... _contextXXX.yyy.Add(newmodel); await _contextXXX.SaveC...