站源碼解析:WebForm三層架構部署與二次開發(fā)實戰(zhàn))
簡介這份源碼包是面向C#/ASP.NET WebForm學習者的計算機教學網(wǎng)站完整實現(xiàn)采用經(jīng)典三層架構表現(xiàn)層、業(yè)務邏輯層、數(shù)據(jù)訪問層完整覆蓋視頻上傳瀏覽、文件上傳下載、在線答疑、信息展示、分權限管理、用戶組等核心模塊內置CKEditor文本編輯器適合計算機專業(yè)課程設計、畢業(yè)設計以及教學平臺二次開發(fā)參考。包內共860個文件除150個cs業(yè)務代碼、57個aspx頁面、135個js腳本、21個css樣式外還包含gif/png圖片素材、doc幫助文檔及配置文件等整體結構完整配套SQL2008數(shù)據(jù)庫與VS2010工程壓縮包僅3.8MB目錄劃分清晰便于閱讀和調試。目前已有48人下載學習。通過該源碼可以深入理解WebForm前端交互、基于角色的權限控制、文件與視頻上傳管理、SQL Server數(shù)據(jù)操作等關鍵技術其三層分層與模塊化寫法也為學習企業(yè)級項目組織方式提供了良好范例。1. 拿到一套C#教學網(wǎng)站源碼我第一反應不是雙擊sln先翻目錄再找數(shù)據(jù)庫文件,最后才打開VS2010的工程。這套C#計算機教學網(wǎng)站源碼用的是VS2010 SQL2008 WebForm 三層架構功能集中在視頻上傳瀏覽、文件上傳下載、在線答疑、信息展示和用戶組分權限管理。它給的并不是一個花哨的演示頁面而是一套能掛課程、能傳資料、能按角色管理后臺的完整站點骨架拿到手少則半天、多則兩三天能跑起來改。適合兩類人一類是學校要做課程設計或實訓項目、但不想從零寫注冊登錄的學生另一類是想看WebForm真實工程里頁面、用戶控件、數(shù)據(jù)訪問層如何配合的入門從業(yè)者。這套源碼說明里寫得很直白不帶技術支持但附有幫助文檔所以后面部署得自己來我下面按實際拆項目順序把結構、部署、改法一次講透。2. 先摸清這套C#源碼的三層骨架從WebForm頁面到數(shù)據(jù)庫訪問WebForm項目里說的三層通常拆成表現(xiàn)層aspx頁面、業(yè)務層類庫里的Service類和數(shù)據(jù)訪問層操作SQL的類。這套源碼把它組織得比較規(guī)矩頁面文件散落在根目錄或子目錄數(shù)據(jù)訪問通過公共類統(tǒng)一封裝頁面里不直接寫SQL而是調用方法拿DataTable或實體集合。下面這個表是資源里抽出的一組關鍵頁面實際運行時它們串起了一個教學網(wǎng)站的主干。文件名頁面職責主要面向角色Index.aspx首頁聚合展示推薦課程、最新文件游客/注冊用戶ListFile.aspx教學文件列表按分類或時間篩選游客/注冊用戶ListVedio.aspx視頻課程列表入口進播放頁游客/注冊用戶ListArticle.aspx文章、公告、資訊展示游客ListInstructor.aspx講師/教師列表展示師資信息游客ListUser.aspx用戶列表管理通常走后臺權限管理員MyFile.aspx我的文件個人上傳記錄管理注冊用戶MyVedio.aspx我的視頻個人視頻管理注冊用戶left.aspx左側導航用戶控件全站共用config.ascx全局配置控件其他aspx頁面引用頁面命名是典型的WebForm風格List開頭是列表頁My開頭是個人中心。不需要文檔這一串文件名已經(jīng)把站點結構說清楚了大半。下面分三節(jié)把骨架拆開。2.1 頁面層入口列表頁、詳情頁、個人中心如何串起來先看入口。Index.aspx會調用數(shù)據(jù)訪問層抓最新的視頻和文件然后綁定到Repeater或DataList上前臺用戶點「更多」跳到ListVedio.aspx或ListFile.aspx列表頁根據(jù)QueryString里的分類ID過濾數(shù)據(jù)點標題進詳情頁詳情頁瀏覽量加一并把同分類的內容列在下方。這套邏輯在WebForm里是標準動作幾乎每個教學類站點都這么寫。從源碼角度看關鍵在列表頁的綁定代碼是否是三層寫法。我拆過不少自稱三層、實際把連接串和SQL全堆在aspx.cs里的項目這套源碼從文件組織上判斷是按標準三層走的。區(qū)分方法很簡單打開一個ListFile.aspx.cs看它是直接new SqlConnection還是調業(yè)務層方法。調方法說明數(shù)據(jù)訪問被收攏到了下層后續(xù)加功能、換數(shù)據(jù)庫都方便直接連庫則說明所謂三層只是分層目錄實際還是兩層的寫法。頁面之間的跳轉參數(shù)也值得注意。老WebForm項目常用Response.Redirect(ListVedio.aspx?categoryId dr[CategoryId])傳參接收方再用Request.QueryString[categoryId]讀出來。這種傳參方式在IIS下沒問題但如果站點部署到虛擬目錄或二級路徑硬編碼路徑就可能404這屬于后面避坑章節(jié)要說的典型問題。2.2 ascx用戶控件與config.ascxWebForm時代的高頻復用單元WebForm里沒有組件化這種說法它靠用戶控件.ascx解決復用。頭部、左側導航、底部版權、登錄框這些每個頁面都要出現(xiàn)的區(qū)塊會被抽成單獨的ascx文件哪個頁面需要就在aspx里注冊引用。這套源碼里的left.aspx就是這樣一個控件里面大概率是分類菜單和最近更新列表config.ascx則是全局配置控件存站點名稱、上傳根目錄、是否開放注冊這類參數(shù)供其他頁面統(tǒng)一讀取改動一處全站生效。在aspx頁面里引用一個ascx固定寫法是先在頂部注冊% Register Src~/config.ascx TagPrefixuc TagNameSiteConfig %然后在頁面主體需要的位置放控件標簽uc:SiteConfig IDucConfig runatserver /Src指向用戶控件文件TagPrefix和TagName是自定義的別名ID是頁面內實例名。注冊好后這個用戶控件的Page_Load事件會在頁面加載時執(zhí)行相當于把一段公共邏輯插進每個引用的頁面。config.ascx里一般會讀配置參數(shù)然后暴露成公共屬性給頁面調用常見做法是在控件里定義SiteName、UploadPath這類屬性外層頁面直接ucConfig.SiteName取值。這里有個容易忽略的點config.ascx如果寫在頁面里被引用它的初始化順序和aspx頁面事件順序是固定的Page_Load里要保證配置參數(shù)先讀完再給屬性賦值否則頁面取到的是空值。遇到這種情況把配置讀取放到Page_Init里即可老項目里踩這個坑的人不少。2.3 數(shù)據(jù)訪問層SQL2008下的連接串與參數(shù)化查詢數(shù)據(jù)訪問層在三層里是離數(shù)據(jù)庫最近的一層。這套源碼的數(shù)據(jù)庫是SQL2008連接字符串通常放在Web.config的connectionStrings節(jié)點里。頁面代碼不直接寫連接串而是通過ConfigurationManager.ConnectionStrings[SqlServer]取出來這是標準做法好處是換庫、換密碼不用滿項目找字符串。典型的數(shù)據(jù)訪問層方法長這樣我在這類教學站里幾乎每次都看到同款寫法public DataTable GetFileList(string categoryId) { string connStr ConfigurationManager.ConnectionStrings[SqlServer].ConnectionString; string sql SELECT * FROM tb_File WHERE CategoryId CategoryId ORDER BY AddTime DESC; using (SqlConnection conn new SqlConnection(connStr)) using (SqlCommand cmd new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue(CategoryId, categoryId); SqlDataAdapter adapter new SqlDataAdapter(cmd); DataTable dt new DataTable(); adapter.Fill(dt); return dt; } }這段代碼有幾點值得細看using保證連接和命令用完自動釋放避免連接池被占滿AddWithValue把categoryId當作參數(shù)傳入而不是字符串拼接從根上擋掉SQL注入SqlDataAdapter.Fill(dt)把結果填充到內存里的DataTable頁面層拿到后直接綁定到Repeater。這套組合在WebForm時代是數(shù)據(jù)訪問層的標準流水線。參數(shù)化的好處不用多講但有一個細節(jié)AddWithValue在SQL2008的舊寫法里可能存在類型推斷問題比如傳入字符串1而數(shù)據(jù)庫列是intSOCKET有時能隱式轉換有時會報轉換失敗。穩(wěn)妥做法是明確指定SqlDbTypecmd.Parameters.Add(CategoryId, SqlDbType.Int).Value int.Parse(categoryId);如果后面自己加查詢條件凡是數(shù)值型、日期型參數(shù)都建議這么寫能少踩一半的坑。數(shù)據(jù)庫訪問層摸清楚后下面進入正題怎么把整套源碼在今天的環(huán)境里跑起來。3. 把環(huán)境跑起來VS2010項目在今天部署的完整步驟與連接串配置VS2010工程拿到2024年的機器上跑大概率會碰到框架不匹配、數(shù)據(jù)庫版本太高、IIS應用池設置不對這幾個坎。別急著裝虛擬機先把下面步驟走完多數(shù)問題能直接解決。3.1 打開老解決方案sln版本與目標框架的處理VS2010生成的sln文件是# Visual Studio 2010版本號開頭VS2015以上打開時會自動做一次升級轉換一般能直接打開。WebForm項目升級后目標框架默認可能還是.NET Framework 4.0建議在項目屬性里把它改到4.5或4.8——老機器上沒有4.0運行時新系統(tǒng)卻自帶4.8改了框架反而更穩(wěn)。如果打開后報「無法讀取項目文件」或「此項目需要VS2010」先看sln頭部Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010Format Version 11.00對應VS2010高版本VS能打開但會提示升級如果提示無法加載多半是項目文件里指定了特定工具版本。把csproj文件里的ToolsVersion4.0/ToolsVersion改成15.0或Current重新加載即可。還有一點WebForm項目的bin目錄里往往帶著一堆舊的DLL升級后建議清掉bin重新生成一次避免舊DLL和新編譯器打架。我一般會在項目目錄點右鍵「清理解決方案」再「重新生成解決方案」這一步能解決一半的詭異報錯。3.2 數(shù)據(jù)庫還原SQL2008備份文件在高版本SQL Server上的還原源碼數(shù)據(jù)庫如果是bak備份文件在SQL Server 2012以上還原時需要注意版本向下兼容的坑高版本可以還原低版本備份但還原后數(shù)據(jù)庫兼容級別還是2008100某些新語法不能直接用查詢不報錯但性能不是最優(yōu)。還原語句在外圍工具里執(zhí)行即可RESTORE DATABASE [TeachSite] FROM DISK ND:\db\TeachSite.bak WITH MOVE NTeachSite_Data TO ND:\Data\TeachSite.mdf, MOVE NTeachSite_Log TO ND:\Data\TeachSite_log.ldf, REPLACE, RECOVERYMOVE兩行指定數(shù)據(jù)文件和日志文件落到本機的實際路徑路徑必須提前存在REPLACE覆蓋同名數(shù)據(jù)庫適合反復還原RECOVERY讓數(shù)據(jù)庫處于可讀寫狀態(tài)。如果備份文件名和邏輯名對不上先執(zhí)行RESTORE FILELISTONLY FROM DISK ND:\db\TeachSite.bak查一下邏輯名再MOVE。如果拿到的是mdf數(shù)據(jù)文件而非bak用附加的方式CREATE DATABASE [TeachSite] ON (FILENAME ND:\Data\TeachSite.mdf) FOR ATTACH;附加后若報版本沖突說明mdf是從高版本SQL Server分離出來的舊版SQL裝不上解決辦法是裝一個同版本或更高版本的SQL Server不要在2008上死磕。3.3 改連接串與config.ascx讓站點連上本機數(shù)據(jù)庫數(shù)據(jù)庫還原后在VS里打開Web.config找到connectionStrings節(jié)點改成本機實例connectionStrings add nameSqlServer connectionStringData Source.;Initial CatalogTeachSite;User Idsa;Password你的密碼; providerNameSystem.Data.SqlClient / /connectionStringsData Source.代表本機默認實例如果是命名實例寫成localhost\SQLEXPRESS指定端口則寫localhost,1433。這里有個常見誤區(qū)2008時代很多人寫Data Source127.0.0.1不加端口在新機器SQL Server默認實例監(jiān)聽動態(tài)端口時可能連不上優(yōu)先用.或localhost。config.ascx如果實現(xiàn)的是讀配置參數(shù)它內部多半會訪問ConfigurationManager上面連接串改好后這個控件讀到的就是新庫參數(shù)。改完先單步調試config.ascx的Page_Load看能否正常讀表讀表報錯八成是連接串問題能讀到但頁面報空值則看屬性賦值順序按2.2節(jié)提到的Page_Init處理。跑通后別急著高興還要處理IIS應用池。WebForm老項目依賴Session和ViewState建議把應用池托管管道模式設為經(jīng)典Classic集成模式Integrated下部分老控件會出奇怪問題。部署時如果發(fā)現(xiàn)回發(fā)(ViewState)報錯先切經(jīng)典模式再試。4. 核心功能代碼邏輯視頻上傳、文件上傳下載、在線答疑的數(shù)據(jù)流這個網(wǎng)站掛的核心功能本質是三條數(shù)據(jù)流文件/視頻從本地上傳到服務器、存儲記錄入數(shù)據(jù)庫用戶下載文件走權限校驗答疑內容用富文本編輯后寫庫再展示。下面按模塊拆開講清楚了。4.1 視頻上傳與瀏覽文件存盤路徑入庫還是二進制入庫視頻這種大文件教學網(wǎng)站幾乎沒有往數(shù)據(jù)庫里塞二進制的寫法原因很實在視頻動輒幾十MB到幾百MB數(shù)據(jù)庫體積會迅速膨脹備份、查詢、流媒體播放全都變慢IIS處理二進制大對象時內存占用也會失控。常見的做法是文件系統(tǒng)存文件數(shù)據(jù)庫只存一個相對路徑字符串播放時拼URL。我看過這套源碼的文件列表MyVedio.aspx對應個人視頻管理上傳邏輯十有八九是下面這套寫法string uploadDir Server.MapPath(~/Upload/Vedio/ DateTime.Now.ToString(yyyyMMdd)); if (!Directory.Exists(uploadDir)) { Directory.CreateDirectory(uploadDir); } string ext Path.GetExtension(fileUpload1.FileName).ToLower(); if (ext ! .mp4 ext ! .flv ext ! .wmv) { // 不合法格式直接拒絕避免用戶上傳可執(zhí)行文件 return; } string newName Guid.NewGuid().ToString() ext; fileUpload1.SaveAs(Path.Combine(uploadDir, newName));三個關鍵點按日期建子目錄避免單目錄文件數(shù)量爆炸白名單校驗擴展名防止上傳aspx、exe這類危險文件文件名用GUID重命名避免中文名和重名導致路徑亂碼或覆蓋。保存成功后把/Upload/Vedio/日期/Guid.mp4這樣的虛擬路徑存進數(shù)據(jù)庫列表頁綁定時直接拼到a href或video src上。瀏覽端如果是老項目可能用Flash播放器或video標簽。若源碼里還是.flv播放方案今天的主流瀏覽器已經(jīng)不支持Flash后面6.3節(jié)會講怎么平滑替換成HTML5的video。4.2 文件下載的權限校驗從Session判斷到Response輸出文件教學網(wǎng)站的文件下載是權限敏感點源碼里既然有用戶組和管理員概念下載頁必然有一層身份校驗。整個流程一般是三連先判斷是否登錄再判斷用戶組等級是否滿足最后才Response輸出文件。典型實現(xiàn)protected void Page_Load(object sender, EventArgs e) { if (Session[UserId] null) { Response.Redirect(~/Login.aspx?backUrlMyFile.aspx); return; } int groupLevel Convert.ToInt32(Session[UserGroupLevel]); if (groupLevel 2) // 假設2為可下載等級 { Response.Write(當前用戶組無下載權限); Response.End(); return; } string fileName Request.QueryString[file]; string fullPath Server.MapPath(~/Upload/Files/ fileName); if (!File.Exists(fullPath)) { Response.Write(文件不存在或已被刪除); return; } FileInfo fi new FileInfo(fullPath); Response.Clear(); Response.ContentType application/octet-stream; Response.AddHeader(Content-Disposition, attachment; filename HttpUtility.UrlEncode(fi.Name)); Response.WriteFile(fullPath); Response.End(); }這段邏輯里最容易翻車的不是權限是文件名輸出中文文件名如果不做HttpUtility.UrlEncode下載時會亂碼或直接被瀏覽器攔截。另一個坑是Request.QueryString[file]直接拼進路徑用戶手動改URL就可以穿目錄讀取其他文件。穩(wěn)妥做法是在數(shù)據(jù)庫里放一個只有GUID的文件名頁面用文件ID查庫得到存儲名而不是把真實文件名暴露在URL參數(shù)里。文件上傳端則是把瀏覽器選的文件用FileUpload.SaveAs存盤擴展名白名單和大小限制和視頻上傳一致。區(qū)別在于文件資料往往還要記錄上傳人、所屬課程、是否公開這些元數(shù)據(jù)在上傳完成后寫一張tb_File表列表頁按權限只顯示當前用戶能看的那一批。4.3 在線答疑與信息展示CKEditor的集成位置與內容安全在線答疑模塊在WebForm里通常是一張發(fā)帖/回帖結構用戶用富文本編輯器寫內容保存進數(shù)據(jù)庫的tb_Question或tb_Answer表列表頁讀取后按發(fā)布時間倒序渲染。編輯器用的是CKEditor集成方式是在頁面放一個textarea再用JS把它替換成編輯器實例script typetext/javascript src/ckeditor/ckeditor.js/script textarea idtxtContent runatserver cols80 rows10 stylevisibility:hidden;/textarea script typetext/javascript CKEDITOR.replace(txtContent, { language: zh-cn, toolbar: Basic }); /scriptCKEDITOR.replace的第一個參數(shù)是textarea的ID第二個參數(shù)是配置對象。lang設為zh-cn出中文界面toolbar選Basic只留基本排版按鈕答疑場景夠用。頁面提交時服務端直接取txtContent.Text拿到用戶輸入的HTML存庫前要不要處理是個關鍵分叉答疑內容存HTML可以讓帖子排版原樣保留但如果把這段HTML直接Response.Write回頁面用戶就能往頁面里注入腳本。這是WebForm時代最典型的安全漏洞。常見做法是答疑帖子這類“內部用戶互相信任”的場景入庫前過濾掉script、iframe、onclick等事件屬性過濾后允許保留p、img、a課程介紹這類后臺編輯的內容則完全信任后臺管理員不清洗直接存。過濾用正則或System.Web.Security.AntiXSS庫都能做但要注意img srcx onerroralert(1)這種寫法過濾onerror這類事件屬性比過濾標簽本身更關鍵。5. 老WebForm項目避坑從VS2010到新系統(tǒng)的五道坎這套源碼底子是2010年的環(huán)境今天部署必然會撞上幾類兼容問題。下面五條是我在同類WebForm站點上反復見過、也踩過的坑按現(xiàn)象→原因→解決寫碰到直接對號入座。5.1 現(xiàn)象運行時報「未能加載文件或程序集 Microsoft.CSharp」現(xiàn)象頁面一跑起來就拋異常程序集加載失敗指向Microsoft.CSharp但項目明明沒有直接用它。原因WebForm項目目標框架是.NET Framework 4.0而代碼某處比如視圖里dynamic類型或某些第三方控件在編譯期依賴了Microsoft.CSharp新機器上默認高版本框架環(huán)境下web.config缺少對低版本程序集重定向的聲明。解決先把項目目標框架升到4.5以上再檢查web.config的compilation targetFramework4.5是否和項目設置一致。如果必須保持4.0就在web.config里給system.web配置節(jié)添加compilation并顯式引用程序集常見的做法是把assemblies里補上Microsoft.CSharp。實際項目里我通常直接升框架十分鐘內能試出來比折騰低版本兼容快得多。5.2 現(xiàn)象連數(shù)據(jù)庫報「在與 SQL Server 建立連接時出現(xiàn)與網(wǎng)絡相關的或特定于實例的錯誤」現(xiàn)象站點能起但任何讀數(shù)據(jù)庫的頁面都報連接失敗錯誤里帶網(wǎng)絡相關字樣。原因連接串指向的實例名或端口在新機器上對不上。2008時代默認實例127.0.0.1裸奔直連很常見新裝SQL Server默認用命名實例或動態(tài)端口舊連接串當然連不上。解決按3.3節(jié)的寫法先確認SQL Server服務名再改連接串。驗證連接串對不對可以在命令行用sqlcmd -S . -U sa -P 密碼跑一條SELECT 1能跑通再回頭改站點。還不行就檢查SQL Server的TCP/IP協(xié)議是否啟用SQL Server配置管理器→協(xié)議→TCP/IP→啟用不動這個光改連接串也一樣白搭。5.3 現(xiàn)象CKEditor圖片上傳報錯返回腳本而不是圖片路徑現(xiàn)象答疑發(fā)帖的編輯器能打字但點圖片上傳按鈕要么彈出腳本錯誤要么上傳后圖片不顯示404。原因CKEditor在WebForm里只是個前端編輯器真正收圖片的是配套的上傳處理器一般是upload.aspx或upload.ashx。老工程把處理器路徑寫死在ckeditor的config里比如/ckeditor/upload.aspx站點一旦被部署到虛擬目錄或非根路徑這個硬編碼路徑就直接404。解決把腳本引用改成%ResolveUrl(~/ckeditor/ckeditor.js)%同時把上傳處理器的配置項改成相對路徑或動態(tài)計算CKEDITOR.replace(txtContent, { filebrowserUploadUrl: %ResolveUrl(~/ckeditor/upload.aspx)% });上傳處理器本身還是個安全隱患檢查一下它是否校驗了文件擴展名至少要把aspx、asp、exe擋掉否則編輯器的上傳功能等于給站點開了一個文件上傳后門。5.4 現(xiàn)象部署到二級目錄后頁面跳轉404但首頁能開現(xiàn)象在虛擬目錄下部署成功首頁正常點菜單或登錄跳轉全部404直接輸http://ip/子目錄/Login.aspx又能打開。原因老項目里的鏈接大量寫成絕對根路徑/Login.aspx、/ListVedio.aspx沒有考慮虛擬目錄前綴。瀏覽器請求時把/Login.aspx解析到站點根而不是虛擬目錄下自然404。解決全局搜索href/、action/、Redirect(/把所有硬編碼路徑替換為ResolveUrl(~/xxx.aspx)或Page.ResolveClientUrl(~/xxx.aspx)。如果不想動全站鏈接直接把站點發(fā)布到IIS根目錄綁定80端口的主站點避免二級目錄這個前提條件也是一勞永逸的路子。5.5 現(xiàn)象Session隔一會兒就丟登錄狀態(tài)頻繁跳回登錄頁現(xiàn)象登錄后能用過十幾分鐘或第二天再訪問Session變空得重新登錄。有時并發(fā)訪問還會出現(xiàn)兩個人串Session的情況。原因IIS應用池默認每隔一段時間回收進程回收時InProc模式的SessionState被一并清空。老項目web.config里往往沒寫sessionState節(jié)點默認就是InProc等于Session全存在IIS工作進程內存里進程一回收全沒了。解決把Session狀態(tài)從進程內改到進程外SQLServer模式是WebForm時代最穩(wěn)定的方案。先在SQL Server里執(zhí)行aspnet_regsql.exe -S . -U sa -P 密碼 -ssadd再改web.configsystem.web sessionState modeSQLServer sqlConnectionStringData Source.;Integrated SecurityTrue cookielessfalse timeout60 / /system.web如果不想裝ASP.NET狀態(tài)服務或建Session庫退一步也可以在IIS應用池的高級設置里把「固定時間間隔」回收改為0不自動回收配合把Idle Time-out設成0Session能撐住不丟但并發(fā)量大時性能有瓶頸。教學站訪問量不高這兩條夠用。6. 二次開發(fā)要讓這套教學網(wǎng)站真正能用先動這三處站點跑通只是開始真正要改成自己能交付的教學網(wǎng)站我建議按下面三個方向動手。6.1 換門面改左側導航、首頁欄目和講師展示left.aspx是全局左側導航先把里面的硬編碼菜單改成后臺可配置的或者簡單替換成自己的菜單文字即可。首頁的欄目名、橫幅、公告文字全部集中在Index.aspx和config.ascx里批量替換文字后再改一下樣式。講師列表ListInstructor.aspx大概率從tb_Instructor表讀數(shù)據(jù)直接用SQL把假數(shù)據(jù)改成真實師資就行不需要動代碼結構。6.2 給視頻加課程分組加字段并改造列表頁原結構如果是「視頻一張表平鋪」時間長了列表會很難翻。最常見的二次開發(fā)是給視頻表加一個CourseId外鍵ALTER TABLE tb_Vedio ADD CourseId INT NULL;然后建一張tb_Course表再在ListVedio.aspx的查詢SQL里加WHERE CourseIdCourseId導航菜單上掛課程列表點擊時帶上courseId參數(shù)即可。響應式前端層面給視頻列表的縮略圖加一層遮罩顯示時長用CSS十分鐘能搞定比改后端邏輯直觀得多。6.3 視頻播放把Flash方案替換成HTML5 video老站點的視頻播放十有八九依賴Flash今天瀏覽器已經(jīng)全面禁用Flash所以播放頁是必須改的一處。最省事的做法是直接用HTML5video標簽前提是源文件轉成H.264編碼的MP4video idplayer controls preloadmetadata stylewidth:100% src%ResolveUrl(~/Upload/Vedio/ videoPath)% 您的瀏覽器不支持HTML5視頻播放 /videocontrols顯示播放控件preloadmetadata只加載視頻元信息打開頁面不會一下子把整個視頻拖進瀏覽器。如果源文件還是FLV或AVI用格式工廠或FFmpeg轉成MP4再入庫一次轉完不再折騰。我是從接觸這套源碼之后才養(yǎng)成習慣每次接手老WebForm項目第一件事就先列三張清單——入口頁跑一遍、用戶控件掃一遍、連接串驗一遍把這三處理順后面的坑基本都平坦了。這套源碼也一樣按這兩章順序走一遍你就能把一個2010年的教學站骨架變成一個今天還能正常招生宣傳、正常傳課傳題的可用站點。希望幫到你。本文還有配套的精品資源點擊獲取