星期四, 10月 28, 2010

ASP.NET RSS Toolkit 的使用方法(字串輸出)

今天在處理有關 RSS 的需求,一直以來我遇到 RSS 都會用 ASP.NET RSS Toolkit 的這個人家開發好的 Project 來使用,他的使用方式也很簡單,你可以參考我的好友 demo 寫的 ASP.NET RSS Toolkit快速滿足你對於RSS的需求 的文章就可以了,不過我還是嫌使用方式還是有點小麻煩,所以參考了一下 source code,直接把 Rss 內容用字串的方式 Render 出來,直接看 code 吧!!

/// <summary>
/// Rss Helper
/// </summary>
public class RssHelper
{
/// <summary>
/// 取回Rss內容
/// </summary>
/// <returns></returns>
public string GetRssContent()
{
var rss = new RssToolkit.Rss.RssChannel();
rss.Title = "我的訊息RSS";
rss.Link = "/";
rss.Description = "";
rss.PubDate = DateTime.Now.ToString("r");

var data = GetDb().RssMessages;
List<RssToolkit.Rss.RssItem> rssInfoList = new List<RssToolkit.Rss.RssItem>();
foreach (var item in data)
{
RssToolkit.Rss.RssItem rItem = new RssToolkit.Rss.RssItem();
rItem.Author = item.Author;
rItem.Title = item.Title;
rItem.Description = item.Content;
rItem.Link = String.Format("http://{0}/RSS/{1}", HttpContext.Current.Request.Url.Authority, item.Id);
rItem.PubDate = item.StartDate.GetValue(DateTime.Now).ToString("r");
rssInfoList.Add(rItem);
}
rss.Items = rssInfoList;

var doc = new RssToolkit.Rss.RssDocument();
doc.Channel = rss;
doc.Version = "2.0";
return doc.ToXml(RssToolkit.Rss.DocumentType.Rss).Replace("utf-16", "utf-8");
}
}

這樣就很簡單的把字串直接抓出來,你要怎麼處理就怎麼處理,讚吧!!

參考:

星期二, 10月 12, 2010

(題目)取亂數不重複 2

之前發過一篇文章"(題目)取亂數不重複",這篇文章用了洗牌演算法來做這個需求,這個 method 效率跟功能都很不錯,也時常在專案中使用到,今天在處理相同的問題時,順手問一下同事,也查一下網路的資料,發現有一種寫法也很不錯,這裡也來紀錄一下,直接看 code 吧!!

public class RandomCreator
{
/// <summary>
/// 取出亂數不重複的array
/// </summary>
/// <param name="min">最大值</param>
/// <param name="max">最小值</param>
/// <param name="count">取出的筆數</param>
/// <returns></returns>
public static int[] GetRandomNumber(int min, int max, int count)
{
if (max - min < 0)
throw new Exception("請輸入正確的範圍");

if ((max - min + 1) < count)
throw new Exception("請輸入想取得的正確數字");

int rang = max - min + 1;
return Enumerable.Range(min, rang)
.OrderBy(a => Guid.NewGuid())
.Take(count)
.ToArray();
}
}

上面的方法,就是把範圍取出來,然後用guid去標記之後再排序,因為guid每次都不同,所以就亂數啦,這方法很像我們 MS-SQL 裡面取亂數的方法,很簡單又很直覺,分享一下..^^..

參考:

星期一, 10月 04, 2010

用 Subversion 來自動更新網站版本和更新時間

不知道各位有沒有在用版本控管的程式,小弟有在用 Subversion 這個軟體,來幫我做版本管理,用了一段時間,也越來越習慣 Subversion 這個軟體,今天來分享一下小技巧,先把想法需求說出來。我的目標是想要把 Subversion 的版本更新的時間放在頁面上,讓我就可以方便做出網站版本和更新時間功能..

如下圖

image

這個作法很簡單,只要簡單的設定就行了,看圖說故事吧,首先我們先找到我們要顯示版本頁面的檔案,按下右鍵

image

再選擇 Subversion -> Properties

SNAGHTML522d1e9

接下來看到 Properties 視窗,選擇 New

SNAGHTML5244f14

再把需要修改的內容寫入(需要更多的設定訊息,請看這裡

SNAGHTML525c9ce

這樣設定就完成啦,之後再簡單把程式設定加入就行了,接下去看

image

注意上面這畫框框地方,注意上面紅色框框的地方,Subversion 在更新的時候就會幫你自動取代掉,格式就像下面這樣

image

我們再簡單處理一下內容,就可以了,讚!!

參考:
http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html

星期二, 9月 21, 2010

修改 Subversion 的 Log Message

不知各位在使用 Subversion 的時後,是否常常在上傳 Log Message 後覺得自己好像沒有寫的很好,或是有些時候想改一下某版本的 Log Message..
今天分享一下如何修改 Subversion 的 Log Message,大家看圖說故事吧!

先選擇要修改哪一個版本

image

寫入要修改的文字

SNAGHTML8416800

出現錯誤拉..><||..
看了一下錯誤,原來是權限的問題,subversion 預設是不允許回去改 Message Log 的,所以要去改 Server 端的權限

SNAGHTML8420ed9

修改 Server 端的 VisualSVN Server 的權限

image

修改 Pre-revision property change hook

image

把下面提供的 script 貼到這裡面,就可以啦

image

Script

@ECHO OFF

set repos=%1
set rev=%2
set user=%3
set propname=%4
set action=%5

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Only allow changes to svn:log. The author, date and other revision
:: properties cannot be changed
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
if /I not '%propname%'=='svn:log' goto ERROR_PROPNAME

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Only allow modifications to svn:log (no addition/overwrite or deletion)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
if /I not '%action%'=='M' goto ERROR_ACTION

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Make sure that the new svn:log message contains some text.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set bIsEmpty=true
for /f "tokens=*" %%g in ('find /V ""') do (
set bIsEmpty=false
)
if '%bIsEmpty%'=='true' goto ERROR_EMPTY

goto :eof



:ERROR_EMPTY
echo Empty svn:log properties are not allowed. >&2
goto ERROR_EXIT

:ERROR_PROPNAME
echo Only changes to svn:log revision properties are allowed. >&2
goto ERROR_EXIT

:ERROR_ACTION
echo Only modifications to svn:log revision properties are allowed. >&2
goto ERROR_EXIT

:ERROR_EXIT
exit /b 1

上面這段 script 很簡單,看不懂的就貼上去就好了 囧rΩ..

參考:
http://subversion.tigris.org/

http://svn.haxx.se/users/archive-2006-03/0107.shtml

星期三, 8月 25, 2010

用Linq to SQL亂數取一筆

之前有一篇文章用Linq to SQL亂數取一筆,今天在寫這個需求的時候,看到有更簡單的寫法,直接看 code 吧!

void Main()
{
var data = Products.OrderBy(a=>Guid.NewGuid()).Take(1);
foreach(var item in data)
{
Console.WriteLine(string.Concat(item.ProductID,"--", item.ProductName));
}
}

這樣就可以很簡單做出亂數取出一筆資料了,我們來看一下生出來的 SQL Statement

SELECT TOP (1)
[Project1].[ProductID] AS [ProductID],
[Project1].[ProductName] AS [ProductName],
[Project1].[SupplierID] AS [SupplierID],
[Project1].[QuantityPerUnit] AS [QuantityPerUnit],
[Project1].[UnitPrice] AS [UnitPrice],
[Project1].[UnitsInStock] AS [UnitsInStock],
[Project1].[UnitsOnOrder] AS [UnitsOnOrder],
[Project1].[ReorderLevel] AS [ReorderLevel],
[Project1].[Discontinued] AS [Discontinued],
[Project1].[CategoryID] AS [CategoryID]
FROM ( SELECT
NEWID() AS [C1],
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
) AS [Project1]
ORDER BY [Project1].[C1] ASC

Linq to SQL 幫我們用 NEWID 生出子查詢,然後再用排序的方式來抓出來,讚吧,簡單多了..^^..

PS: 經過一些測試,好像是.net framework 4.0才有效過ㄟ,^^||..喵滴..

參考:
http://msdn.microsoft.com/zh-tw/library/bb386976.aspx

星期三, 8月 11, 2010

Image 轉 Byte[] 的 GDI Error

今天在把 Image 轉成 Byte[] 的時候,一直遇到下列這個錯誤..

errorPage

關於這個錯誤,網路上沒有啥資料可以使用,自己 try 了半天,終於成功用出來了..XD
在這裡紀錄一下,讓以後遇到相同問題的人可以不用像我一樣這樣亂七八糟的亂試,看下面的 code 吧!!

/// <summary>
/// Image轉Byte[]
/// </summary>
/// <param name="image"></param>
/// <returns></returns>
private static byte[] GetImageByte(Image image)
{
Image newImage = image.GetThumbnailImage(image.Width, image.Height,
new System.Drawing.Image.GetThumbnailImageAbort(callBack), IntPtr.Zero);

ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(newImage, typeof(byte[]));
}
private static bool callBack()
{
return true;
}

這 method 的寫法,就是利用原本的 Image 生出一個跟自己一樣的 Image,得到新的 Image 再轉出來,雖然自己有覺得在逃避問題,不過,山不轉路轉阿,先轉過去,之後有時間來慢慢研究吧..暈..

星期二, 8月 03, 2010

中計了..FILCO 黑軸 80%

噹噹噹,中計了中計了,話說之前在回家的路上,收到一個自稱好心人士的禮物,心想天下哪有這麼好康的事情,可以讓我無限使用無限享受這份大禮,事情發生不到兩個月,內心驚覺這是個陰謀這是個陰謀,電視上常常看到有些新聞,就是使用一些手段讓人不知不覺的上癮,之後就離不開了,現在的我,情況就像這樣,使用了好的鍵盤後再用其他鍵盤就感覺很暗暗暗,今日心癢難忍,所以下班就去光華"金鍵盤"敗家啦..><||..

先看一下他的外殼..

DPP_00001

開箱了開箱了..

DPP_00002

看一下可愛的mark..

DPP_00003

正面來一張..無痕的無痕的..

DPP_00004

側面來一張...優滴優滴..

DPP_00005

阿們,這次敗家的花了3200大洋,也算是對自己手指的一個犒賞,畢竟鍵盤是我的吃飯傢伙,買好一點等於對自己的手指好一點,該花則花,該用則用,"人參"就是這樣阿..拉拉拉拉拉...

參考:
http://gdgt.com/diatec/filco/majestouch-tenkeyless/fkbn87ml-eb/

星期日, 8月 01, 2010

未來

女人用最珍貴的青春

來等待沒有確定的未來

是真愛還是太傻

手動加入 Entity Framework 的關聯

今天來紀錄在使用 Entity Framework 的一個技巧,我們常常在使用 .edmx 的時候需要自己去拉關聯,因為有時候資料庫的 table 跟 table 不一定會在一開始設計的時候加上關聯,或是有些時候資料庫部份我們並沒有權限去修改,這時候我們就可以自己去 .edmx 上面拉關聯,這樣我們在寫 linq to entity 就可以不用用 join in 的方式而是直接用關聯的方式寫就行了,下面我建立一個簡單的兩個 table 來做的簡單的範例

這是簡單的兩個 Table,因為資料庫裡面沒有設關聯,所以在 edmx 裡是沒有關聯的

image

我們手動加入關聯

SNAGHTMLecfebd

之後我們還要在"關聯"設定"Mapping Details"下面這個才算完成

image

編譯一下,竟然發現出現錯誤..

image

我們還要去把 Child 的 ParentId 去掉才會正確編譯的過..

image

這樣就 ok 啦,住意這個修改只有在 .edmx 裡有作用,在資料庫那邊完全不會有任何改變,所以大可放心去修改吧!

參考:
http://msdn.microsoft.com/en-us/library/aa697427%28VS.80%29.aspx

星期五, 7月 23, 2010

用 LinqPad 來使用 Entity Framework

最近再研究 Entity Framework,也試著用 Entity Frmaework 來寫專案,發覺真的需要一個工具可以幫我快速開發,以及驗證產出來的SQL Statement到底好不好,朋友就推薦我用 LinqPad,上官方網站也說可以支援 Enitity Framework,所以就直接下載來試用了,不過在 LinqPad 使用 Entity Frmaework,官方網站文字上並沒有說得很詳細,這裡簡單的介紹如何使用 LinqPad 來使用 Entity Framework

首先先新增一個 Class 專案

image

新增完,就可以在專案裡面新增要新增的 edmx 類型的檔案

image

新增 ADO.NET Entitiy Data Model

image

內容選擇從資料庫取出來

image

這裡就是最熟悉不過的設定了

image

繼續設定下去吧

image

這裡我是把所有的 Table 加進去

image

產完了,我們現在來編譯一下,因為編譯才會生出 dll 檔案

image

編譯完成後,就可以開啟 LinqPad 來設定啦,首先按 Add connection

image

在 Path to Custom Assembly 選擇我們剛剛編譯出來的 dll 檔案

image

然後跟著按下確定

image

接的設定都會幫你設定好啦,你可以按一下 Test 來確定有沒有連線錯誤

SNAGHTML27d3a3

之後就可以成功的使用 Entity Framework 啦

image

很簡單吧,讚..

而且這樣用 dll 方式產生出來的連接,如果我們在資料庫專案上對 edmx 加了哪些關聯,或是多了哪些欄位,我們就可以在 LinqPad 上面馬上使用,這樣也很貼近專案的開發方式,因為有時真的蠻需要在 edmx 上面動手腳的,所以這裡真的推薦有在用 Enitity Framework 開發的使用者,可以去載來用用

PS:用Linq to SQL 也可以用這一招來建立連線

參考:
http://msdn.microsoft.com/en-us/library/aa697427%28VS.80%29.aspx
http://www.linqpad.net/

星期日, 7月 18, 2010

(加強版) jquery 簡單新增移除 table rows

之前有寫一個簡單的範例 jquery 簡單新增移除table rows ,因為有人留言說如果可以指定行數來刪除 row 那就更有實用性了,所以我就寫了一個改良版的,這個範例結合了後端用 ajax 抓取 server 端的時間,還有用 jquery 1.3 以後才有的 .live() 的函式來處理,程式更短更簡單,直接看code吧!

View

<style type="text/css">
table
{
border: solid 1px red;
border-collapse: collapse;
}
table td
{
border: solid 1px red;
width: 150px;
}
</style>

<table width="450px" cellpadding="0" cellspacing="0">
<thead>
<tr>
<td>新增時間</td>
<td>內容</td>
<td>##</td>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>r</td>
<td><a href="javascript:;">刪除row</a></td>
</tr>
</tbody>
<tfoot>
<tr>
<td></td>
<td></td>
<td>
<%= Ajax.ActionLink("新增一筆", "GetNow",
new AjaxOptions() {
OnSuccess="CreateRow",
HttpMethod="POST",
}) %>
</td>
</tr>
</tfoot>
</table>
<script type="text/javascript">
function CreateRow(data)
{
var time = data.get_data();
var newRow = $('tbody tr:first').clone();
newRow.find('td:first').append(time);
$('tbody').append(newRow);
}
function DeleteRow(elem)
{
var row = $(elem).parents('tr');
var index = $('tr').index(row);
if (index != 1)
row.hide();
}
$(document).ready(function ()
{
$('tbody a').live('click', function ()
{
DeleteRow(this);
});
});
</script>

controller

public class TableController : Controller
{
//
// GET: /Table/

public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult GetNow()
{
return Content(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
}
}

有圖有真相

image

這樣就實用性就很高啦..讚..
參考:
http://msdn.microsoft.com/en-us/library/dd394709.aspx
http://api.jquery.com/live/

星期二, 6月 29, 2010

ViewModel 也可以是很複雜的型別阿!!

最近在實務方面,有遇到較複雜的需求,在頁面上需要有重複的子母表單,我的想法是想用 MVC 的 ViewModel 的方式丟一個 Collection 到頁面,這個 ViewModel 記載著子母表單的彼此關係,然後在頁面填完表單,可以用 Post 的方式由頁面再傳回 List<ViewModel>,讓我整個過程都用強型別來處理,所以接下來我們就把這個想法實現吧..

我們先建立子母表單的 class,然後用 TestService 這來模擬資料來源..

image

有了個些測試資料,我們開始準備要顯示的頁面,首先我們先新增兩個 UserControl,這兩個 UserControl 都要放在 EditorTemplates 裡喔,EditoirTemplates 這個命名不能亂改阿阿阿..

image

ViewModel.ascx
 
image
ViewModelChild.ascx
 
image
接下來我們要新增View


image


EditTemplate.aspx

image

接下來我們只要加入controller就大功告成了..


image


TestController.cs

image
呼呼,終於把要寫的要加的都用好了,我們來看一下跑出來的結果吧!!


Get 的方式跑出來,沒問題,優..


image 
重點來啦,如果 Post 的方式也可以接回 ViewModel,那就完美啦..


image

讚..都有抓到ㄟ,出運啦,mvc可以讓我用很簡單的方式用實質型別傳遞來處理資料,這對我們在寫程式也會非常便利,善用這種方法來處理資料,就可以不用在處理那些接值塞值得工作了..^^||...


參考:

星期二, 6月 22, 2010

抓取關聯 Table 的資料

最近在玩 Entity Framework 這個不錯的 ORM 技術,學著自己處理一些簡單的增刪查改的動作,發現還真的不錯用,尤其想到以後可以用到不同的資料庫,又可以用相同的處理手法,就覺的是很不錯的投資,不過也有發現一些需要注意的問題,我用個範例來說明一下..

這是簡單的資料表關聯圖..

image

--我想由TableA抓出TableD--

直接下語法,取出資料..

var data = db.TableA;
foreach (var tableA in data)
{
Console.WriteLine("TableA" + tableA.TableName);
foreach (var tableB in tableA.TableB)
{
Console.WriteLine("--TableB--" + tableB.TableName);
foreach (var tableC in tableB.TableC)
{
Console.WriteLine("----TableC----" + tableC.TableName);
foreach (var tableD in tableC.TableD)
{
Console.WriteLine("------" + tableD.TableName + "-------");
}
}
}
Console.WriteLine("*************");
}

它跑出的 SQL Statement

image

上圖可以看出是一個一個迴圈去下SQL Statement,這樣在筆數多的時候,效能可能會非常低落,這種方式只適合在某一個條件下去取出資料,才是比較對的選擇..

我們換另一種方式用 Include 的方式去把它一次載出來..

var data = db.TableA.Include("TableB.TableC.TableD");
foreach (var tableA in data)
{
Console.WriteLine("TableA" + tableA.TableName);
foreach (var tableB in tableA.TableB)
{
Console.WriteLine("--TableB--" + tableB.TableName);
foreach (var tableC in tableB.TableC)
{
Console.WriteLine("----TableC----" + tableC.TableName);
foreach (var tableD in tableC.TableD)
{
Console.WriteLine("------" + tableD.TableName + "-------");
}
}
}
}

這樣一次就下完所有的SQL Statement,把所有的資料都抓出來,效能一定比一筆一筆下好..

image

還有另一種方式也可以一次把資料都抓出來,就是用匿名型別的方法..

var data = db.TableA.Select(a => new
{
tableA = a,
tableB = a.TableB,
tableC = a.TableB.Select(b => b.TableC),
tableD = a.TableB.Select(b => b.TableC.Select(c => c.TableD))
});
foreach (var item in data)
{
Console.WriteLine("TableA" + item.tableA.TableName);
foreach (var tableB in item.tableA.TableB)
{
Console.WriteLine("--TableB--" + tableB.TableName);
foreach (var tableC in tableB.TableC)
{
Console.WriteLine("----TableC----" + tableC.TableName);
foreach (var tableD in tableC.TableD)
{
Console.WriteLine("------" + tableD.TableName + "-------");
}
}
}
Console.WriteLine("*************");
}

下圖的 SQL Statement 是醜了點,也沒有 Include 簡潔有利,但是不失為一個好方法..

image

這幾種抓取資料的方法,提供大家參考一下,有啥問題也可提出來一起討論看看..