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()*@

                    <h3>後台登入</h3>


                    <div class="logintype">
                        @Html.LabelFor(model => model.AccountName, new { @class = "control-label" })
                        <div class="controls">
                            @Html.TextBoxFor(model => model.AccountName, new { @class = "form-control", placeholder = "請輸入登入帳號" })
                            @Html.ValidationMessageFor(model => model.AccountName, null, new { @class = "help-inline" })
                        </div>
                    </div>
                    <div class="logintype">
                        @Html.LabelFor(model => model.Password, new { @class = "control-label" })
                        <div class="controls">
                            @Html.PasswordFor(model => model.Password, new { @class = "form-control", placeholder = "請輸入登入密碼" })
                            @Html.ValidationMessageFor(model => model.Password, null, new { @class = "help-inline" })
                        </div>
                    </div>

                    <div class="logintype">
                             @TempData["Error"]
                    </div>
                    <input type="submit" name="button" value="登入">
                }
登入的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裡的設定
<authentication mode="None" />
修改成
 <authentication mode="Forms">
      <forms  loginUrl="/Login" path="/"></forms>
    </authentication>

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日 星期日

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日 星期日

Angular 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日 星期一

Angular 初學及整理(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日 星期二

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.開始 > 電腦上右鍵 > 管理 > 裝置管理員 > 將驚嘆號的都先移除 > 在最上面右鍵 > 掃瞄硬體變更
參考來源