繁体   English   中英

ASP C#如何编写简洁的GUI代码

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

看看这篇文章你如何测试你的Request.QueryString []变量?

尝试在单独的函数中捕获重复代码。 (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不要滚动您自己的身份验证:使用表单身份验证,除非您有令人信服的理由不这样做。 使用表单身份验证时,您无需在每个页面上编写代码来检查您是否已登录。框架会为您处理。


2 学习使用服务器控件

另外,正如其他人写的那样,你不应该在代码中编写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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM