[英]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.