// 上傳頭圖 (上傳圖片到資料夾, 不進行存檔到資料庫, 上傳的圖片名稱會經由程式改成和電影名稱一樣 $('#file_upload').uploadify({ // .... 省略 uploadify 部分的設定 .... onSWFReady: function () { // 可以使用 uploadify }, onFallback: function () { // 無法使用 uploadify // console.log('Flash was not detected or flash version is not supported.'); // 新增一個可上傳檔案的 form $('#file_upload').after('<form enctype="multipart/form-data" method="post" name="filefox" id="filefox" style="display: initial;">' + // 可加入一些必要的數值到 type="hidden" 欄位 '<input type="file" name="pic" id="pic">' + // 選圖檔案 '</form>').remove(); // 選擇圖片後就自動上傳 $('#pic').change(function () { var fd = new FormData($('#filefox')[0]); // your form element, 使用FormData對象發送文件 // fd.append("CustomField", "This is some extra data"); // 額外添加對象 $.ajax({ type: 'POST', url: '/upload/test/', data: fd, // 如果在 Chrome 上顯示下面這個錯誤 // Uncaught TypeError: Illegal invocation (未捕獲類型錯誤:非法調用) // 指jQuery的AJAX報錯:檢查jQuery的文檔後發現,如果它不是一個字符串,jQuery嘗試將數據轉換成一個字符串。 processData: false, // 在這裡告訴jQuery不要碰我的數據 contentType: false, // 防止jQuery來為你添加一個Content-Type頭 success: function (data) { changeBanner(true); } }); }); } });
2014年9月29日 星期一
JQuery的套件Uploadify, 無法使用的替代方法
FireFox必須額外安裝flash player才能使用Uploadify套件, 在要使用該套件的情況下, 遇到不能使用該套件的時後, 自行改寫ajax上傳功能 :
2014年9月22日 星期一
LINQ to Entities 使用 rank / row_number / dense_rank 技巧
T-SQL
rank :
遇到相同數值會給相同的排名, 其後的排名則跳過, 例如: 1,2,2,4 (會重複號碼, 也會跳號)row_number :
遇到相同數值會依其他的依據來排名, 例如: 1,2,3,4 (不重複號碼, 也不跳號)dense_rank :
遇到相同數值會給相同的排名, 其後的繼續排名, 例如: 1,2,2,3 (會重複號碼, 但不跳號)======================================================
LINQ to Entities
rank :

row_number :
說明 :
TopicSortingRank.ToList() 後才能使用在 .Select 中使用索引, 否則會出現 NotSupportedException 的錯誤 :
LINQ to Entities does not recognize the method 'System.Linq.IQueryable`1[<>f__AnonymousType0`3[System.Int32,System.Decimal,System.Int32]] Select[TopicSortingRank,<>f__AnonymousType0`3](System.Linq.IQueryable`1[HappyMovie.Model.TopicSortingRank], System.Linq.Expressions.Expression`1[System.Func`3[HappyMovie.Model.TopicSortingRank,System.Int32,<>f__AnonymousType0`3[System.Int32,System.Decimal,System.Int32]]])' method, and this method cannot be translated into a store expression.
dense_rank :
2014年9月9日 星期二
使用 Group By 組合某一個欄位的數值成為一個字串
假設有一個資料表TopicItem :
想要看VideoId有哪些TopicId, 所以想組合成:
語法 :
select
VideoId,
STUFF
(
(
select DISTINCT ',' + convert(varchar(10),TopicId) from TopicItem where VideoId = a.VideoId
FOR XML PATH ('')
), 1, 1, ''
) as Topics
from TopicItem a
group by VideoId
想要看VideoId有哪些TopicId, 所以想組合成:
語法 :
select
VideoId,
STUFF
(
(
select DISTINCT ',' + convert(varchar(10),TopicId) from TopicItem where VideoId = a.VideoId
FOR XML PATH ('')
), 1, 1, ''
) as Topics
from TopicItem a
group by VideoId
2014年8月5日 星期二
Html.DropDownList 應用
1. 年齡選單
- 預設值為空白(代表全部年紀)
- 範圍 0 ~199
var ageList = new List<SelectListItem>(); ageList.Add(new SelectListItem { Text = "全部年紀", Value = "" }); ageList.AddRange(Enumerable.Range(0, 120).Select(x => new SelectListItem { Text = x.ToString(), Value = x.ToString() })); ViewBag.age = new SelectList(ageList, "Value", "Text", age);
頁面 :
@Html.DropDownList("age")
2. 英文字母選單
- 預設值為空白(代表全部字母)
- 範圍 A ~Z
var selectListAzItem = new List<SelectListItem>(); selectListAzItem.Add(new SelectListItem { Text = "字母", Value = "" }); selectListAzItem.AddRange(Enumerable.Range('A', 26).Select(x => new SelectListItem { Text = ((char)x).ToString(), Value = ((char)x).ToString() })); ViewBag.az = new SelectList(selectListAzItem, "Value", "Text", az);
3. 自定內容
List<SelectListItem> ratingSorting = new List<SelectListItem> { new SelectListItem{Text= "全部評分",Value= ""}, new SelectListItem{Text= "沒有評分",Value= "0"}, new SelectListItem{Text="有評分",Value= "1"} }; ViewBag.rating = new SelectList(ratingSorting, "Value", "Text", rating);
4. 從資料庫撈取資料
客製化
- 插入自定的資料到頂部當成預設資料
var locationList = _db.Location.OrderBy(x => x.Id).Select(x => new SelectListItem { Text = x.Name, Value = x.Id.ToString(), }).ToList(); // 最後沒有 ToList() 則會得到型別為 IEnumerable<SelectListItem>, 只有 List 型別才能用 Insert 方法 locationList.Insert(0, new SelectListItem { Text = "全部地區" }); ViewBag.location = new SelectList(locationList, "Value", "Text", location);
直接使用
- 資料表欄位Id當Select的Vaule
- 資料表欄位Name當Select當Text
ViewBag.location = new SelectList(_db.Location, "Id", "Name");
5. 使用Enum
var reportTypeList = Enum.GetValues(typeof(ReportType)).Cast<ReportType>().Select(v => new SelectListItem { Text = v.ToString(), Value = ((int)v).ToString() }).ToList(); reportTypeList.Insert(0, new SelectListItem { Text = "全部" }); ViewBag.reportType = new SelectList(reportTypeList, "Value", "Text", reportType);
如果範例中的 enum ReportType 有 DiplayName, 並想要使用 DisplayName 做 Text 名稱
public enum ReportType { [Display(Name = "訊息報錯")] Error, [Display(Name = "補充電影資料")] Movie, [Display(Name = "回報問題")] Problem, [Display(Name = "網站Bug修復")] Bug, [Display(Name = "其他")] Other, }
先做一個 function 來取她的 DiplayName
public string GetReportTypeDisplayName(ReportType value) { var type = value.GetType(); var members = type.GetMember(value.ToString()); var member = members[0]; var displayAttributes = member.GetCustomAttributes(typeof(DisplayAttribute), false); var displayAttribute = (DisplayAttribute)displayAttributes.FirstOrDefault(); return displayAttribute == null ? value.ToString() : displayAttribute.GetName(); }
在 Select 出 SelectListem 時, 使用自定的方法
Text = GetReportTypeDisplayName(v),
=========================
頁面上抓取 selected 數值
string ageSelected = ((SelectList)ViewBag.age).Where(x => x.Selected).Select(x => x.Value).FirstOrDefault();
2014年8月3日 星期日
常用的 System.IO.Path 與範例
string FilePath = @"D:\test\test.rar"; Console.WriteLine("路徑 : {0}", FilePath); // 變更副檔名 Console.WriteLine("變更副檔名 : {0}", System.IO.Path.ChangeExtension(FilePath, "dat")); // "D:\test\test.rar" // 取得檔案路徑 Console.WriteLine("取得檔案路徑 : {0}", System.IO.Path.GetDirectoryName(FilePath)); // "D:\test" // 取得副檔名 Console.WriteLine("取得副檔名 : {0}", System.IO.Path.GetExtension(FilePath)); // ".rar" // 取得檔案名稱(包含副檔名) Console.WriteLine("取得檔案名稱(包含副檔名) : {0}", System.IO.Path.GetFileName(FilePath)); // "test.rar" // 取得檔案名稱不包含副檔名 Console.WriteLine("取得檔案名稱不包含副檔名 : {0}", System.IO.Path.GetFileNameWithoutExtension(FilePath)); // "test" // 回傳最上層實體路徑 Console.WriteLine("回傳最上層實體路徑 : {0}", System.IO.Path.GetPathRoot(FilePath)); // "D:\" // 建立隨機檔 Console.WriteLine("建立隨機檔 : {0}", System.IO.Path.GetRandomFileName()); // 例如 : "mvho5ulp.wrn" // 建立暫存檔並回傳整路徑 Console.WriteLine("建立暫存檔並回傳整路徑 : {0}", System.IO.Path.GetTempFileName()); // 例如 : "C:\Users\ian\AppData\Local\Temp\tmp8DBA.tmp" // 系統暫存檔路徑 Console.WriteLine("系統暫存檔路徑 : {0}", System.IO.Path.GetTempPath()); // "C:\Users\ian\AppData\Local\Temp\ // 是否包含副檔名 Console.WriteLine("是否包含副檔名 : {0}", System.IO.Path.HasExtension(FilePath)); // True // 絕對路徑還是相對路徑 Console.WriteLine("絕對路徑還是相對路徑 : {0}",System.IO.Path.IsPathRooted(FilePath)); // True // 取得完整路徑檔名 Console.WriteLine("取得完整路徑檔名 : {0}", System.IO.Path.GetFullPath(FilePath)); // "D:\test\test.rar" // 將二個路徑合併 string FilePath1 = @"D:\"; string FilePath2 = @"test\test.rar"; Console.WriteLine("將二個路徑合併 : {0}", System.IO.Path.Combine(FilePath1, FilePath2)); // "D:\test\test.rar"
使用 Request 解析網址的說明與範例 :
http://blog.miniasp.com/post/2008/02/10/How-Do-I-Get-Paths-and-URL-fragments-from-the-HttpRequest-object.aspx
2014年8月1日 星期五
管理 ASPNET MVC 中的 Entity Framework DbContext 的生命週期
在應用程式中管理 DbContext 實例是非常重要的, 一個 DbContext 使用了資料庫連線(database connections)這樣重要的資源且需要被釋放(released), 如果沒有正確的 dispose 一個 DbContext 實例, 那麼相關的資料庫連線可能不會被釋放回連線池(connection pool).
寫老式的ADO.NET程式的人都知道一定要這麼做 !
在ASP.NET MVC應用程式中, DbContext 實例基本上是在 Controller 中使用, 一些基礎知識說明 MVC 的 controllers 在當請求(request)到達時被建立, 然後在請求已經完成時被 dispose (are disposed), 在 ASP.NET MVC中如何確認 DbContext 實例被 dispose (is disposed)?
使用 using 區塊可以確保, 當執行到區塊底部時, EmployeeContext 會被 dispose (is disposed), using 區塊是 try{...}finally{...} 的簡寫方式(語法糖), context (DbContext 實例)會在 finally 裡面被 dispose (is disposed), 這區塊會確保 context 被 dispose (is disposed), 但是這樣很難在應用程式中的不同地方分享同一個 context, 會發現自己一直在建立更多要使用的 DbContext 實例, 這也使自己的 Controller 裡出現邏輯處理之外的雜訊, 即使比使用 try finally 乾淨多了, 但是依然感覺一些雜訊存在
public class EmployeeController : Controller
寫老式的ADO.NET程式的人都知道一定要這麼做 !
在ASP.NET MVC應用程式中, DbContext 實例基本上是在 Controller 中使用, 一些基礎知識說明 MVC 的 controllers 在當請求(request)到達時被建立, 然後在請求已經完成時被 dispose (are disposed), 在 ASP.NET MVC中如何確認 DbContext 實例被 dispose (is disposed)?
方法1 : 使用 Using 區塊
using (EmployeeContext context = new EmployeeContext())
{
return View(context.Employees.ToList());
}
使用 using 區塊可以確保, 當執行到區塊底部時, EmployeeContext 會被 dispose (is disposed), using 區塊是 try{...}finally{...} 的簡寫方式(語法糖), context (DbContext 實例)會在 finally 裡面被 dispose (is disposed), 這區塊會確保 context 被 dispose (is disposed), 但是這樣很難在應用程式中的不同地方分享同一個 context, 會發現自己一直在建立更多要使用的 DbContext 實例, 這也使自己的 Controller 裡出現邏輯處理之外的雜訊, 即使比使用 try finally 乾淨多了, 但是依然感覺一些雜訊存在
方法2 : Dispose 區塊
另一種方法是在 controller 中實作 disposepublic class EmployeeController : Controller
{
private EmployeeContext _context;
public EmployeeController()
{
_context = new EmployeeContext();
}
public ActionResult Index()
{
return View(_context.Employees.ToList());
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_context.Dispose();
}
base.Dispose(disposing);
}
}
當請求完成時, controller 會被dispose (is disposed), 這方式也確保了 EmployeeContext 也被dispose (is disposed); 和 using 區塊很像, 在Controller裡產生了雜訊並且很難在應用程式中不同的地方分享同一個實例, 這方法並且依賴團隊中的所有開發人員要正確的實作 dispose
方法3 : 依賴注入 (Dependency Injection)
public class EmployeeController : Controller { private EmployeeContext _context; public EmployeeController(EmployeeContext context) { _context = context; } public ActionResult Index() { return View(context.Employees.ToList()); } }這方法解除了 controller 對 DbContext 實例的生命週期的責任. controller 要求一個 DbContext 實例, 但是不需要關心這實例從哪裡來或是當她結束的時候會去那裡?我們知道這個 Controller 中只有一個建構子, 所以建立 EmployeeController 必須傳入一個 EmpolyeeContext 實例, 所以 Controller 不用再負責建立 DbContext, 意思說也不再需要去 dispose !但是如果 Controller 不用再去建立 context, 那誰該去建立? 我們如何確認 context 真的被 dispose (is being disposed)?用 IoC 容器解決這問題!nuget上有很多 injection/IoC 容器, 例如 NInject, 大致流程是註冊使用 NInject 的 OnPerRequestHttpModule 並設置要用來產生實例的 DbContext(例如範例中的 EmpolyeeContext), 經過這些設置後, NInject 將會認出你的 Controller 所要求的實例(例如 EmpolyeeContext 的實例), 然後執行以下流程:1. 每次 Http Request 時建立實例2. 傳送實例到 Controller 建構子3. Http Request 結束時 dipose 實例OnPerRequestHttpModule 的預設行為:每次 Http Request 都建立一個新的 EmpolyeeContext 實例(context), 這表示不同的 Request 無法使用同一個 context, 也保證不會產生兩個以上的 EmpolyeeContext 被建立, 即使最後請求經過了三個都要求同一個 EmpolyeeContext 的 Controllers, 換句話說, context 的生命週期和 request 的生命週期綁在一起
2014年7月30日 星期三
取得更新失敗的詳細原因
1. 驗證不過的原因
public ActionResult Create(TopicCategory model) { if (ModelState.IsValid) { _db.TopicCategory.Add(model); _db.SaveChanges(); return Json(new { status = "success", information = model.Id }); } else { string messages = string.Join("; ", ModelState.Values .SelectMany(x => x.Errors) .Select(x => x.ErrorMessage)); return Json(new { status = "error", information = messages }); }}
2. EF SaveChanges()失敗原因
try
{
_db.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
ortry
{
// Your code...
// Could also be before try if you know the exception occurs in SaveChanges
_db.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
訂閱:
文章 (Atom)




