2022年12月13日 星期二

[React & .Net Core]專案結構說明


這篇主要是延續第一篇.NET 6+React的開發說明,範例程式碼可參考這裡

說明在開發程式碼時的一些建議存放規範以及規則,讓開發人員可以方便快速開發。


此專案為全端專案,故要拆成兩個部分做說明,分別是前端(React)以及後端(WebAPI)


(1)前端(React)

首先將上次的專案打開,並且將clientapp/src的資料夾展開,如以下畫面


從上到下依序說明:

public:主要存放進靜態檔案,例如html,Image,icon,etc.

src:主要存放程式碼的地方,內部會切分許多資料夾來存放不同功用的程式碼

 components:存放開發好的React元件,讓多個地方可以共用。

 contexts:存放一些跨系統會使用的變數,最常使用的是登入資訊、樣式、 etc. 

 models:存放強型別的typescript結構,建議所有物件都須定義

 pages:頁面存放位置

 services:服務使用,通常使用在呼叫API或共用方法 

 stores:Redux的Store存放位置,這專案暫不使用Redux,先保留

 app.tsx:主要頁面,通常定義了路由以及頁面結構

 index.tsx:進入點,用來載入app.tsx,正常情況不會改

 react-app-env.d.ts:Typescript使用,主要讓一些檔案類型像照片可以Import而不會出現錯誤

 reportWebVitals.ts:效能測量方式,可拿來本機console或串接第三方套件做效能偵測

 setupProxy.js:設定代理伺服器位置,通常使用於多個不同位置API的設定

 setupTests.ts:測試用,可使用jest+enzyme搭配測試,會在有一篇測試的做說明

 .env:設定參數位置,現有設定是.NET6官方範本產生的,development版本有預設port=44410

 .gitgnore:用來管理檔案是否排除git版控(此檔案刪除會所有檔案都加入版控)

aspnetcore-https.js:.NET6官方範本產生,須搭配package.json內的prestart使用才會在Debug時對接到.NET SPAProxy

 aspnetcore-react.js:同前一個說明,實際差別於後續再補充,

 package.json:Webpack的config,用於管理套件、打包...等設定

 README.md:專案說明,結構是mockdown語法。

 tsconfig.json:Typescript的config,用於管理編譯屬性和設定。

 

(2)後端(WebAPI)

API是MVC結構,如下圖。



p.s.在小專案也可直接使用Minimal API,但此專案不使用和介紹。

從上到下依序說明(跳過前端資料夾):

Properties:存放publish,launch設定。

Controllers:controller存放位置,正常會依照類別去做controller的命名,例如MemberController(會員相關),CouponController(優惠券),LoginController(登入相關),etc.

Models:結構定義存放位置。

Pages: Server頁面定義位置,可以定義類似錯誤頁或是API說明頁...等等。

Services:服務存放位置,通常用於定義共用方法以及介接資料層。

appsettings.json:專案參數的設定,通常定義資料庫連線、外部URL或加密設定...等等。

Program.cs:專案進入點,.NET 6 將Startup.cs整合進裡面,並使用Top-level statements簡化。

 

上述介紹了專案內各個檔案或資料夾的定義以及說明,下一篇會使用React搭配mui開發出一個可切頁的範例網站。




















[React & .Net Core]專案開發教學(.Net 6 + React + TypeScript)

前言

此教學會從無到有建立一個SPA框架搭配API的架構,適合產品的快速開發。

事前準備:

(1)安裝Visual Studio 2022 (功能須選用[ASP.NET與網頁程式開發])

p.s. 此教學先以有GUI介面的方式實作,未來會有使用VSCODE+comand line的方式。

(2)安裝Node.js(範例是用18.12.1 LTS,可使用現有Recommended的下載即可)

(3)使用Chrome(後續會安裝React擴充功能,開發時比較方便)

教學開始:

打開VS,點選新增新專案


用React去搜尋範本類型,並選擇ASP.NET Core with React.js

填入專案名稱以及專案版本選擇.NET6.0(長期支援),點選Create。



新增成功後會產生下圖所列的專案結構,可以F5試跑看看,會跑出Bootstrap樣式的網站。



但這原生的範本有幾個想要加強的部分

(1)使用TypeScript的強型別(原生是Javascript)

(2)樣式框架想用MUI,希望減少範本預安裝的一些套件(ex.bootstrap、reactstrap...etc)

p.s. 以上這些部分想要實現最簡單就是直接用語法新增一個Clientapp取代原本的ClienApp,因使用create-react-app語法,所以名稱限制不可使用駝峰式命名,故改成Clientapp。



首先將原先範本產生的ClientApp改名成ClientApp_Bak,後續會有部分程式碼須轉移。

在PowerShell(快捷鍵Ctrl+`)先CD到專案目錄後執行下列語法,就會產生一個clientapp的react範本

npx create-react-app clientapp --template typescript

實際上檔案結構都相同,只是所有JS都變成TS了!


再來要開啟專案.csproj檔案,並將sparoot位置改成clientapp




將ClientApp_Bak的package.json內的scripts區覆蓋到clientapp的package.json

原本clientapp的package.json


改完後的clientapp的package.json


將原本一些在ClientApp_Bak的檔案搬移到clientapp裡,如下列清單

(1)ClientApp_Bak/.env 

=>clientapp/.env

(2)ClientApp_Bak/aspnetcore-https.js

=>clientapp/aspnetcore-https.js

(3) ClientApp_Bak/aspnetcore-react.js

=>clientapp/aspnetcore-react.js

(4) ClientApp_Bak/src/setupProxy.js

=>clientapp/src/setupProxy.js

這樣就升級成TypeScript囉!可使用F5就可以看到專案已成功。


再來要安裝專案所須程式,一樣使用npm將套件載入

須先指定到clientapp資料夾再執行下面script
Ex. cd clientapp 

//安裝React基本元件(轉頁第三方套件)

npm install react-router react-router-dom 


//安裝React基本元件(TypeScript使用,裝在dev即可)

npm install @types/react-router @types/react-router-dom cross-env --dev


//安裝mui

npm install @mui/material @emotion/react @emotion/styled @mui/icons-material 


執行完就可以開始開發程式了,如果上方步驟覺得複雜,可直接從GitHub下載即可使用~

下一篇會講解React基本語法,敬請期待~


參考連結:

https://www.nolanbradshaw.ca/net-react-typescript-template

https://mui.com/material-ui/getting-started/installation/


2022年9月22日 星期四

【Xamarin】Firebase Cloud Messaging IOS-推播功能實作

 待補

【Xamarin】Firebase Cloud Messaging 推播API說明

此篇是講解如何使用API主動推播給APP的用戶

API總共有兩種呼叫方式

1.Server Key。
2.Service Account+ProjectID(SenderID)。

這兩種我們會推薦使用第二種方式去發送推播,因為未來可以針對服務帳號去切開各推播的連線方式。

先進入FCM的專案設定 =>雲端設定








點選管理服務帳戶,會看到服務帳號的內容。












選擇一個Admin的帳戶點入後,在點選密鑰頁籤內的[添加密鑰]=>[創建新密鑰]。







選擇JSON格式後,網頁會自動下載。

成功後就可以看到有一個密鑰產生。(下載檔案後面會用到)



程式部分用Winform當作範例,並安裝相關的Nuget套件。

只需安裝[FireBaseAdmin]即可。


Winform建立一個按鈕和三個文字框,並定義成下圖所示。


在表單初始化的地方加入FCM驗證那段(不用自行處理Oauth2,FirebaseAdmin會幫你實做這段)

  public Form1()
        {
            InitializeComponent();

            #region FCM驗證
            FirebaseApp.Create(new AppOptions()
            {
                Credential = GoogleCredential.FromFile("private_key.json")
            });
            #endregion
        }
p.s.目前範例使用檔案載入金鑰,也可使用JSON字串的方式帶入,如同下方範例
    #region FCM驗證
            FirebaseApp.Create(new AppOptions()
            {
                Credential = GoogleCredential.FromJson("JSON字串")
            }) ;
            #endregion

在按鈕的Click事件上寫下方程式(要注意定義的名稱)

private void btnSend_Click(object sender, EventArgs e)
        {
            string token = txtToken.Text;
            string notificationTitle = txtTitle.Text;
            string notificationBody = txtContent.Text;
            // See documentation on defining a message payload.
            var message = new FirebaseAdmin.Messaging.Message()
            {
                Data = new Dictionary<string, string>()
                {
                    { "myData", "1337" },
                },
                //Token = registrationToken,
                //Topic = "all",
                Notification = new Notification()
                {
                    Title = notificationTitle,
                    Body = notificationBody
                },

         //IOS 專用屬性

        Apns=new ApnsConfig(){

            Aps= new Aps

            { 

                //紅點數字通知,傳1代表固定顯示1。

                Badge=1

            }

        }

            };
            if (string.IsNullOrEmpty(token))
            {
                message.Topic = "all";
            }
            else
            {
                message.Token = token;
            }
            // Send a message to the device corresponding to the provided
            // registration token.
            string response = FirebaseMessaging.DefaultInstance.SendAsync(message).Result;
            // Response is a message ID string.
            Console.WriteLine("Successfully sent message: " + response);
        }

在專案根目錄下放入剛剛下載的密鑰(名稱改為private_key.json)。



開始偵錯專案,填入Token、主旨和內容,點選發送。



手機就可以看到推播訊息。












【Xamarin】Firebase Cloud Messaging 安卓-推播功能實作

Xamarin 開發推播功能時可以用Google的FCM(Firebase Cloud Messaging)來實現,下列列出安卓的實作流程。

首先先建立FCM專案(範例以Google個人用戶為主,Google企業用戶待後續研究)

輸入專案名稱


選擇是否加入Google Analytics(推薦選繼續,後續在說明Google分析的使用方式)

選擇Google Analytics帳戶(選擇預設即可)

新增專案後新增安卓應用程式


填入應用程式的套件名稱(自行定義,會設定至程式的套件名稱)



下載Google-service.json檔(須放置在安卓程式的專案根目錄)


如果在設定時沒下載到,在專案設定的下方也可以下載。



後續一直按繼續就成功了,再來就要設定程式的部分。



安卓要先設定其套件名稱,點選安卓專案->屬性->安卓資訊清單,填入剛剛新增FCM應用程式時的套件名稱



安卓專案安裝需要的Nuget套件

有幾個套件需要下載:
1.Xamarin.GooglePlaySercices.Base
2.Xamarin.Firebase.Messaging
3.Xamarin.Google.Dapper
4.Prisim (可以不安裝,只是一種設計模式來優化程式)

安裝時需要注意編譯的安卓版本,可以看MonoAndroid的版本去做下載,以下為範例程式的載Nuget截圖

將剛剛下載的google-services.json加入專案的根目錄

調整google-services.json的建置動作為GoogleServicesJson(如果沒看到可重開VS或是Rebulid看看)




在AndroidManifest.xml新增<reciver>

下面這段文字請放在<application>內。

<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>

建立CustomFirebaseMessagingService服務

推播要有一個背景執行的Service,此Service需繼承FirebaseMessagingService,裡面有兩個需要覆寫的方法OnNewTokenOnMessageReceived

OnNewToken:得到新的Token時會觸發,通常是APP第一次開啟時。
OnMessageReceived:當有訊息傳入時觸發

CustomFirebaseMessagingService範例

 [Service]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    public class CustomFirebaseMessagingService : FirebaseMessagingService
    {
        public readonly ILocalNotificationsService localNotificationsService;
        public CustomFirebaseMessagingService()
        {
            localNotificationsService = new LocalNotificationsService();
        }
        public override void OnNewToken(string token)
        {
            base.OnNewToken(token);
            Log.Debug("FMC_SERVICE", token);
        }
        public override void OnMessageReceived(RemoteMessage message)
        {
            var notification = message.GetNotification();
            localNotificationsService.ShowNotification(notification.Title, notification.Body, message.Data);
        }
    }

用FCM 介面試試看發送第一則訊息


選擇[Firebase通知訊息]



輸入通知標題和通知文字



如果知道Token可用上圖右側[傳送測試訊息]

輸入Token點選送出,會立即發送,不會經過Firebase審核時間。


如果不知道Token可直接依照Topic或是指定條件做群發。





排定時間選擇立即傳送



選用部分可不用填寫,直接點選審查,過一下子就可以看看手機上是有收到推播。









2020年6月8日 星期一

[Webix] 第三章:Widgets - 6.SpreadSheet

Webix Pro 提供的 Complex widgets,適合模擬線上編輯Excel(類似Google Document),

畫面呈現:


程式碼:
//webix.ready() function ensures that the code will be executed when the page is loaded
webix.ready(function(){
//object constructor
webix.ui({
view:"spreadsheet",
//loaded data object
data: base_data
});
});


重要屬性:

data:資料來源,可以是Json或是JSArray。(id為鍵值,Value代表顯示文字)

重要事件:


重要方法:

parse():帶入資料。

主要研究方向:

1.是否能直接線上取得編輯好的文件,而不是單純使用檔案功能。(取代瑞太後台的匯入匯出功能)
可以,編輯完直接取得該元件的資料內容即可直接使用其資料做動作。
測試畫面:


測試結果:

測試程式碼:
webix.ready(function(){
webix.ui(
{rows:[ {
view:"toolbar",
id:"myToolbar",
cols:[
{ view:"button", id:"LoadBut", value:"Load", width:100, align:"left" },
{ view:"button", value:"Save", width:100, align:"center" },
{ view:"button", value:"Info", width:100, align:"right",click:function(){
console.log($$("sheet").config.data)
} }
]
},{
view:"spreadsheet",
id:"sheet",
toolbar: "full",
data:{
sheets: [
{
name: "Tab 1",
content:{
data:[
[1,1,"Page 1"]
]
}
},
{
name: "Tab 2",
content:{
data:[
[1,1,"Page 2"]
]
}
},
{
name: "Tab 3",
content:{
data:[
[1,1,"Page 3"]
]
}
}
]
},
bottombar:true
}]});
});

[ASP.Net]GridView自訂分頁處理

  ASP.Net的GirdView在每次分頁處理時都會在重新抓取所有資料在進行分頁,遇到大量資料或是設計不良的情況下,在切換時頁面會卡住,造成使用者體驗不佳。 可以透過GirdView內建的參數以及SQL OFFSET語法來替代原先的分頁處理,以下為步驟說明 1.asp...