2018/10/18

提升前端安全性 檢查表

1.加上安全的header
https://devco.re/blog/2014/03/10/security-issues-of-http-headers-1/

2.頁面端傳遞變數時,將其編碼,以免有些參數跑掉了
透過javascript傳遞值,要再加上 encodeURIComponent() 做urlEncode
若使用  encodeURI()  
  • 不編碼符號包括: ~!@#$&*()=:/,;?+'
(轉引自 https://blog.longwin.com.tw/2010/01/javascript-encodeuri-component-utf-8-2010/)

3.不要相信前端傳遞的資料。關鍵的代碼需要在後端編碼過,再傳到前端。

2018/10/11

Entity framework 攻略

有多重排序的需求,該怎麼作?

.OrderBy(x => new { x.PROGRAM_CODE, x.LITERACY_CODE }).ToList();

提升寫入速度

利用foreach新增多筆資料或刪除多筆資料時,將多筆資料塞到一個 list中,再利用RemoveRange()方法處理。同時不要每一筆紀錄就執行一次 savechange()。

也有人建議將偵測異動屬性關閉,但這樣會抓不到savechange筆數
dbContext.Configuration.AutoDetectChangesEnabled = false;

要追求極致效能,使用手寫sql等技巧,有以下的討論:
https://www.thereformedprogrammer.net/entity-framework-core-performance-tuning-a-worked-example/


Entity framework 要如何 left join?

(LINQ LEFT JOIN where clause)

此處的情境假設有個db實體為XEntities,主要表格為PROGRAMs,join SCHOOLs、PROGRAM_TYPE兩個表格。要找出 PLAN_FILL_RECORD 有沒有填寫紀錄。

因為 PLAN_FILL_RECORD 要指定只抓某年度的紀錄,因此年度的條件是放在 join 該行的 where 敘述中。若放在 on 的敘述,會變成 inner join。
此外,PLAN_FILL_RECORD 不一定有值,所以在on 之後會讓查詢結果加上一個 into 敘述(黃色部分),將以上的查詢結果帶到 pRes  之中。
接下來再用 from .... in  pRes.DefaultIfEmpty() 的語法查詢結果,這樣有結果則顯示資料,沒結果則帶出 left join資料表的欄位預設值。
最後用欄位投影方式,處理欄位有null時如何顯示。這裡為了讓資料維持強型別,定義了一個 OBJECT_SHOW物件來接收資料。

var query2 = (
from b in XEntities.PROGRAMs
join e in XEntities.SCHOOLs
    on b.SCHOOL_NO equals e.SCHOOL_NO
join p in XEntities.PROGRAM_TYPE
    on b.PROGRAM_TYPE equals p.PROGRAM_CODE
join plan in XEntities.PLAN_FILL_RECORD.Where(o => o.STANDARD_YEAR == cyear)
    on b.PROGRAM_ID equals plan.PROGRAM_ID into pRes

from res in pRes.DefaultIfEmpty()
select new OBJECT_SHOW()
{
    SCHOOL_NO = b.SCHOOL_NO,
    //..................
    PROOF2 = res == null ? "" : res.PROOF2,
    REPLY_DOCU_NO = res == null ? "" : res.REPLY_DOCU_NO
})
.ToList();

[參考1]

Entity framework 要如何撰寫像sql 一樣的where colunm in ('a','b','c')?


  List<string> optionList = new List<string>();
            optionList.Add("IN03");
            optionList.Add("IN19");

          using(Entities db = new Entities()){
              var Query1 = from a in db.ISSUEs
                           where (optionList.Contains(a.ISSUE_CODE.ToString()))
                           select a;

              foreach (ISSUE vi in Query1)
              {

                  Response.Write(vi.ISSUE_NAME +"<br/>");
           
              }
       
          }

 Entity framework 刪除失敗

使用EF異動資料 ,在更新之前 根据外键 我查询了 是否已经存在:
dbContext.model.Where(d => d.HotelId == hotelId).FirstOrDefault();
如果 存在 就更新, 不存在就Add;
存在 时 去 更新:
dbContext.Entry(model).State = EntityState.Modified;
dbContext.SaveChanges()
此时运行就会报错: Store update, insert, or delete statement affected an unexpected number of rows (0)

解决办法:
 dbContext.model.Where(d => d.HotelId == hotelId).FirstOrDefault();
 dbContext.Entry(mod).State = EntityState.Detached;    // 查询完后 dbContext实体 内 已经存在了, 要设置为 detach ,然后再去更新
dbContext.Entry(model).State = EntityState.Modified;
dbContext.SaveChanges()




抓取 Entity framework 寫入時的Exception


 try
                {
                    CEntities.CURSE_QA.Add(QA);
                    CEntities.SaveChanges();
                }
                //將錯誤訊息顯示在頁面上
                catch (System.Data.Entity.Validation.DbEntityValidationException Dx) {

                    string DbErrorList = "";
                    var qq = Dx.EntityValidationErrors;
                    foreach (var thisError in qq) {
                        foreach (var thisSubError in thisError.ValidationErrors)
                        {
                            DbErrorList = DbErrorList + thisSubError.ErrorMessage;
                        }
                    }
                    Literal1.Text = DbErrorList;
                }
                catch (Exception ex)
                {
                     
                    throw ex;
                }


2018/10/3

C# 入門語法整理(字串函數)


常用字串函數

用途
回傳
.Tostring()
其他型別轉字串
字串
char sp = ‘,’;
string someStr=”joe,alisa,tesla”;
string[] array1 =someStr.split(sp)
把字串分割成陣列
字串陣列
.Trim()
清字串末尾的空白
字串
(“where a={0}”, str1)
字串格式化
字串
.replace(“目標字元”,”取代後字元”)
取代某個字串
字串
string.Contains("goodbye")
確認是否包含某個字元
bool
string.IndexOf(“清華”, 0)
查出某字串自第幾個字元起是否包含要查詢的詞彙
Int,表示所在位置,
不存在時,回傳-1
string.Compare("字串", "測試"); // result = -1 
string.Compare("字串測試", "字串測試"); // result = 0 
比對兩個字串是否完全相符
不同=-1
相同=0

.ToUpper()
轉大寫
字串
.ToLower()
轉小寫
字串
.Substring(1, 2)
擷取某部分字串
字串

轉型別(型別寫在前面)
(int32)obj

求餘數
%
Stringbuilder 類別
用於大量的字串串接,提高效能
Stringbuilder sb = new stringbuilder();
Sb.append(“xxxxxxxx”);

條件 (三元) 運算子
Stirng vColor = ( thisClass=”金牌會員”)? “gold”: “gray”;

HTMLENCODE
System.Net.WebUtility.HtmlDecode(texts);