2013年3月28日 星期四

[ASP.NET]產生一組英文加數字混和的亂數字串

這篇算是一個小筆記 :P

有時候我們會去需要產生一組亂數的字串

用於產生新密碼或者是驗證之類的,直接把它用成共用的Functuin還蠻方便的

protected void Page_Load(object sender, EventArgs e)
{
    //使用
    Response.Write(CreateRandomCode(10));
}

/// <summary>產生亂數字串</summary>
/// <param name="Number">字元數</param>
/// <returns></returns>
public string CreateRandomCode(int Number)
{
    string allChar = "0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
    string[] allCharArray = allChar.Split(',');
    string randomCode = "";
    int temp = -1;

    Random rand = new Random();
    for (int i = 0; i < Number; i++)
    {
        if (temp != -1)
        {
            rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
        }
        int t = rand.Next(36);
        if (temp != -1 && temp == t)
        {
            return CreateRandomCode(Number);
        }
        temp = t;
        randomCode += allCharArray[t];
    }
    return randomCode;
}

當然這個重複性還是蠻高的,如果一定要產生唯一的亂數

可以使用Guid類別,他會針對使用者的電腦去產生一個唯一值

重複機率可能比樂透還低

-----

若文章有侵權地方,麻煩請告知,將迅速處理,謝謝!

2013年3月22日 星期五

[Jquery]搭配Jquery UI讓表單Email欄位自動完成

Technorati 的標籤:
最近寫到一個功能,為了要讓使用者快速建立表單,

多半會有自動完成的功能,類似Google搜尋會跑出建議的選項點選

所以在Email欄位,希望能讓使用者Key的時候自動帶入常用的Host

網路上有Jquey Autocomplete 的套件,還沒深入研究過,但我想功能應該更齊全,

此範例只用官方的Jquery UI來完成:

首先先到官方網站下載頁面,第一個下拉選單可以選擇主題,其實只是載入不同的css檔
image

以下是下載後的檔案結構,我新增一個autocomplete的網頁檔

image

當然記得在<head></head>裡載入Jquery的 Js檔

image

在Body新增一個Input標籤

image

接著在<head></head>加入以下程式碼,

大概邏輯是每MailData是我建立常用Email的資料

在Key in的時候將字串"@host.com",插入最後面

        $(document).ready(function () {
            var MailData = ["gmail.com", "hotmail.com", "msn.com", "yahoo.com", "yahoo.com.tw", "pchome.com.tw"];
            $("#email").autocomplete({
                autoFocus: true,
                source: function (request, response) {
                    var KeyValue = request.term,
                        index = KeyValue.indexOf("@"),
                        Address = KeyValue,
                        host = "",
                        result = [];

                    result.push(KeyValue);
                    if (index > -1) {
                        Address = KeyValue.slice(0, index);
                        host = KeyValue.slice(index + 1);
                    }
                    if (Address) {
                        var findedHosts = (host ? $.grep(MailData, function (value) {
                            return value.indexOf(host) > -1;
                        }) : MailData),
                        findedResults = $.map(findedHosts, function (value) {
                            return Address + "@" + value;
                        });
                        result = result.concat($.makeArray(findedResults));
                    }
                    response(result);
                }
            });
        });
</script>

最後的完成圖:

image 

若文章有侵權地方,麻煩請告知,將迅速處理,謝謝!

2013年3月6日 星期三

[ASP.NET MVC]利用ViewEngines來載入不同的View

這標題有點抽象,製作Master Page 與 Detail Page,在ASP.NET我們通常會用Masterpage控制項,
去把一些共用的樣式放在母版裡面,當然也可以利用Ajax的方式載入Detail Page的內容放置div裡面
在ASP.NET MVC,做法當然也有很多種,在這裡分享一下我實務上常用到的小技巧:
1
Technorati 的標籤:
我先新增一個MVC專案,在Controllers裡面增加MasterPage的Controllers
並產生一個Index的View,及3個分別顯示不同內容的View
Controllers裡會是長這樣子:
public ActionResult Index(int Type)
{
    string ViewType = string.Empty;

    //針對傳入的參數,導向不同的View
    switch (Type)
    {
        case 1:
            ViewType = "Detail1";
            break;
        case 2:
            ViewType = "Detail2";
            break;
        case 3:
            ViewType = "Detail3";
            break;
        default:
            break;
    }

    var content = string.Empty;
    var view = ViewEngines.Engines.FindView(ControllerContext, ViewType, null);
    using (var writer = new StringWriter())
    {
        var context = new ViewContext(ControllerContext, view.View, ViewData, TempData, writer);
        view.View.Render(context, writer);
        writer.Flush();
        content = writer.ToString();
    }
    ViewData["DetailView"] = content.ToString();

    return View();
}



此頁面需要傳入一個int的Url參數,再針對不同的值顯示不同的Detail內容,

我們可以用ViewEngines這個Class來取得View的內容,

取得之後將View的內容丟給ViewData,然後再丟給Index.cshtml顯示:
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>Index</title>
</head>
<body>
    <div>
        @(new HtmlString(ViewData["DetailView"].ToString()))
    </div>
</body>
</html>

以下為結果:

2

2013年2月26日 星期二

[Asp.NET]將數字轉為圖片

最近吵得沸沸揚揚的內政部實價登錄網站,提供各縣市.地區的房價查詢
因為房價透明化,上線第一天就造成大量的流量而造成網路癱瘓
當然今天這篇文章不是在譴責上線沒做好壓力測試,也不是來做房地產分析,
眼尖的人最近應該有發現最近在網站上的價格有些不一樣:
1
用瀏覽器的開發者工具可以發現總價的部分都改為圖片了
2
改成圖片的原因的目的就是政府不讓外界抓到這些統計資料,
進而將這些資料去讓房仲業做出另一個介面提供查詢
當然這邊文章也不是要討論Open Data的相關議題
只因為以前有做過類似的需求,所以來介紹一下數字轉圖片的功能
基本上此功能在C#可以用Graphics這個類別去繪製出來,
我將他寫成一個方法來完成此需求:

private string TransIntToImage(int Number)
   {
       string StrNum = Number.ToString();
       Bitmap Bmp = new Bitmap(StrNum.Length * 80, 25);  //建立實體圖檔並設定大小
       Graphics Gpi = Graphics.FromImage(Bmp);
       MemoryStream stream = new MemoryStream();

       Gpi.Clear(Color.White);    //設定背景顏色
       Font _font = new Font("Verdana", 9, FontStyle.Bold); //設定字型大小.樣式
       for (int i = 0; i < StrNum.Length; i++)
       {
           Int32 j = i * 18;
           Gpi.DrawString(StrNum[i].ToString(), _font, Brushes.Blue, j, 0);
       }
       Bmp.Save(stream, ImageFormat.Jpeg);
       byte[] byteArray = stream.GetBuffer(); //將Bitmap轉為Byte[]
       return Convert.ToBase64String(byteArray); //轉為Base64sting
}

回傳的是一個Base64字串,目的是直接顯示在網頁上,不再另存圖片了:

使用方法如下:
protected void Page_Load(object sender, EventArgs e)
{
    string temp = TransIntToImage(51515);
    img_Number.ImageUrl = "data:image/jpeg;base64," + temp; //直接在網頁上顯示圖片
}

結果顯示:

image



若文章有侵權地方,麻煩請告知,將迅速處理,謝謝!

2013年2月13日 星期三

[Html]Facebook分享連結卻與meta description不一致的情況

一個很蠢的小問題,卻糾纏了1個小時,做個小記錄不要再有人受害~
Facebook近況分享可以貼上影音連結、新聞、等其他外部網站,如下圖:
1
而這些縮圖、標題、內文敘述主要是存在於Html的meta欄位
點選右鍵查看原始碼就可看見:
2
但今天在做本公司網頁時,在FB分享卻存在於舊的資訊,
一看就知道Facebook有cache的機制,網頁修改meta資訊,直接分享還是會存在於舊的
不知道什麼時候這些cache會清掉,但也不能傻傻的等
一開始的解決方式是直接更換檔名,非常的愚蠢XDD
後來才找到Facebook有針對Developers的debug頁面
只要將你更新後的網頁連結,丟上此連結後,
分享過後就會發現是最新修改的資訊了!

2013年2月11日 星期一

[ASP.NET]Html轉成PDF的解決方案

最近遇到一個需求,需要將Html轉成PDF,上網找解決方案找老半天,
不是付費的不然就是匯出後整個版面跑掉,或者是中文亂碼
甚至用過itextsharp這種控制PDF的套件去寫,也不是麼容易T__T
後來發現wkhtmltopdf這個免費的套件,終於解決了我的問題,所以一定要來分享一下!
一開始先至官網下載,依據自己的作業系統下載
1
安裝的話就是一直下一步就對了,
筆者安裝路徑為D:\wkhtmltopdf\wkhtmltopdf.exe
接著我們進入DOS模式去執行程式
2
3
第一個黃框為執行檔的位置
第二個黃框為轉檔目標的URL
第三個黃框為PDF儲存的位置
接著執行就直接進行轉換了:
image
目前測試效果還不錯,如果是中文字的話,記得要在編碼設定為utf-8
不然轉換後都會是亂碼!
接著我們自己寫程式執行吧!
基本上大同小異,只是利用Process這個類別去執行它而已:
protected void Page_Load(object sender, EventArgs e)
{
    Process _process = new Process();
    _process.StartInfo.FileName = @"D:\wkhtmltopdf\wkhtmltopdf.exe";
    _process.StartInfo.Arguments = @"http://www.google.com.tw D:\temp2.pdf";
    _process.Start();
}

如果你要在產生過後,對這個PDF檔案做一些處理(例如開啟此檔案),

必須要等這個執行續完成,不然會出錯,可以用以下方法:
Process _process = new Process();
_process.StartInfo.FileName = @"D:\wkhtmltopdf\wkhtmltopdf.exe";
_process.StartInfo.Arguments = @"http://www.google.com.tw D:\temp2.pdf";
_process.Start();

while (_process.HasExited)
{
    //讓執行續暫停1秒
    Thread.Sleep(1000);
}

Process.Start(@"D:\temp2.pdf");

這樣就完成了,其實他還有很多姊妹作,像是HtmlToImage

有機會再分享囉!

相關文章:

http://brooky.cc/2011/05/26/convert-html-to-image-and-pdf/

http://code.google.com/p/wkhtmltopdf/

http://www.cnblogs.com/heblade/archive/2009/10/16/Html_to_pdf.html

2013年2月7日 星期四

[MS SQL]將多筆資料合併欄位,減少不必要的連線

之所以會有這篇文章,是最近在改寫公司老舊的ASP報表

主要的邏輯是撈出全部資料後,逐筆判斷該資料在另一個Table是否有相似的資料

如果有則Response出來,秀在此筆資料的下方,但如此簡單的邏輯,卻要Run很久才能跑出來

仔細看他的寫法是這樣,我以C#改寫,以使用者登入紀錄為例,我建了兩個資料表:


使用者資料表
登入紀錄資料表
1 2

當然這裡舉例的不是那麼恰當,登入紀錄應該是記錄到時分秒單位

重點是在下面這段程式:


string connString = WebConfigurationManager.ConnectionStrings["TestDBconn"].ConnectionString;
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;

string Sql_User = "select * from [User]";
SqlDataAdapter da = new SqlDataAdapter(Sql_User, conn);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        //依使用者撈出登入紀錄
        string Sql_Login = "select * from LoginRecord where UserID = " + dt.Rows[i]["sn"].ToString();
        da = new SqlDataAdapter(Sql_Login, conn);
        DataTable dt_login = new DataTable();
        da.Fill(dt_login);
        if (dt_login.Rows.Count > 0)
        {
            for (int k = 0; k < dt_login.Rows.Count; k++)
            {
                /* 
                 * Show Login Data . . . . .
                 */
            }
        }
    }
}

乍看之下結果沒什麼問題,但很可怕的是逐筆連線去執行select

因如果資料可能上千上萬,甚至DB是用 Link Server的方式,

原本連線要兩秒這樣加下來就會Run到天荒地老

接著就會換來使用者的一句,程式怎麼寫那麼爛Q_Q

所以將這支程式做一點改寫,使用SQL的for XML Path語法

3

現在已經把該使用者登入紀錄全篩到一個新的欄位LoginData,

但這樣還是不太好閱讀,故我們用一些小技巧,把它轉為varchar

並用逗號分隔,再用Substring去除開頭的逗號:

4

如此已經完成抓出每個使用者的登入紀錄了,

接下來只要把這個子查詢,加入主表裡就改寫成功了:

5



經過這樣改寫已經把連線此數降為1次,

接下來只需要在程式裡用Split切割逗號,去秀出要的資料,

這種寫法應該是程式老手不太會犯的錯誤,

活生生的案例在實務上遇到了,也許一開始資料量小沒care這麼多

但還是養成code review的習慣以免害到後人阿!