[英]ASP C# How to program neat GUI code
大約幾個月我正在編寫ASP C#。 我總是在事件中編寫很多代碼,在load事件中我檢查查詢字符串是否有效數據。 這是我在其中一個項目中的一些示例代碼:
protected void Page_Load(object sender, EventArgs e)
{
if (Controller.Manual == null)
{
Response.Redirect("login.aspx");
}
lblLocation.Text = "<a href='viewdocument.aspx'>" + Controller.Manual.Title + "</a>";
if (Request.QueryString["gchap"] != null)
{
if (Controller.IsNumeric(Request.QueryString["gchap"].ToString()))
{
genchap = Convert.ToInt32(Request.QueryString["gchap"]);
FillGeneralList();
SetChapterTitle();
}
}
if (Request.QueryString["qchap"] != null)
{
if (Controller.IsNumeric(Request.QueryString["qchap"].ToString()))
{
qualchap = Convert.ToInt32(Request.QueryString["qchap"]);
FillQualityList();
SetChapterTitle();
}
}
// Check document Id is set (did)
if (Request.QueryString["did"] != null)
{
if (Controller.IsNumeric(Request.QueryString["did"].ToString()))
{
docId = Convert.ToInt32(Request.QueryString["did"]);
DetermineView();
}
}
}
我知道必須有一種方法可以更簡潔的方式實現這一目標。 這只是加載事件。 在其他事件上,例如click和onchange事件,我有類似的代碼。 我認為這是意大利面條代碼並沒有很好的安排。 所以你能告訴我如何安排我的代碼嗎?
編輯:
我想知道的是,是否有更簡潔的方法,比方說,填寫一個列表框? 我在哪里檢查查詢字符串值是否有有效數據? 我在哪里檢查(輸入/查詢字符串)數據是否是數字? 你應該在哪里放置驗證Querystring的代碼? 還在加載事件中?
我對ASP.NET網站的一些組織問題感到痛苦。 我在幾個項目上都有類似的代碼。
如果您可以選擇框架,那么您可以查看ASP.NET MVC。 這使您可以在View(Html),控制器(所有操作和業務邏輯)和Model(數據庫)之間進行清晰的分離。 這樣你的代碼隱藏文件就沒有代碼了,它在控制器中保持良好和整潔。
嘗試使用TryParse( 例如 ),您可以簡化所有看起來像的代碼
xx.IsNumeric(Request.QueryString["qchap"].ToString())
和
Convert.ToInt32(Request.QueryString["gchap"]);
並減少對Request.QueryString
變量的調用次數
你可以試試像
原始代碼
if (Request.QueryString["gchap"] != null)
{
if (Controller.IsNumeric(Request.QueryString["gchap"].ToString()))
{
gchap = Convert.ToInt32(Request.QueryString["gchap"]);
FillGeneralList();
SetChapterTitle();
}
}
建議
int? gchap; //nullable types thanks Richard :D
if (!int.TryParse(Request.QueryString["gchap"], out id)) {gchap = null};
if (gchap != null) {
FillGeneralList();
SetChapterTitle();
}
// you could make this neater with your own little method
嘗試在單獨的函數中捕獲重復代碼。 (qchap / gchap)
例如:
qualchap = ConvertFillAndSet(Request.Querystring["qchap"]);
genchap = ConvertFillAndSet(Request.QueryString["gchap"]);
private int ConvertFillAndSet(string qrystring)
{
int numberToReturn = 0;
//if the conversion was ok -> true, else false
if (Int32.TryParse(qrystring,numberToReturn))
{
FillQualityList();
SetChapterTitle();
}
//returns 0 if tryparse didn't work
return numberToReturn;
}
從哪兒開始。 不幸的是,盡管有其他評論,但你並沒有真正寫出任何特定的“網絡表單”。 所以轉向MVC並不會讓你的代碼變得更好。
1不要滾動您自己的身份驗證:使用表單身份驗證,除非您有令人信服的理由不這樣做。 使用表單身份驗證時,您無需在每個頁面上編寫代碼來檢查您是否已登錄。框架會為您處理。
另外,正如其他人寫的那樣,你不應該在代碼中編寫html,特別是對於那些微不足道的東西。 Web表單也不會讓您這樣做。
<!-- this is in MyPage.aspx -->
<asp:HyperLink id="viewLink" runat="server" />
// in the code-behind file MyPage.aspx.cs
viewLink.NavigateUrl = "~/viewdocument.aspx";
viewLink.Text = Controller.Title;
如果您要堅持使用Web表單,則需要熟悉ASP.Net頁面生命周期
3您的代碼需要重構。 無論是Web表單,php還是MVC。 這里有一些基本的重構,而這些都不是.net特定的。 我將逐步完成這些步驟。
// this may be a good candidate for an extension method
int? ConvertNullable(string nullableInt) {
if( string.IsNullOrEmpty(nullableInt) )
return null;
int value;
if( Int32.TryParse(nullableInt, out value) )
return value;
return null;
}
然后允許你寫。
int genchap? = ConvertNullable(Request.QueryString["gchap"]);
int qualchap? = ConvertNullable(Request.QueryString["qualchap"]);
int docId? = ConvertNullable(Request.QueryString["did"]);
FillQualityList(genchap,qualchap);
SetChapterTitle(genchap,qualchap);
DetermineView(docId);
但傳遞大量原語是一件麻煩事,容易出錯,所以有時我們會創建一個小類來封裝數據,在這種情況下是頁面初始化信息。
class ChapterView
{
public int? GenChapter {get; set;}
public int? QualChapter {get; set;}
public int? DocumentId {get; set;}
}
private ChapterView GetChapterView()
{
return new ChapterView
{
GenChapter = ConvertNullable(Request.QueryString["gchap"]),
QualChapter = ConvertNullable(Request.QueryString["qualchap"]),
DocumentId = ConvertNullable(Request.QueryString["did"])
}
}
請注意,我不知道GenChap和QualChap是什么,但它們有點簡潔,你可以完成重構,使它們在代碼中更具可讀性。 但即使沒有更好的名字,我們現在擁有更多可讀代碼。
ChapterView chapterView = GetChapterView();
FillQualityList(chapterView);
SetChapterTitle(chapterView);
DetermineView(chapterView);
最后,您可以確定每次頁面執行時都不需要調用它來從查詢字符串中讀取。 如果您已經閱讀了Asp.Net Page LifeCycle,您就會知道事件可能會更改GenChapter
或其他影響頁面呈現方式的內容。 您可能會發現在PreRender中設置視圖而不是一遍又一遍地調用FillQualityList會更好。
ChapterView chapterView;
Page_Load()
{
if( !IsPostback )
{
ChapterView chapterView = GetChapterView();
}
else
{
chapterView = (ChapterView) ViewState["chapterview"];
}
}
NextChapter_Click()
{
chaperView.NextChapter();
}
Page_PreRender()
{
FillQualityList(chapterView);
SetChapterTitle(chapterView);
DetermineView(chapterView);}
// make sure class is marked [Serializable]
ViewState["chapterview"] = chapterView;
}
你應該遵循分層方法。 即:將所有數據訪問代碼放入數據訪問層,將所有業務邏輯(也包括驗證)放在業務層中,將所有模型代碼放入業務對象層
最后為ui - 盡量不要在代碼中生成html標記。 此外,始終為您的aspx頁面創建一個根類,其中已經實現了常用方法。 然后為每個其他aspx頁面子類化這個根類
如果你要在你的c#代碼中硬編碼html標記 - 我可以向你保證這會導致很多混亂(基於我自己的經驗)
但有些情況下你根本無法避免它。 對於這種情況 - 這就是我所做的 - 我擺脫了背后的代碼,只是把代碼放在我的aspx / ascx文件本身。 這種方式當我必須根據永不停止的客戶端請求更改我的UI時,我不必重新編譯我的代碼 - 我只需在登台/生產服務器上替換我的aspx / ascx文件。
你知道客戶是怎么回事:嗯,你可以讓黑條看起來有點像灰色,你可以增加線之間的間距,你可以改變這個超鏈接的文本......像這樣的請求似乎永遠不會結束:-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.