顯示具有 C# 標籤的文章。 顯示所有文章
顯示具有 C# 標籤的文章。 顯示所有文章

2019年4月22日 星期一

Web API 發佈與 HTTP Error 500.19 問題處理

Local 測試完畢後,接下來就要發佈到 Server 上。
專按按右鍵,選擇 Publish,選擇其中的 IIS, FTP, etc


2019年4月21日 星期日

修改 WebAPI Http Request Method

實務上,除了一次取得全部資料,通常也會依照條件來選取單筆資料。

ASP.Net WebAPI 預設的 Method 如下,帶入的參數為 id,
執行後網址後面輸入 /api/{control_name}/{id},但是跑了會錯,因為:

  • MODEL 內並沒有欄位名稱為 id
  • MODEL 使用多個欄位條件,單一欄位不足篩選。



2019年4月20日 星期六

透過 Model 建立對應的 Controller,並測試 WebAPI

MVC 專案中,已經有一個 Controllers 資料夾。
在上面案右鍵,依序選擇 Add > Controller...


2019年4月19日 星期五

WebAPI 專案內加入 Entity Framework 6 Data Model

完成基本 WebAPI 專案後,接著就是要加入 MODEL。

MODEL 可以想像成「資料集合」,資料表、VIEW 等都可算是。

MVC 架構已經預設好一個資料夾叫 Models,我們直接將 MODEL放在裡面。
MODEL 可以是任何一個物件類別,這邊則使用 Entity Fremawork 來建立。

在資夾上按右鍵,依序選擇 Add > New Item...


2019年4月18日 星期四

Visual Studio 2017 快速建立 WebAPI 專案

以下示範如何於 Visual Studio 2017 建立一個 WebAPI 專案,並以 JSON 格式回傳資料。

首先,建立一個新專案,選擇「ASP.NET Web Application (.Net Framework)」,並確認參數正確。

2018年11月26日 星期一

簡單筆記

TryParse

decimal d = 0;
string s = "123.456";

if (decimal.TryParse(s, out d))
    MessageBox.Show(d.ToString("N1"));
else
    MessageBox.Show(s);

Excel 的 MROUND

/// <summary>
/// MROUND 函數為:傳回四捨五入為所需倍數的數字。EX.MROUND(7,5)=>5  MROUND(8,5)=>10
/// </summary>
/// <param name="number">原始數值</param>
/// <param name="multiple">倍數因子 (計算0.5的倍數就傳0.5)</param>
/// <returns>計算後的結果,效果等同 Excel MROUND 公式</returns>
public static decimal GetMROUND(decimal number, double multiple)
{
    return Math.Round(number / (decimal)multiple, MidpointRounding.AwayFromZero) * (decimal)multiple;
}

2018年9月7日 星期五

取得軟體版本編號 ( 含 ClickOnce )

一般 Winform 自行修改「組件資訊」內的版本編號
// 取得組件資訊內的版本
AssemblyName.GetAssemblyName(System.Windows.Forms.Application.ExecutablePath).Version.ToString();

使用 ClickOnce 發行的版本編號
// 判斷是否為發行版本 (否則 Debug 執行時會出錯)
if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
{
    MessageBox.Show(System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString());
}

2018年8月28日 星期二

Winform 軟體自動更新

Winform 的更新方式很多,最方便的莫過於微軟的 ClickOnce。這次的需求無法用這個機制滿足User,只好自己開發,順便紀錄一下。

網路上能找了幾篇來參考:



最後整理出一些重點符合需求也能兼顧效能與彈性,我的版本:


  1. 更新檔直接放共享網路。(不用架設額外 Web 或 FTP,大家也都能存取)
  2. 更新檔封裝為一個壓縮檔,縮短下載(複製)時間。
  3. 放置一個純文字文件紀錄目前版本供本地端讀取比較。
  4. 更新時不需出現確認視窗,有更新就直接執行。(ClickOnce會出現)
  5. 需於主程式啟動判斷更新,並可定時檢查與手動執行。

簡單畫個圖 (包含專案佈署流程):

2018年6月11日 星期一

使用 Regex.Replace 快速取代字串

這次需求是需要取出地址前兩個字,但資料各種組成都有,例如:

(799)臺南市仁德區保安路9段99號~90
799臺南市仁德區保安里99鄰保安路9段99號~90
799-00臺南市仁德區保安里99鄰保安路9段99號~90
(79988)臺南市仁德區保安里99鄰保安路9段99號~90@!?+=-\|%$^#*&{}[]

使用 Regex.Replace先將數字與特殊字元取代(主要處理郵遞區號部分)

string address = @"(79988)臺南市仁德區保安里99鄰保安路9段99號~90@!?+=-\|%$^#*&{}[]";
string pattern = @"[\d\W_]";
string replacement = "";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(address, replacement);


結果:

臺南市仁德區保安里鄰保安路段號

2018年6月6日 星期三

錯誤 CS2001 \Properties\AssemblyInfo.cs could not be found.

開啟專案後 Properties/AssemblyInfo.cs 顯示問號

建置顯示錯誤
Source file 'D:\SampleCode\MsWordToImage\MsWordToImage\Properties\AssemblyInfo.cs' could not be found.




參考
https://stackoverflow.com/questions/6494691/source-file-properties-assemblyinfo-cs-could-not-be-found

屬性 > 應用程式 > 組件資訊 (即AssemblyInfo)




打開應該會是一片空白,請(至少)填入標題 (Title),按下確定。

這時問號就會消失(組件資訊已經產生),其他資訊系統會自動寫入,結果如下圖。


2018年4月8日 星期日

自動送出 Enter

在處理 DataGridView 編輯時,原本使用 GetChanges() 方法,取得 DataTable 中有異動的資料。 再根據其 RowState 決定要 INSERT 或 UPDATE。 但如果使用者編輯後沒有按TAB或ENTER,呼叫 GetChangs() 可能會得到 null 類似這篇 作者是參考這篇解決 測試後依然無解,最後乾脆於儲存時強行 ENTER
SendKeys.SendWait("{ENTER}");
參考這篇,送出字串與按鈕的方法不同。

DataGridView 內使用 DateTimePicker

宣告全域變數
private DateTimePicker cellDateTimePicker;
初始化 Form1() 時加入
this.cellDateTimePicker = new DateTimePicker();
this.cellDateTimePicker.ValueChanged += new EventHandler(cellDateTimePicker_ValueChanged);
//this.cellDateTimePicker.CloseUp += new EventHandler(cellDateTimePicker_CloseUp);
this.cellDateTimePicker.Format = DateTimePickerFormat.Short;
this.cellDateTimePicker.ShowCheckBox = true;
this.cellDateTimePicker.Checked = true;
this.cellDateTimePicker.Visible = false;
this.dgvCertificate.Controls.Add(cellDateTimePicker);
在 ValueChanged 事件加入對應方法 (cellDateTimePicker_ValueChanged),一些屬性設定。 最後將 DateTimePicker 加入 DataGridView 的 Controls 內 撰寫 cellDateTimePicker_ValueChanged
void cellDateTimePicker_ValueChanged(object sender, EventArgs e)
{
    if (cellDateTimePicker.Checked)
    {
        //cellDateTimePicker.Format = DateTimePickerFormat.Short;
        //cellDateTimePicker.CustomFormat = null;
        dgvCurrent.CurrentCell.Value = cellDateTimePicker.Value.ToString("yyyy/MM/dd"); //convert the date as per your format
    }
    else
    {
        //cellDateTimePicker.Checked = false; // 採用checkbox,清除值要取消勾選
        //cellDateTimePicker.Format = DateTimePickerFormat.Custom;
        //cellDateTimePicker.CustomFormat = " ";
        //cellDateTimePicker.forma
        dgvCurrent.CurrentCell.Value = " ";
    }
    cellDateTimePicker.Visible = false;
}
在 DataGridView 的 CellBeginEdit 事件內加入判斷,對應的儲存格才用DateTimePicker取代
private void dgvCertificate_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
    dgvCurrent = dgvCertificate;
    // 如果欄位是證照日期就用之前宣告的 cellDateTimePicker 取代
    // 也可以用  e.ColumnIndex == 1 判斷,用 Name 避免欄位移動又得修改
    if ("certificate_CER_DATE".Equals(dgvCertificate.Columns[e.ColumnIndex].Name))
    {
        Rectangle tempRect = dgvCertificate.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
        cellDateTimePicker.Location = tempRect.Location;
        cellDateTimePicker.Width = tempRect.Width;
        string s = dgvCurrent.CurrentCell.Value.ToString();
        cellDateTimePicker.Value = (!"".Equals(s) && !"0001/1/1 上午 12:00:00".Equals(s)) ? DateTime.Parse(s) : DateTime.Today;
        cellDateTimePicker.Checked = (!"".Equals(cellDateTimePicker.Value) && !"0001/1/1 上午 12:00:00".Equals(cellDateTimePicker.Value)) ? true : false;
        cellDateTimePicker.Visible = true; //這行要放在所有設定之後
    }
}
編輯結束後隱藏 DateTimePicker
private void dgvCertificate_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if ("certificate_CER_DATE".Equals(dgvCertificate.Columns[e.ColumnIndex].Name))
    {
        cellDateTimePicker.Visible = false;
    }
    //MessageBox.Show(dgvCertificate.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString()+
    //    dgvCertificate.Rows[e.RowIndex].Cells[e.ColumnIndex].FormattedValue.ToString());
}