2013年12月30日 星期一

Asp.net MVC NuGet安裝指定套件的版本(17)

VS有個很強的功能就是NuGet相信很多人都知了就不再多說
至於沒用過的可試試,只要在專案上按下右鍵如下圖及可搜尋及安裝

但像jQuery有很多版本確不想要安裝到最新的版本那怎麼辦?
jquery點選下面的版本
會有一行 PM > Install-Package jQuery -Version 1.10.2
到VS > 工具 > 程式庫套件管理員 >套件管理主控台 > 點一下就會出現主控台視窗 將剛的那一樣貼上執行即可

2013年12月27日 星期五

2013年12月22日 星期日

Asp.net jQuery+DropDownList連動後出現System.Web.HttpUnhandledException

這其實只是不了解jquery及asp.net postback的問題
有兩個DropDownList,Master及Detail
下拉Master連動Detail一般來寫程式碼都會如下
 $(function () {
    $("#<%= Master.ClientID%>").change(function () {
            var q = $("#<%= Master.ClientID%>").val();
                $.ajax({
                    url: '/get.ashx',
                    type: 'post',
                    async: true,
                    data: { q: q },
                    success: function (data) {
                        $('#<%= Detail.ClientID%>').empty();
                        var myarray = $.parseJSON(data);
                        $.each(myarray, function (i, item) {
                            var option = "";
                            $('#<%= Detail.ClientID%>').append(option);
                        });
                    }
                });
            });
  });
上面程式碼看似無誤,但在PostBack後就會出現System.Web.HttpUnhandledException
因為PostBack後會產生畫面
放在$(function (){});裡面又會跑一次但程式而此時就會造成錯誤
所以必需將select change放於jquery function外
 $(function () {
    
  });

$("#<%= Master.ClientID%>").change(function () {
            var q = $("#<%= Master.ClientID%>").val();
                $.ajax({
                    url: '/get.ashx',
                    type: 'post',
                    async: true,
                    data: { q: q },
                    success: function (data) {
                        $('#<%= Detail.ClientID%>').empty();
                        var myarray = $.parseJSON(data);
                        $.each(myarray, function (i, item) {
                            var option = "";
                            $('#<%= Detail.ClientID%>').append(option);
                        });
                    }
                });
            });

2013年12月18日 星期三

Asp.net 系統收到多個不同的 Content-Disposition 標頭。我們不允許這種情形,這是為了避免遭到 HTTP 回應分割攻擊。

今天使用者遇到了這個問題
系統收到多個不同的 Content-Disposition 標頭。我們不允許這種情形,這是為了避免遭到 HTTP 回應分割攻擊。
看了一下程式
 Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", mFileName));
 Response.AddHeader("Content-Disposition", string.Format("attachment; filename=\"{0}\"", mFileName));
多加了分雙引號這樣輸出的標頭才會指定檔名是什麼減少攻擊

2013年11月25日 星期一

IIS 回收時間(IIS Session Time Out)

很難得的遇到一次User全部被系統踢出去的經驗
所以判斷是IIS自己踢的
找了一下設定在
IIS > 應用程式集區 > 集區名稱上右鍵 > 進階設定
如圖

固定時間間隔(分鐘):預設是1740改成0就不會回收了

2013年11月17日 星期日

Javascript 秒數轉時分秒

最近常在網頁上用到
尤其是撥html5 video
   function formatSecond(secs) {          
            var hr = Math.floor(secs / 3600);
            var min = Math.floor((secs - (hr * 3600)) / 60);
            var sec = parseInt( secs - (hr * 3600) - (min * 60));

            while (min.length < 2) { min = '0' + min; }
            while (sec.length < 2) { sec = '0' + min; }
            if (hr) hr += ':';
            return hr + min + ':' + sec;

        }
參考網址 點我

2013年11月12日 星期二

Asp.net MVC 必裝NuGet套件Elmah(16)

先廢話一下
今天不是實作了,完成前面幾項功能其實就差不多可以做出一個基本網站了
但這樣還不夠尤其實是錯誤訊息相當重要
因為程式總是會有例外
所以必需靠這些訊息來判斷那裡有問

安裝NuGet套件方式 點我前往
相關教學 點我前往
點我前往
其實就幾個重點
1.elmah.mvc.route最好設定不要使用預設
2.如果開啟遠端如下,一定要設定elmah.mvc.requiresAuthentication
  
    
  
3.以下是幾個設定在相關教學裡有保哥說的很詳細
     
     
    
    
    
    

參考網址
點我前往
點我前往

2013年11月9日 星期六

Asp.net MVC 實作抓最大排序及繫結的方法(15)

先廢話一下
其實很簡單但是有時會無法繫結
Controller部份先
//抓最大值
int Sort =  (from u in db.TabContent 
  where u.TabID==tabid
  select u.Sort).DefaultIfEmpty().Max(x => x == null ? 0 : x);
ViewBag.Sort = Sort + 1;
以上這部份很簡單沒問題吧
        
@Html.LabelFor(model => model.Sort, new { @class = "control-label col-md-2" })
@Html.TextBoxFor(model => model.Sort) @Html.ValidationMessageFor(model => model.Sort)
程式碼自動產生會這樣
但如何修改成能抓ViewBag
        
@Html.LabelFor(model => model.Sort, new { @class = "control-label col-md-2" })
@Html.TextBox("Sort",null, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Sort)
改成用弱型別是一個方法記得"Sort"這樣就能抓到ViewBag了
而且最好以欄位名稱命名
這樣在Model Binding時就能抓到值喔
不然會抓不到資料有興趣可以試試 參考網址

2013年11月4日 星期一

Asp.net MVC 實作jQuery+Html.DropDownList更換頁面資料(14)

先廢話一下
這功能蠻實用的原本還想說用AjaxBeginForm但不知該如何寫
雖然寫出來了但應該還有許多可以地方可以加強
Controller部份先抓產生下拉選單的資料
        public ActionResult Index( )
        {
            ViewBag.TabData = new SelectList(db.Tab, "TabID", "TabName"); //產生下拉選單
            return View();
        }
View的部份也放一個@Html.DropDownList接收下拉選單
也放一個DIV來準備給jQuery用
@Html.DropDownList("TabData", null, null, new { id = "ddTabData" })
然後產原本產生的Index裡的Table另外開一個_List.schtml裡
所以這時畫面應該只剩一個下拉選單
我們要讓下拉後變更整個Table裡的資料
怎麼做當然就是去呼叫剛的頁面
要動態更新DOM我只會jQuery哈
  
去呼叫@(Url.Action("GetList", "TabContent", null))

  public ActionResult GetList(int tid = 1)
        {
            var tabcontent = db.TabContent.Where(u => u.TabID == tid).Include(t => t.Account).Include(t => t.Account1).Include(t => t.Tab);
            return View("_List",tabcontent.ToList() );
        }
這樣就會回傳一整個Table回來
但_List.cshtml裡除了原本宣告model要放
@{    
    if (IsAjax)
    {
        Layout = null;
    }    
}
上面這句也要加,不加差在那邊各位可以自己測試!!
參考網址

2013年11月2日 星期六

Asp.net MVC 實作AutoMapper後加上PagedList(13)

先廢話一下
今天終於將MVC課程上完了
接下來就要多練習
上篇文章提到AutoMapper可自動轉型
但試了很久就是沒法轉成PagedList
還好運氣不錯找到一篇文章>
public ActionResult Index()
{
	Mapper.CreateMap(); 
        var OrderList = db.Account.OrderBy(o => o.AccountID);//設定OrderBy List
        var PagedList = OrderList.ToPagedList(p, 2);//分頁的 List
        var viewmodel = Mapper.Map, IEnumerable>(PagedList.ToArray()); // 分頁列表轉換成ViewModel
        var query = new StaticPagedList(viewmodel, PagedList.GetMetaData()); // reconsitute a new IPagedList containing the viewmodels
        return View(query);       
}
說真的我還真看不太懂最後一行那句
但這樣在View中是完全不需要更改的
寫到現在這樣CRUD最底層都差不多寫好了
簡單的專案也差不多快完成了
參考網址
點我

2013年11月1日 星期五

Asp.net MVC 實作AutoMapper Mapping Model and ViewModel(12)

先廢話一下
第一次寫MVC檢視一下程式碼
發覺定義了太多ViewModel
只要新增一個欄位後View Controller Model居然都需要改
天阿這一定不會是我想要的
相信寫MVC的人覺對不會想發生這種問題
Google搜尋後發覺有一個好的套件
AutoMapper在NuGet裡搜尋就能找到安裝
來看一下原本的程式碼
public ActionResult Index()
{
 var query = from u in db.Account
                    select new AccountVM
                    {
                        AccountID = u.AccountID,
                        AccountName = u.AccountName,
                        IsUsed = u.IsUsed,
                        LoginIP = u.LoginIP,
                        LoginDate = u.LoginDate,
                        Name = u.Name,
                        Email = u.Email
                    };

         return View(query);
}
看以上程式碼只要加一個欄位每次都要跑來修改
唉~對於最內部系統的人最痛苦的事就是新增欄位了
來看一下使用AutoMapper
public ActionResult Index()
{
        Mapper.CreateMap();
        List account = db.Account.ToList();
        List< AccountVM> query = Mapper.Map<  List< Account>,List< AccountVM>>(account);   
        return View(query);
}
這樣不管怎麼增加欄位都不需要在Controller修改了
只是目前不知會不會有什麼Bug 參考網址
點我

Asp.net MVC 實作DropDownList繫結資料庫selected(11)

先廢話一下
DropDownList很簡單阿
WebForm用selectvalue=xxx就好
但MVC的DropDownList讓我研究了一早上

大部份在網路上找的都是建立或者連動DropDownList
可能是我搜尋功力差找不到繫結資料庫又能Select的方法
自己想了一個很瞎的方式
就是自己判斷抓出來的值跟DropDownList有沒有一樣
然後把Select變True
只是不知這樣是否為最佳的寫法
以下是View程式碼
@{                    
 List list = (List)ViewBag.TabColumnName;
 foreach (var s in list )
 {
     if (item.TabColumnName.Equals(s.Value))
  {
   s.Selected = true;
  }
  else
  {
   s.Selected = false;
  }            
 }
}              
@Html.DropDownListFor(modelItem => item.TabColumnName, list)  
Controller如下
ViewBag.TabColumnName =TabColumnVM.getTabColumnName(); 

2013年10月31日 星期四

Asp.net MVC 實作TempData應用自訂Error(10)

先廢話一下
大部份都會設計刪Master時Detail也順便刪
依需求所以做個不一樣的
如果Detail是有資料時就提示不能刪除Master
這樣好像讓資料更安全點
使用TempData來紀錄錯誤的訊息
為何用TempData因為他只會被使用一次
所以在post錯誤時傳給Get一次顯示
  public ActionResult Delete(short? id)
        {            
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
     //重點在這裡接收後顯示錯誤
            if (TempData["CustomError"] != null)
            {
                ModelState.AddModelError(string.Empty, TempData["CustomError"].ToString());
            }

            //Account account = db.Account.Find(id);
            var query = from u in db.Tab where u.TabID == id;

            if (query == null)
            {
                return HttpNotFound();
            }
            return View(query);
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(short? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            string Sql = " TabID == @0";
            var query1 = (from u in db.TabColumn.Where(Sql, id)
                          select u).ToList();
            if (query1.Count() > 0)
            {               
  //有錯時丟給Get顯示
                TempData["CustomError"] = "頁籤內有欄位所以不可刪除";
                return RedirectToAction("Delete",null, id);
            }

            Tab query = db.Tab.Find(id);
            db.Tab.Remove(query);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
在View裡記得加以下才會顯喔
@Html.ValidationSummary(true)
參考網址

2013年10月30日 星期三

Asp.net MVC 實作TextBoxFor DataFormat(9)

先廢話一下
多實作多健康
一般會在Model裡設定DataFormat
[DisplayName("時間")]
[DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}", ApplyFormatInEditMode = false)]
public Nullable pDate { get; set; }
以上在list用DisplayFor都沒什麼問題
但TextBoxFor時如果MS-SQL是中文版的還是會出現上午、下午這種字眼當然驗證就不會過了
改成如下就能正常顯示yyyy-MM-dd HH:mm:ss
@Html.TextBoxFor(model => model.LoginDate, "{0:yyyy-MM-dd HH:mm:ss}", new { @class = "form-control", @readonly = "readonly" })
參考網址
點我

Asp.net MVC 實作使用TryUpdateModel更新資料(8)

先廢話一下
最近真的越寫MVC越上癮了
雖然因為很不熟一直卡
但是做出來的成就感特別好
有些東西做出來但是還是有些詳細的原理還需了解

終於做到需要開始CRUD了
首先針對會員資料做更動
最先遇到的是修改欄位後有些欄位不更新
找了兩篇相當好的文章 點我 點我
使用TryUpdateModel有10個多型能使用
重點再於第四個參數
為不更新的欄位名稱
沒輸入密碼時不更新>
  [HttpPost]
        [ValidateAntiForgeryToken]
       
        public ActionResult Edit(int Id, AccountEdit Form)
        {
            if (ModelState.IsValid)
            {              
                Account query = db.Account.Find(Id);               
                List list = new List();

                //  沒打 是空時 時不更新
                if (Form.Password == null || Form.Password.ToString().Equals(""))
                {
                    list.Add("Password");
                }
           
                if (TryUpdateModel(query,"",null,list.ToArray()))
                {
                    try
                    {
                        // 有打時 不是空 這段必需要寫在TryUpdateModel
                        if (Form.Password != null && !Form.Password.ToString().Equals(""))
                        {                            
                            query.Password =  PublicFunction.EncodeStringMD5(Form.Password); 
                        }                      

                        db.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        string e = ex.Message.ToString();
                        throw;
                    }
                   
                    return RedirectToAction("Index");
                }
                return View(query);
            }
            return View(Form);          
        }
       
有個特別的地方就是要輸入時才更新密碼部份
原本寫在TryUpdateModel外面感謝保哥指導
"TryUpdateModel會蓋掉 model的資料"
"因為他在這時後才做 Model Binding"
所以要寫在TryUpdateModel裡面
參考網址
點我
點我
微軟官方

2013年10月29日 星期二

Asp.net MVC 實作一個View多個Model(7)

先廢話一下
這功能看似簡單
但不知如何架構跟下語法可能會寫不出來
先在ViewModels裡建一個Class裡面有三個IEnumerable
public class TabContainerVM
    public class TabContainerVM
    {
        public IEnumerable tab { get; set; }
        public IEnumerable tabcolumn { get; set; }
        public IEnumerable tabrow { get; set; }
    }
在Controller裡把資料自行加入到model裡後回傳
  public ActionResult TabContainer()
        {
            var tab = from u in db.Tab                      
                      select u;

            var tabcolumn = from u in db.TabColumn
                            select u;

            var tabrow = from u in db.TabRow
                         select u;

            var model = new TabContainerVM
            {
                tab = tab,
                tabcolumn = tabcolumn,
                tabrow = tabrow
            };

            return PartialView("_TabContainer",model);
        }
view的話就能使用
@model  ViewModels.TabContainerVM

@foreach (var tab in Model.tab) {
    @foreach (var tab in Model.tabcolumn ) { //do something
  • }
}
參考網址 點我

2013年10月27日 星期日

Google 分析網頁效能工具

Google 分析網頁效能工具
剛忽然逛到真的需要記一下

Asp.net MVC 實作RenderBody和RenderSection(6)

先廢話一下
MVC好像越來越有趣了
如果個人邏輯相當好的話
可以在View中發揮的彈性很大
因為MVC網頁一種個感覺就很像在挖洞
可以到處填補彈性的確比WebFrom來的好
我想RenderBody和RenderSection的範例在新增一個專案後就會有了
RenderBody搭配一個_Layout所以一個_Layout只會有一個RenderBody
只要將頁面的_Layout路徑設定即能套用
  @RenderBody()
RenderSection在_Layout裡可以有許多的RenderSection
但切記是_Layout裡而不是在一般頁面裡喔
如果直接在一般頁面裡他會跳出以下錯誤
無法直接要求檔案 "~/Views/Home/Index.cshtml",因為它會呼叫 "RenderSection" 方法。

_Layout裡
required為true表示您只要是套這個_Layout的頁面都必需要又head的section不然會出錯這相當重要
  @RenderSection("head",required: false)
一般頁面
@section head{
//你的程式碼
}

2013-10-27補充
我做了一個測試在_Layout裡設定@RenderSection("head",required: false)
再將/Home/Index裡在呼叫一個Partial
而Partial裡加入
 @section head{
                
        }
在執行後Partial裡的程式碼完全不會顯示
所以Partial裡寫@section 是沒用的僅供參考摟!!

2013年10月26日 星期六

Asp.net MVC 實作登出及驗證(5)

先廢話一下
登入登出看似簡單但有許多需要注意的小地方
參考了很多網站才實作出來
上次做到Asp.net MVC 實作登入驗證(1)
當然要有驗證是否登入跟登出
找了許多站終於結合出比較有效的程式碼
驗證是否已登入,程式碼不長但很實用
if ( User.Identity.IsAuthenticated)
{
  //這邊是有驗證過已登入
}
如果是一整個Controller都需要驗證可加[Authorize]在Class上
如果整個Controller裡有不需驗證的可加[AllowAnonymous]
    [Authorize]
    public class HomeController : Controller
    {       
        [AllowAnonymous]
        public ActionResult Index()
        {
            ViewBag.Title = PublicFunction.WebSiteName; 
            return View();
        }

        public ActionResult Create()
        {
            return View();
        }
     
    }
以下是登出的完整程式碼
 [HttpPost]
        [ValidateAntiForgeryToken]     
        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();
            Session.Abandon();

            // clear authentication cookie
            HttpCookie cookie1 = new HttpCookie(FormsAuthentication.FormsCookieName, "");
            cookie1.Expires = DateTime.Now.AddYears(-1);
            Response.Cookies.Add(cookie1);

            // clear session cookie (not necessary for your current problem but i would recommend you do it anyway)
            HttpCookie cookie2 = new HttpCookie("ASP.NET_SessionId", "");
            cookie2.Expires = DateTime.Now.AddYears(-1);
            Response.Cookies.Add(cookie2);

            //FormsAuthentication.RedirectToLoginPage(); 
            return RedirectToAction("Index", "Home", null);
        }

參考網站
登出實作
Session.RemoveAll() 及Session.Abandon() 的差別

2013年10月25日 星期五

Asp.net MVC 實作FancyBox(4)

今天沒廢話

先到FancyBox下載套件
將js及css放入如圖

在/App_Start/BundleConfig.cs加入
bundles.Add(new ScriptBundle("~/bundles/fancybox").Include("~/Scripts/fancybox/jquery.fancybox.js"));
bundles.Add(new StyleBundle("~/Content/fancybox").Include("~/Content/fancybox/jquery.fancybox.css"));
View的部份新增兩個一個為主頁面(Index)一個為被呼叫頁面(FancyBox)
加入jQuery參考及FancyBox參考
ActionLink寫法如下

@Scripts.Render("~/bundles/fancybox")
@Styles.Render("~/Content/fancybox")

@Html.ActionLink("[新增]", "FancyBox", "Home", null, new { @class = "fancybox fancybox.iframe" })

2013年10月24日 星期四

Asp.net MVC 實作TinyMCE文字編輯器搭配@Html.Raw(3)

先廢話一下
昨天在想目前常接到需要文字編輯器的網頁程式
之前都是使用CkEditor但在MVC上不是很好套
所以找了一款我個人覺得蠻合適的編輯器TinyMCE
就看個人的需求來選擇
套用方式很簡單form部份如下
如果是強型別可改為@Html.TextAreaFor
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
    {
        @Html.TextArea("abc")
        
    }
再加入參考js及寫script




在action裡接收程式碼如下
當然也可以使用強型別接會更會
記得加[ValidateInput(false)]
不然會出現"具有潛在危險"Request.Form 的值已從用戶端"
但最好使用時要小心最後是在後台有權限判斷才能使用
[HttpPost]
[ValidateInput(false)]
public ActionResult Index(FormCollection form)
{
  if(ModelState.IsValid)
  {
    string test = form["abc"];
  }
    return View();
}

2013-10-29補充
使用文字編輯器時通常為在前後產生

而在MVC中如果是以欄位
@item.content
來輸出裡面有

則會備程式編成html 所以需搭配

@Html.Raw(@item.content)

2013年10月23日 星期三

Asp.net MVC 實作常用的Model驗證(2)

先廢話一下
MVC重點在於關注點分離
保哥說過Model要重、Controller要輕、View要笨
所以設計Model相當重要
為來減輕Controller跟View所以很多事情都要拿到Model來做
表單欄位驗證就必需要在Model裡做

以下就寫幾個會常用到的欄位驗證(os其實是以後自己要copy用)
//先using以下兩個命名空間
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
以下幾個例子大概都包含了常用的
public class AccountInfo
{

        [Key]
        public int AccountID { get; set; }

        [DisplayName("登入帳號")]
        [Required(ErrorMessage = "請輸入登入帳號")]
        [StringLength(40, ErrorMessage = "登入帳號最多20個字")]
        public string AccountName { get; set; }

        [DisplayName("密碼")]
        [Required(ErrorMessage = "請輸入密碼")]        
        [MaxLength(20, ErrorMessage = "密碼最多20個字")]
        [MinLength(8, ErrorMessage = "密碼最少8個字")]        
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [DisplayName("確認密碼")]
        [DataType(DataType.Password)]
        [Compare("Password", ErrorMessage = "密碼與確認密碼不符")]
        public int ConfirePassword { get; set; }

        [DisplayName("姓名")]
        [StringLength(10, ErrorMessage = "姓名最多10個字")]   
        public string Name { get; set; }

        [DisplayName("生日")]     
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
        public DateTime BirthDay { get; set; }

        [DisplayName("年齡")]
        [Range(1,100,ErrorMessage="年齡請輸入1~100歲")]    
        public int Age { get; set; }

        [DisplayName("電子郵件")]
        [EmailAddress(ErrorMessage="信箱格式錯誤")]
        public string Email { get; set; }

        [DisplayName("個人部落格")]
        [Url (ErrorMessage="連結格式錯誤")]
        public string BolgUrl { get; set; }

       [DisplayName("薪資")]
       [RegularExpression(@"^d+$", ErrorMessage = "請輸入數字.")]
        public int Salary { get; set; }
}

2013年10月22日 星期二

Asp.net MVC 實作登入驗證(1)

先廢話一下
離上次寫MVC文章剛好一年了
這一年裡基本上我都沒機會去使用MVC
剛好這次公司有點數所以去上了課
自己又投資自己去上保哥的MVC5課程
剛好兩邊教法不一樣有些重點也不一樣
趁著還熟著時順手向同事要了個已經快開發成的案子
當然第一次寫要上線應該很難
接下來幾天會針對實作及遇到的問題做整理

一開始我想剛學完基礎的人
基本上跟我一樣不知如何下手
隨便要個舊專案或是拿個不是很重要的案子來寫
首先應該會從會員開始吧
但千萬別從新增會員開始
因為這樣就有點難了
我是以VS2013來開發目前是RTM
1.新增一個專案 > .net版本選4.5 > 選MVC > 建好了網站 > 刪除一些不必要的原件(Controllers Views Models)裡都刪了 只留View裡的Shared
2013範本是Bootstrap 3.0,jQuery 1.10.2。
2.開發分成Code First、DB First、Model First因個人習慣DB First所以先來建資料庫,先求簡單只有三個欄位,ID、登入帳號、密碼,但有一個重點記得設PK,EF必要的就是PK,這次實做簡單登入 所以直街先手動新增一筆假一料
3.建立一個ADO.NET 實體模型資料庫 > 由資料庫產生 > 新增連接 > 依提示操作設定連線資訊 > 測試連接看能不能成功 > 完成後記得build一下
4.在Controller新增一個AccountController 在新增一個View /Account/Login.cshtml
因為在微軟內建的驗證中有一個已經幫我們做好驗正了
 app.UseCookieAuthentication(new CookieAuthenticationOptions
 {
         AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
         LoginPath = new PathString("/Account/Login")
 });
5.新增一個ViewModels資料夾來存放自己定義的model 加入
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
定義Model
    public class Login 
    {
        [DisplayName("登入帳號")]
        [Required(ErrorMessage = "請輸入登入帳號")]
        [StringLength(40, ErrorMessage = "登入帳號最多20個字")]
        public string AccountName { get; set; }

        [DisplayName("登入密碼")]
        [Required(ErrorMessage = "請輸入登入密碼")]
        [StringLength(40, ErrorMessage = "密碼最多20個字")]
        [DataType(DataType.Password)]
        public string  Password { get; set; }
    }
Login的畫面
2013-10-30更新
                @using (Html.BeginForm("Login", "Login", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post))
                {
                    @Html.AntiForgeryToken()
                    @*@Html.ValidationSummary()*@

                    

後台登入

@Html.LabelFor(model => model.AccountName, new { @class = "control-label" })
@Html.TextBoxFor(model => model.AccountName, new { @class = "form-control", placeholder = "請輸入登入帳號" }) @Html.ValidationMessageFor(model => model.AccountName, null, new { @class = "help-inline" })
@Html.LabelFor(model => model.Password, new { @class = "control-label" })
@Html.PasswordFor(model => model.Password, new { @class = "form-control", placeholder = "請輸入登入密碼" }) @Html.ValidationMessageFor(model => model.Password, null, new { @class = "help-inline" })
@TempData["Error"]
}
登入的Action
2013-10-30更新
      [HttpPost]
        [ValidateAntiForgeryToken]     
        public ActionResult Login(Login form)
        {
            if (ModelState.IsValid)
            {               
                //驗證資料庫登入
                //這邊請使用自行驗證摟
                string Sql = " AccountName == @0 and Password == @1 and IsUsed == @2";
                var query = (from u in db.Account.Where(Sql, form.AccountName, form.Password, "true")
                             select u).ToList();

                if (query.Count() != 1)
                {                   
                    ModelState.AddModelError(string.Empty, "帳號或密碼錯誤登入失敗");
                    return View("Index",form);
                }

                try
                {
                    query[0].LoginIP =PublicFunction.GetIpAddress();
                    query[0].LoginDate = DateTime.Now;
                    db.SaveChanges();
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError(string.Empty, ex.Message.ToString());
                    return View("Index", form);
                }
              

                bool isPersistent = false;//如果票證將存放於持續性 Cookie 中 (跨瀏覽器工作階段儲存),則為 true,否則為 false。 如果票證是存放於 URL 中,則忽略這個值。
                string userData = "";//可放使用者自訂的內容
                string mAccountID = query[0].AccountID.ToString();
               
                //寫cookie
                //使用 Cookie 名稱、版本、到期日、核發日期、永續性和使用者特定的資料,初始化 FormsAuthenticationTicket 類別的新執行個體。 此 Cookie 路徑設定為在應用程式的組態檔中建立的預設值。
                //使用 Cookie 名稱、版本、目錄路徑、核發日期、到期日期、永續性和使用者定義的資料,初始化 FormsAuthenticationTicket 類別的新執行個體。
                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
                  mAccountID,//使用者ID
                  DateTime.Now,//核發日期
                  DateTime.Now.AddMinutes(1800),//到期日期 30分鐘 
                  isPersistent,//永續性
                  userData,//使用者定義的資料
                  FormsAuthentication.FormsCookiePath);
              
                string encTicket = FormsAuthentication.Encrypt(ticket);
                Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));

                //HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
                //cookie.Expires = ticket.Expiration;
                //Response.Cookies.Add(cookie);

                //FormsAuthentication.RedirectFromLoginPage(strUsername, isPersistent);

                if (form.ReturnUrl != null)
                {
                    return Redirect(form.ReturnUrl.ToString());
                }
                else
                {
                    return RedirectToAction("Index", "Admin");
                }
                
            }
            //return RedirectToAction("Index", "Login", null);
            return View("Index", form);
        }

最後再需要驗證的Class上加[Authorize] 雖然大部份程式碼都是copy來的
但也花了一下午才了解如何登入
看來還真有的學呢

2013-10-26補充 請注意Web.Config裡的設定

修改成
 
      
    

2013-10-30更新
在login頁多加一個returnUrl
這樣使用者登入後可直接到他需要的頁面
上面的View跟Controller都需更新
   public ActionResult Index(string returnUrl)
        {            
            ViewBag.ReturnUrl = returnUrl;
            return View();
        }   

2013-11-13更新
MVC5使用範本新增如果加了authentication mode="Forms"
此時自訂的驗證會不正常
修改
public override void ExecuteResult(ControllerContext context)
            {               
                var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
                if (UserId != null)
                {
                    properties.Dictionary[XsrfKey] = UserId;
                }
                context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
            }
改為
public override void ExecuteResult(ControllerContext context)
            {
               //多下列這行
                context.RequestContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
                var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
                if (UserId != null)
                {
                    properties.Dictionary[XsrfKey] = UserId;
                }
                context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
            }
參考網址
點我前往
點我前往
點我前往
點我前往
點我前往
點我前往

2013年10月3日 星期四

Google 讓Google幫你翻譯你的網站吧

剛在查Html5 TAG時偶然發覺得
這算是一個相單不錯的功能
但前提是你必需相信Google翻譯
點我前往

因為使用方式相當簡單所以就不另外寫了
還是不會使用的請點下面連結
網路上的教學

2013年10月1日 星期二

IIS Html5 Video tag影片不能撥放

我想Html5是一個必然的趨勢
他新增了許多的tag然後各大瀏覽器都會陸續支援功能
使用方式點我進入

但看標籤是IIS
所以今天並不是要講怎麼使用html5標籤來撥影片
基本上看了範例應該不難

將網頁及影片放到IIS上後發覺影片不動了
看原始碼點了連結發現原來404找不到檔案
看了一下原來IIS並不認識.mp4的副檔名是什麼


處理方式如下
在IIS上 > MIME類型右鍵 > 開啟功能
新增

副檔名打mp4
MIME類型打application/octet-stream

以上完成後瀏覽器有支援就能撥放

以下連結是有關html5 video 的好站
Safari Html5 Developer
點我前往

2013年9月29日 星期日

Html5 判斷是否為行動裝置

之前覺得相當好用但忘記記錄
今天補上連結如下
http://detectmobilebrowsers.com/
基本上很好套

2013年9月26日 星期四

Android DDMS加入檔案時錯誤

相信大家在測試階段會使用DDMS或者ADB方式將資料放入Android模擬器中
有時也會出現一些無法將資料放入的錯誤

1.Failed to push items null
a.將eclipse > windwos > Preferences > Android > DDMS > ADB connection time out (ms)條大一點
b.檢查看看是否有掛載sd卡

2.Failed to push selection: Invalid argument
將檔名改成純英文

3.Failed to push  on emulator- : Read-only file system
a.看看模擬器的實體路徑對不對
b.看模擬器路徑中是否有空白或一些字元如-之類( 最好在於簡單的絕對路徑會比較好)
c.檢查看看是否有掛載sd卡

參考網址
點我前往

以上是可能預到的如有其他再補上

2013年9月25日 星期三

Javascript return confirm 換行

雖然這是個很簡單的東西
但我始終是記不起來阿
Button1.OnClientClick = "return confirm('您確定要刪除嗎??\\n\\r刪除後將無法復原!!');";
重點再於一個\\n\\r
在程式中為什麼要\\呢如果在網頁內就直接寫\n\r即可
因為\是跳脫字元

2013年9月22日 星期日

T-SQL 找回被刪除的資料

相信大多數的人都是在user下了delete後就把資料刪了
這樣資料庫就不會那麼大
記得之前DBA有跟我說過資料不要刪
所以在程式部份會有一個欄位去判斷已刪的話資料就不會顯示了
這樣後面就能查的出來
這是相當好的方式
但如果是個經常刪除的table就會浪費許多空間

只是一直找不到好方法去讀log
不然log經常都那麼大又用不到
透過 Transaction Log(fn_dblog) 找回被刪除的資料
感謝亂馬客改了那麼好用的sql語法
測試後真的好用
要先執行預存程序後才做的刪除才會查的到喔(我測試是這樣)
希望這篇對大家都有幫助

ps欄位是varbinary之類的可能無法使用

2013年9月16日 星期一

T-SQL 備份所有資料庫

相信許多人跟我一樣懶
所以都會找許多簡單且別人已經寫好的語法來使用
備份資料庫是相當重要的
或許在工具上就已經有提供了
所以可以在固定的時間就會固定的備份
但我也常發覺到有了這功能後
除非職務是DBA不然不會每天去看是否有備份

然而事情就會發生
剛好就是會有不知為什麼系統就是會沒幫我們備份
又剛好就是系統有問題就是需要還原
唉~所以我個人通常都會在上班、下班及修改資料庫前先備份
每次用工具點就很麻煩
以下提供一個已經有人寫好的T-SQL連結給大家
希望不要再有資料遺失的遺憾了!!

如何使用 T-SQL 來備份所有的使用者資料庫

2013年8月25日 星期日

AngularJS filter一次整理(Part2)

剛接觸Angularjs不久所以沒有寫的很好
filter部份除了Limit To沒用其他都用上啦
應該算是個還可以的範例
希望對有看到這篇文章的人有幫助

點我下載

2013年8月22日 星期四

Javascript 目前取得clinet端日期時間

以下做法雖然很瞎但是相當好用
但注意的是取得的是目前clinet端瀏覽器的時間喔非server上的時間要注意就好

var d = new Date();
var month = d.getMonth() + 1;
var day = d.getDate();
var hour = d.getHours();
var minutes = d.getMinutes();
var seconds = d.getSeconds();
var NowDate = d.getFullYear() + '-' + toTen(month) + '-' + toTen(day);
var Now = d.getFullYear() + '-' + toTen(month) + '-' + toTen(day) + ' ' + toTen(hour) + ":" + toTen(minutes)+":" +toTen(seconds);
alert(NowDate);
alert(Now);
function toTen(s) {
return s < 10 ? '0' + s : s;
}

2013年8月20日 星期二

Html5 語音輸入功能

下午試一下語音輸入語法如下

<input type="text" name="text" placeholder="請輸入" id="text"   x-webkit-speech x-webkit-grammar="bUIltin:search"  />

但需要webkit的瀏覽器才有
chrome才會出現
剛測試結果只有電腦版的chrome才會有
如果用手機的不會出現
我在想可能在手機鍵盤上本來就有

2013年8月2日 星期五

c# DataTableToLinq常用語法(附原碼)

記得剛開始在寫程式時公司是用VB那時LINQ剛出,於是就用了LINQ+ ADO.NET Entity Framework ,一開始也是相當不順,但用久就習慣了。

後來也有人問我說用VB寫LINQ語法不會卡卡的嗎,我到覺得用ADO.NET Entity Framework 才會卡卡因為必需規劃的很詳細,不然很麻煩,所以後來我都用Datatable,可能在自由度會比較高,但是如果自己打錯字就完了。

後來常會遇到有些相當麻煩的語法,想起了LINQ相當好用於是找了LINQ來搭配Datatable(當然dataset也可),解決了許多已經撈出資料後做處理的問題,我覺得只要搭配的好不一定真的要用全新的功能,所以以下原始碼給大家參考使用,當然裡面只是小部份而且寫法也可多變,只是讓我自己在忘記時能快速查到使用方式。

2013-08-02
內含以下語法
distinct
groupby
join
leftjoin
like
orderby
top
where

原始碼點我下載去

2013年7月12日 星期五

Asp.net PostBack後停在原網頁位置

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="" Inherits="" MaintainScrollPositionOnPostback="true" %>
加上MaintainScrollPositionOnPostback="true"
雖然這很久之前就要知道了
但最近有人問我就做一次筆記摟

IIS HTTP 錯誤 404.11 - Not Found 要求篩選模組設定為拒絕包含雙重逸出序列的要求。

又來解決錯誤了
問題是發生在網址列做seo用中文時
如果發佈到g+ 後網址中如果有空白會變成+號也就是%20=>+號

 1.打開IIS點選要求篩選


2.點右邊的編輯功能設定

3.最後勾選允許雙重逸出


網址列有些字元最好是不要用
上傳檔案至 IIS 的檔案名稱有三個字元最好禁止使用: % # +

參考資料
點我前往
點我前往

2013年7月8日 星期一

AngularJS 初學及整理(Part1)

這幾天由朋友提供了AngularJS這個js好奇的我當然開始找資料
找到一篇邊學AngularJS邊做Todo List只能說將最重要的CRUD都寫上了
看完1~4大概有點小懂了
再看看最下面有提供一個範例就能比較好了解

以下筆記給自己參考

1.ng-app
將本頁變成AngularJS的應用程式(放於<html ng-app>旁邊)

2.需加入AngularJS參考
http://code.angularjs.org/angular-1.0.1.min.js
https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js

3.ng-controller
用來控制本頁面的控制器如MVC的C(廢話)

4.ng-submit
指定送出表單的function

5.ng-model
綁定繫結的欄位名稱

6.ng-repeat
跟asp.net 的repeat差不多,不用迴圈自動綁入

7.ng-hide,ng-show
顧名思義就是顯示隱藏

8.ng-click,ng-dblclick
顧名思義就是按一下跟按兩下

以上翻譯如不是很好請見諒
可能平常沒在寫MVC所以學起來有點吃力
有了這方便的東西後真該寫寫MVC了

以上參考來源
點我進入
相當好的範例

2013年6月18日 星期二

Asp.net 具有潛在危險 Request.Form 的值已從用戶端 偵測到 PartII

之前有寫過一篇Asp.net 4.0 validateRequest="False"仍有錯誤

但想了想將驗證關閉是一個很大的風險

萬一真的有攻擊不就完了

剛測試使用try catch居然也抓不住哈!!

想說真有時還是要檔一下

找了一下方法有幾個

1.一頁一頁改
2.寫在web.config
但都只是將驗證關掉

如果不關掉的話該怎麼辦還好找到下列連結
直接寫在Global.asax裡也不錯
只寫一次將錯誤導入錯誤頁如果真要關驗證還是只關該頁吧!!

2013年5月5日 星期日

Javascript 為了再次顯示網頁,網頁瀏覽器必需重新傳送您之前送出的資訊。



<script>alert('完成');location.reload();</script>

在IE上面出現了"完成"後再跳
為了再次顯示網頁,網頁瀏覽器必需重新傳送您之前送出的資訊。
然後網頁就會一直重複
找到的解決方法為

<script>alert('完成'); location.replace(location.href);</script>

參考

點我前往
點我前往

2013年4月23日 星期二

Windows 8 & 2012 啟用序號方式

按windows鍵 + R跑出執行 > cmd > Slui 3 > 出現畫面輸入序號完成即可

參考來源

2013年4月11日 星期四

HTC MTP Device FAILED

安裝完HTC SYNC MANAGER後確還是不能將手機跟電腦連結時解決方法如下:
1.手機可以插著usb沒關係 > 開始 > 搜尋程式及檔案 > 輸入"regedit"
2.展開HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{EEC5AD98-8080-425F-922A-DABF3DE3F69A}刪除“upperfilter”項或“lowerfilter”
3.開始 > 電腦上右鍵 > 管理 > 裝置管理員 > 將驚嘆號的都先移除 > 在最上面右鍵 > 掃瞄硬體變更
參考來源

2013年4月8日 星期一

Android Develpoer Tools

之前要開發Andorid相當麻煩
過去剛學時有寫過一篇Android 開發前下載的程式,安裝順序,及設定
還要找到底用什麼版的Eclipse開發浪費時間
直到昨天突然的Eclipse掛掉後一切都不同了
只需到http://developer.android.com/sdk/index.html
下載一次裡面都已經包好了
內容有
eclipse
sdk
只需要安裝基本的java
然後設定一下sdk的路徑
window > preferences > android > SDK Location
就可以用了
天阿之前還攪一堆


希望大家都能開發中好用的軟體喔!!

ps sdk裡只會含最新的我目前的是4.2.2如果有使用舊版的話,請下載舊版的Packages即可喔


===========================================
2013-09-07補充
如果使用新的Develpoer Tools舊專案確一直有錯時
請在專案上右鍵 > properties > Android > Project Build Target設定一下即可 ===========================================
2013-12-30補充
如果開啟舊的workspace沒出現ADT Manager的話可以另開一個workspace資料在將舊的匯入

2013年3月10日 星期日

Android 發怖APK至Google Play常見問題整理


在發怖到Google Play問題如下

1.您上傳的 APK 是在偵錯模式中進行簽署,請在發佈模式中簽署 APK。
2.您上傳的 APK 未經簽署,請建立具有簽章的 APK。
3.您上傳的 APK 未經壓縮校準,請對您的 APK 執行壓縮校準工具,然後重新上傳。

解決1跟2的方式
點我前網

最簡單步驟
1.找到keytool.exe位置
執行命令提示字元在位置下執行下列,產生出easyusing.keystore
keytool -genkey -v -keystore easyusing.keystore -alias easyusing -keyalg RSA -keysize 2048 -validity 10000
2.在eclipse專案中左鍵 > Android Tools > Export Signed Application Package > 要匯出的專案 > 選擇剛產生的keystore,及剛所輸入的密碼 >選擇匯出的apk位置
3.再執行zipalign即可上傳

解決3的方式
第一次發怖到Google Play時出現了這個問題
找了一下使用zipalign來優化
點我前網教學
點我下載軟體

最簡單步驟
1.下載軟體解壓
2.將apk copy到資料夾下
3.執行優化.bat
4.到newApp中點改檔名.bat就完成

以下有再補充

Android 模擬器截圖

相信大家在發佈apk檔到google play會被要求需截圖
小畫家截大小不一樣還傳不上去
找到ddms.bat執行


 點選到機器上面 > 右鍵 > CTRL +S

就會出現目前模擬器上的畫面按Save就能存了夠簡單吧
PS如果手機接上開發模式一樣可以用

2013年3月4日 星期一

Asp.net 網頁關閉前跳確認視窗(jQuery)

相當幸運有使用者要求這功能
剛好在網路上找到兩篇文章有教
參在一起就ok了




資料來源
參考1
參考2

2013年1月21日 星期一

Asp.net ashx中使用session

using System.Web.SessionState;
public class checkCookie : IHttpHandler ,IRequiresSessionState
這樣就能使用session啦

參考點我前

2013年1月14日 星期一

Asp.net 關掉ViewSatae吧!!

相信使用asp.net都知道viewstate是相當好用的東西,相反的他也是個大魔王
會產生大量的編譯文字
許多元件都需要放在form裡面
只要放在裡面就會自動產生一堆編譯文字
找了篇文章大家請參考寫的很好
檢查了一下自己的程式將viewstate都關了減低傳輸量