Visual WebGUI 利用 HtmlBox 和 Html Page 互動

個標題好似唔係咁易明 🙂

不過,如果有用過 Visual WebGUI 嘅朋友就可能估到係講咩。

起因係我想替我用 Visual WebGUI 寫嘅其中一個 application 補寫一個功能,俾啲用戶自己更改啲 login users 嘅 security level,原本嘅 security level 用一隻 XML 檔案嚟做,記住不同 security level 喺某個功能有咩 CRUD permission。可以睇一下隻 XML 就易明好多:

Continue reading “Visual WebGUI 利用 HtmlBox 和 Html Page 互動”

使用 VisualWebGUI 的 Project 由 v6.3.17 升級至 v10.0.4

Gizmox-ProductBox-VWGps_trans

Visual WebGUI  v6.2.x 及之前嘅版本係免費嘅,不過由 v6.3.x 開始就要收錢,而且又整多咗啲 Extensions/ Enterprises 嚟收錢,所以我啲舊 projects 基本係升級到 6.3.17 就停咗,唔想再俾錢,而且佢啲新版本 6.4.x/ 7.1.x/ 7.2.x 出得好快,搶錢之餘又越搞越差,舊 bugs 喺新版本又會出現番,forum 上啲勁人又唔見哂,總之就係早走早著!

不過,到咗今年佢知道唔掂,大概係使哂啲天使投資,回歸當初,搞咗個 10.0.x 出嚟,open source,完全免費!

咁,我咪又試下升級啲 projects,由 v6.3.17 直升 v10.0.4,貪佢可以支持 Chrome/ Safari/ IE 10/ IE11,唔使淨係用 Firefox。

Continue reading “使用 VisualWebGUI 的 Project 由 v6.3.17 升級至 v10.0.4”

NetSqlAzMan 在 xPort3 中的應用

NetSqlAzMan 是基於 .Net 的一個 RBAC (Role-Based Access Control) 軟件,屬於開源的項目,可以在這裡找到,因為 xPort3 是建基於 .Net 3.5,所以我們用的 NetSqlAzMan 是 v3.6.0.5。

xPort3 則是我們自主開發的 web 應用軟件,是 .Net 3.5 + C# + Visual WebGUI v6.3.17,Visual WebGUI 也是開源的,可以在這裡找到。

NetSqlAzMan 最主要的功能是控制 CURD:

C = Create

U = Update

R = Read

D = Delete

就是說,誰可以有:新增/存檔/觀看/刪除 這四項基本權限,再因應 xPort3 增加一些特殊的權限控制的要求(例如 Approve 批核,Print 打印,等等)。
Continue reading “NetSqlAzMan 在 xPort3 中的應用”

IIS7 + SSL + Multiple Sites

新建 web server (Win2008 Standard Server) 給 SSL websites 專用,SSL 採用自製 (Self-Signed Certificate)。

在建立第二個 websites 時出現問題, 說是同一個 port 不可以給兩個 websites 共用。

當然,沒有分別設定 HTTP HEADER。

可是 IIS 的 Management Console 沒法 edit 個別 website 的 HTTP HEADER 資料啊?

原來 IIS 7 的 Management Console 未有改善這個功能,說是 IIS7.5 就可以了,又係 Microsoft 的討厭手段。

要用 appcmd 了,啟動 cmd,轉移至 C:WindowsSystem32inetsrv,輸入以下的指令:


appcmd set site /site.name:"你的 website 名" /+bindings.[protocol='https',bindingInformation='*:443:你要用的 HTTP HEADER 名']

參考資料:

  1. 這是 Microsoft 的說明
  2. 這裡是網友的說明 (比較清楚)

@Html.ActionLink 太麻煩了

不吐不快!

Microsoft 攪的東西有些時候真是無聊!

這個 MVC Razor 中用的 @Html.ActionLink 其實就是 HTML 中的 a tag. 以下是我不滿的例子:

@Html.ActionLink("Home", "Index", "Home", new { id = "", sid = "" }, new {data_role="button", data_icon="arrow-u", data_iconpos="notext"})

<a href="@Url.Content("~/")Home/Index" data-role="button" data-icon="arrow-u" data-iconpos="notext">Home</a>

第一行是 Html.ActionLink 的用法. 為了要增加幾個 jQueryMobile 要用到的 attributes 就變成一句奇怪的 syntax. 中間的 id 和 sid 東西原本是 parameters, 在這裡雖然沒有用到, 因為要加上最後的 attributes, 就算沒有用, 也要寫上, 否則就是 syntax error 了. 那幾個 attributes 也有問題的, 因為 MVC 不接受 “-“, Microsoft 就取巧, 叫你用 “_” 他幫你生成 “-“, 攪成三不像!

第二行是沒有 Html.ActionLink, 衹採用了 Url.Content 來取得 root 的路徑. 清楚易明.
這個 Url.Content 也是找了一會才找到的, 以前是用 ResolveUrl, 在 Razor 中居然又要改了!

Synchronize 兩台 IIS7

使用了兩種不同的方法去 synchronize 兩台 IIS7,記錄下來供日後參考。

  1. 用 WebDeploy + Robocopy
  2. 用 Appcmd + Robocopy (這個辦法比較好)

WebDeploy + Robocopy

首先在 source 啟動 WebDepSv:


net start webdepsv

然後在 destination 使用以下的 command 續一把 website 從 source sync 至 destination:
Continue reading “Synchronize 兩台 IIS7”

利用 PowerShell 自動 Restore 數據庫

也是三部曲,首先是準備 PowerShell 的 restore script,接著是利用一個 batch file (.BAT) 啟動這個 script 檔案,最後就是在 Task Scheduler 創建一個 task 按時執行這個 batch file 就完成了。
PowerShell script file 稱為 SqlRestore.ps1,內容如下:

#============================================================
# Restore a Database using PowerShell and SQL Server SMO
# Restore to the same database, overwrite existing db
# Donabel Santos
# 2010.10.16 paulus: modified
#============================================================

#clear screen
cls

#load assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
#Need SmoExtended for backup
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

#get backup file
#you can also use PowerShell to query the last backup file based on the timestamp
#I'll save that enhancement for later
$backupFile = "C:MSSQLBackup" + $args[0] + ".bak"

#we will query the db name from the backup file later

$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
$backupDevice = New-Object ("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($backupFile, "File")
$smoRestore = new-object("Microsoft.SqlServer.Management.Smo.Restore")

#settings for restore
$smoRestore.NoRecovery = $false;
$smoRestore.Partial = $false
$smoRestore.ReplaceDatabase = $true;
$smoRestore.Action = "Database"

#show every 10% progress
$smoRestore.PercentCompleteNotification = 10;

$smoRestore.Devices.Add($backupDevice)

#read db name from the backup file's backup header
$smoRestoreDetails = $smoRestore.ReadBackupHeader($server)

#display database name
"Database Name from Backup Header : " + $smoRestoreDetails.Rows[0]["DatabaseName"]

$smoRestore.Database = $smoRestoreDetails.Rows[0]["DatabaseName"]

#restore
$smoRestore.SqlRestore($server)

#2010.10.16 paulus: set owner to sa
$db = New-Object Microsoft.SqlServer.Management.Smo.Database
$db = $server.Databases.Item($smoRestoreDetails.Rows[0]["DatabaseName"])
$db.SetOwner("sa", $TRUE)

"Done"

 

batch file 稱為 RestoreDb.bat,內容如下:

powershell -command "& {C:MSSQLSqlRestore.ps1 Club.Secretary}"

powershell -command "& {C:MSSQLSqlRestore.ps1 Club.Secretary.RTIA}"

batch file 比較簡單,再來就是設立 Task Scheduler。如果 Task Scheduler 啟動的時間比 Backup 的時間早,就可以做成有兩天的備份了。

配合之前講的 Backup script 便建立了一個 SQL Server 的 mirrror server, 用作 disaster backup, 雖然不是 synchronized,難得是免費的,效果也算不壞吧?

利用 PowerShell 做 SQL 數據庫備份

分成三個部份,首先是準備 PowerShell 的 backup script,接著是利用一個 batch file (.BAT) 啟動這個 script 檔案,最後就是在 Task Scheduler 創建一個 task 按時執行這個 batch file 就完成了。

PowerShell script file 稱為 SqlBackup.ps1,內容如下:

#============================================================
# Backup a Database using PowerShell and SQL Server SMO
# Script below creates a full backup
# Donabel Santos
# 2010.10.16 paulus:modified
#============================================================

#specify database to backup
#ideally this will be an argument you pass in when you run
#this script, but let's simplify for now
$dbToBackup = $args[0]

#clear screen
cls

#load assemblies
#note need to load SqlServer.SmoExtended to use SMO backup in SQL Server 2008
#otherwise may get this error
#Cannot find type [Microsoft.SqlServer.Management.Smo.Backup]: make sure
#the assembly containing this type is loaded.

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
#Need SmoExtended for smo.backup
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

#create a new server object
$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
$backupDirectory = $server.Settings.BackupDirectory

#2010.10.16 paulus: display default backup directory
"Default Backup Directory: " + $backupDirectory

#display current backup database
"Current database: " + $dbToBackup

$db = $server.Databases[$dbToBackup]
$dbName = $db.Name

$timestamp = Get-Date -format yyyyMMddHHmmss
$smoBackup = New-Object ("Microsoft.SqlServer.Management.Smo.Backup")

#BackupActionType specifies the type of backup.
#Options are Database, Files, Log
#This belongs in Microsoft.SqlServer.SmoExtended assembly

$smoBackup.Action = "Database"
$smoBackup.BackupSetDescription = "Full Backup of " + $dbName
$smoBackup.BackupSetName = $dbName + " Backup"
$smoBackup.Database = $dbName
$smoBackup.MediaDescription = "Disk"
#2010.10.16 paulus: overwrite
$smoBackup.Initialize = $TRUE
#2010.10.16 paulus: no need for timestamp
#$smoBackup.Devices.AddDevice($backupDirectory + "" + $dbName + "_" + $timestamp + ".bak", "File")
$smoBackup.Devices.AddDevice($backupDirectory + "" + $dbName + ".bak", "File")
$smoBackup.SqlBackup($server)

#let's confirm, let's list list all backup files
$directory = Get-ChildItem $backupDirectory

#list only files that end in .bak, assuming this is your convention for all backup files
$backupFilesList = $directory | where {$_.extension -eq ".bak"}
$backupFilesList | Format-Table Name, LastWriteTime

batch file 稱為 BackupDb.bat,內容如下:

del C:MSSQLBackup*.* /F /Q
powershell -command "& {C:MSSQLSqlBackup.ps1 Club.Secretary}"
powershell -command "& {C:MSSQLSqlBackup.ps1 Club.Secretary.RTIA}"
robocopy C:MSSQLBackup \151-SQL2K8C$MSSQLBackup /Z /W:5 /MIR

第一行,把檔案夾內的舊 backup files 刪除。
第二行,啟動 Powershell script 備份數據庫 Club.Secretary。
第三行,再用 PowerShell script 備份數據庫 Club.Secretary.RTIA。
如此安排是容許選擇性地 backup SQL Server 內的 databases.
第四行,用 RoboCopy 把剛才備份的檔案抄至指定的 computer 151-SQL2K8 去,RoboCopy 用了一個 /MIR 意思是 Mirror, 確保 151-SQL2K8 收到的檔案跟本機完全相同,不多也不少。

最後的設定 Task Scheduler 就不用講了吧?