# 常用Function
## C#
### List 轉 Datatable
參考: https://dotblogs.com.tw/shadowkk/2018/02/09/154620
```C#=
public DataTable ConvertToDataTable<T>(IList<T> data)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
foreach (PropertyDescriptor prop in properties)
{
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
foreach (T item in data)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
{
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
}
table.Rows.Add(row);
}
return table;
}
```
### DataTable 轉 SQL Table
參考:http://t.csdn.cn/oQPX6
Example:
```C#=
/// <summary>
/// 将DataTable导入到SQL数据库表中
/// </summary>
/// <param name="dt">DataTable 数据源</param>
/// <param name="connectString">SQL连接字符串</param>
public static void DataTableToSQLServer(DataTable dt, string connectString)
{
using (SqlConnection conn = new SqlConnection(connectString))
{
conn.Open();
//批量数据处理SQL表
SqlBulkCopy bulkCopy = new SqlBulkCopy(conn);
try
{
bulkCopy.DestinationTableName = "test_table";//要插入的SQL表的表名
bulkCopy.BatchSize = dt.Rows.Count;
#region Datatable 表列 对应 SQL表的列
bulkCopy.ColumnMappings.Add(0, 0);//映射字段名 DataTable列 ,数据库 对应的列
bulkCopy.ColumnMappings.Add(1, 1);
bulkCopy.ColumnMappings.Add(2, 2);
bulkCopy.ColumnMappings.Add(3, 3);
bulkCopy.ColumnMappings.Add(4, 4);
#endregion
bulkCopy.WriteToServer(dt); //复制到SQL指定表
MessageBox.Show("插入成功");
}
catch (Exception ex)
{
MessageBox.Show("异常:"+ex);
}
}
}
```
### 加密解密SHA256
參考:[Link](https://stackoverflow.com/a/33546720/12550853)
```c#=
//加密
public string Hash(string password)
{
var bytes = new UTF8Encoding().GetBytes(password);
var hashBytes = System.Security.Cryptography.MD5.Create().ComputeHash(bytes);
return Convert.ToBase64String(hashBytes);
}
```
```c#=
//解密
```
## SQL
### SQL XML to Table
參考:[Link](https://learn.microsoft.com/zh-tw/sql/t-sql/xml/nodes-method-xml-data-type?view=sql-server-ver16)
Example:
```sql=
declare @xml xml
--取得XML
set @xml = (select obj_name as [@obj_name],obj_value
from usp_parameter where tran_id = '202302131812344312364' and usp_name = 'usp_data_add' for xml path('data'),root('root'))
--轉換成Table
SELECT
Tbl.Col.value('(data[@obj_name="index_no"]/obj_value)[1]','varchar(3000)') as index_no,
Tbl.Col.value('(data[@obj_name="qty"]/obj_value)[1]','varchar(3000)') as qty,
Tbl.Col.value('(data[@obj_name="name"]/obj_value)[1]','varchar(3000)') as name
FROM @xml.nodes('//root') Tbl(Col)
```
## APP 重新啟動問題
#### 問題動作(Debug Mode不會發生,用APK直接安裝才會發生)
1. 打開APP
2. 按home鍵
3. 再去點開APP Icon 會自動重新啟動
#### 問題解決
###### 備註:不要在activity 加上 android:launchMode = "singleTask" / "singleTop", 加了沒用
1. 可以在每個Activity 加上 OnResume
```c#=
protected override void OnResume()
{
base.OnResume();
CrossNFC.OnResume();
}
```
2. 在主啟動Activity(MainLauncher = true)裡加上判斷IsTaskRoot
參考:https://stackoverflow.com/a/33260878/12550853
參考:https://stackoverflow.com/a/27699870/12550853
參考:https://learn.microsoft.com/en-us/answers/questions/642899/xamarin-form-app-android-app-restarts-when-app-is
```c#=
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
//下面這判斷
if (!IsTaskRoot)
{
Finish();
return;
}
}
```
## Git SSL 憑證問題 解決
SSL certificate problem: unable to get local issuer certificate
```git=
//把SSL 憑證關閉
git config --global http.sslVerify false
```
## IIS 500 錯誤問題
檢查web.config內使用的module版本
在IIS的module是否存在


若沒有就要下載 .Net Core Runtime
https://dotnet.microsoft.com/en-us/download/dotnet/3.1

## IIS 500.19 錯誤問題
確認路徑底下有沒有這個.dll, 若沒有就要下載最新的dotnet core hosting bundle
```
%ProgramFiles%\IIS\Asp.Net Core Module\V2\
```

## Xamarin Android 無法使用dotnet list package 問題
https://stackoverflow.com/a/69483666/12550853
查看錯誤路徑後,發現沒有Xamarin的資料
```batch=
error: The imported project "C:\Program Files\dotnet\sdk\7.0.100\Xamarin\Android\Xamarin.Android.CSharp.targets" was not found. Confirm that the expression in the Import declaration "C:\Program Files\dotnet\sdk\7.0.100\Xamarin\Android\Xamarin.Android.CSharp.targets" is correct, and that the file exists on disk.
```
實際位置在
```xml=
<!--程式自動產生的路徑-->
<!--Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /-->
<!--修改後的路徑-->
<Import Project = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Xamarin\Android\Xamarin.Android.CSharp.targets"/>
```
## Android set cookie , Web read cookie
Setting a Cookie in Android WebView:
To set a cookie in an Android WebView, you can use the CookieManager class. Here's an example:
```javascript=
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
// ...
// Initialize the CookieSyncManager (required for older versions of Android)
CookieSyncManager.createInstance(context);
// Get an instance of the CookieManager
CookieManager cookieManager = CookieManager.getInstance();
// Set the cookie
String cookieValue = "my_cookie_name=my_cookie_value";
cookieManager.setCookie("https://example.com", cookieValue);
// Sync the cookies
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.getInstance().sync();
} else {
CookieManager.getInstance().flush();
}
```
This code sets a cookie named "my_cookie_name" with the value "my_cookie_value" for the "example.com" domain.
Reading a Cookie from Blazor Web Code:
To read a cookie from Blazor web code, you can use the IJSRuntime interface to call JavaScript code that retrieves the cookie. Here's an example:
```csharp=
@page "/"
@inject IJSRuntime JSRuntime;
@implements IDisposable
@code {
private string cookieValue;
protected override async Task OnInitializedAsync()
{
cookieValue = await JSRuntime.InvokeAsync<string>("getCookieValue", "my_cookie_name");
}
public void Dispose()
{
JSRuntime.InvokeVoidAsync("clearCookie", "my_cookie_name");
}
}
```
In this example, we use the IJSRuntime interface to call JavaScript functions. The OnInitializedAsync method invokes the getCookieValue JavaScript function, passing the name of the cookie as a parameter. It retrieves the cookie value asynchronously and assigns it to the cookieValue variable.
The Dispose method is implemented to clear the cookie when the Blazor component is disposed. It invokes the clearCookie JavaScript function, passing the name of the cookie as a parameter.
To complete the example, you need to add the JavaScript functions to your index.html or a separate JavaScript file:
```javascript=
function getCookieValue(cookieName) {
var cookieValue = document.cookie
.split(';')
.map(cookie => cookie.trim())
.find(cookie => cookie.startsWith(cookieName + '='));
if (cookieValue) {
return cookieValue.substring(cookieName.length + 1);
}
return null;
}
function clearCookie(cookieName) {
document.cookie = cookieName + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
}
```
The getCookieValue function retrieves the value of a cookie by its name. The clearCookie function removes the cookie by setting an expiration date in the past.
Make sure to include the necessary JavaScript interop configuration in your Blazor application's Startup.cs file.
## List\<T> Clone功能
```c#
public class Parent
{
public string str_A { get; set; }
public string str_B { get; set; }
}
List<Parent> lst_A = new List<Parent>();
lst_A.Add(new Parent { str_A = "AA1", str_B = "BB1" });
lst_A.Add(new Parent { str_A = "AA2", str_B = "BB2" });
```
```c#
public object Clone(object source)
{
using (MemoryStream memoryStream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(memoryStream, source);
memoryStream.Seek(0, SeekOrigin.Begin);
return formatter.Deserialize(memoryStream);
}
}
```
套用前
```c#
// 直接這樣等於會造成後續在修改lst_B裡面的參數時,會連同lst_A一起被改寫
var lst_B = lst_A;
// 測試
lst_B[0].str_A = "CC1";
Console.WriteLine(lst_B[0].str_A);
Console.WriteLine(lst_A[0].str_A);
```
套用後
```c#
// 套用function Clone後,會變成個別獨立的List<Parent>,後續修改時不會一起被改寫
var lst_B = (List<Parent>)Clone(lst_A);
// 測試
lst_B[0].str_A = "CC1";
Console.WriteLine(lst_B[0].str_A);
Console.WriteLine(lst_A[0].str_A);
```
## Nuget Global 路徑設定
https://stackoverflow.com/questions/43541859/change-nuget-package-folders-used-by-visual-studio-2017
NuGet.Config 設定檔:%APPDATA%\NuGet\
```xml!
<configuration>
<config>
<clear />
<add key="globalPackagesFolder" value="c:\packages" />
</config>
</configuration>
```
## Object Class Mapper
[AutoMapper Library](https://automapper.org/)
```java
using AutoMapper;
var config = new MapperConfiguration(cfg =>
{
// .ForMember 表示自定義/手動 mapping
cfg.CreateMap<class_A, class_B>()
.ForMember(dest => dest.create_ru, opt => opt.MapFrom(scr => [custome_data]));
});
var mapper = config.CreateMapper();
var toDB = mapper.Map<class_B>(jsonbody);
```
<table>
<tr>
<th> class_A</th>
<th> class_B</th>
</tr>
<tr>
<td>
```c#
public class class_A
{
public string obj_1 { get; set; }
public string obj_2 { get; set; }
public string obj_3 { get; set; }
public string obj_4 { get; set; }
public double obj_5 { get; set; }
public bool bln_manudel { get; set; }
}
```
</td>
<td>
```c#
public class class_B
{
public string obj_4 { get; set; }
public string obj_2 { get; set; }
public string obj_1 { get; set; }
public string obj_3 { get; set; }
public double obj_5 { get; set; }
public string create_ru { get; set; }
}
```
</td>
</tr>
</table>
## 誤使用VS2022開啟VS2019專案
目前最新版本的VS2022開啟VS2019專案後
再回到VS2019 會出現SDK版本錯誤,無法開啟專案
只需要在 xxx.sln同一個目錄底下建立檔案 global.json,裡面指定sdk版本就能打開了
```json
{
"sdk": {
"version": "5.0.416"
}
}
```
## VS Code Python Install Module
```
py -m pip [module name]
```
## 其他程式範例
[SMBLibrary](https://github.com/TalAloni/SMBLibrary/blob/master/ClientExamples.md)