ASP C # Как программировать аккуратный код GUI - PullRequest
2 голосов
/ 06 апреля 2009

В течение нескольких месяцев я программирую на ASP C #. Я всегда программирую много кода в событиях, и в событии загрузки я проверяю строку запроса на достоверность данных. Вот пример кода, который у меня есть в одном из моих проектов:

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, у меня есть похожий код. Я думаю, что это код спагетти и не очень хорошо организован. Так можете ли вы сказать мне, как я могу организовать свой код?

EDIT:

Что я хочу знать, есть ли более аккуратный способ, скажем, заполнить список? И где я могу проверить, имеет ли значение строки запроса действительные данные? Где я могу проверить, являются ли данные (input / querystring) числом? И где вы должны поместить код, который проверяет строку запроса? Также в событии загрузки?

Ответы [ 5 ]

4 голосов
/ 06 апреля 2009

Я чувствую вашу боль из-за некоторых проблем организации с сайтами ASP.NET. У меня был код похожий на ваш в нескольких проектах.

Если у вас есть выбор ваших фреймворков, вы можете заглянуть в ASP.NET MVC. Это позволяет вам четко разделить представление (HTML), контроллеры (все действия и бизнес-логика) и модель (база данных). Таким образом, у вас будет нулевой код в ваших файлах за кодом, все это будет хорошо и аккуратно в контроллерах.

3 голосов
/ 06 апреля 2009

Попробуйте использовать 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 []?

2 голосов
/ 15 апреля 2009

С чего начать. К сожалению, несмотря на другие комментарии, вы на самом деле не пишете что-то специфичное для веб-форм. Так что переход на MVC волшебным образом не сделает ваш код лучше.


1 Не используйте собственную аутентификацию: используйте аутентификацию с помощью форм , если у вас нет веских причин не делать этого. При использовании проверки подлинности с помощью форм вам не нужно писать код на каждой странице, чтобы проверить, что вы вошли в систему. Фреймворк сделает это за вас.


2 Научитесь использовать серверные элементы управления :

Также, как пишут другие, вы не должны писать html в коде, особенно для чего-то такого тривиального. Веб-формы также не заставляют вас делать это.

  <!-- 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;

Если вы собираетесь придерживаться веб-форм, вам необходимо ознакомиться с жизненным циклом ASP.Net Page


3 Ваш код нуждается в рефакторинге. Неважно, веб-формы, 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; 
}
2 голосов
/ 06 апреля 2009

Попробуйте захватить повторяющийся код в отдельной функции. (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;
}
1 голос
/ 06 апреля 2009

вы должны следовать многоуровневому подходу. То есть: поместите весь свой код доступа к данным в слой доступа к данным, поместите всю свою бизнес-логику (включая проверки) в свой бизнес-уровень, поместите весь код своей модели в уровень своего бизнес-объекта

и, наконец, для пользовательского интерфейса - старайтесь никогда не генерировать html-разметку из кода, насколько это возможно. Кроме того, всегда создавайте корневой класс для ваших ASPX-страниц, где уже реализованы общие методы. затем подкласс этого корневого класса для всех остальных страниц ASPX

если вы собираетесь жестко закодировать html-разметку в вашем коде c # - могу вас заверить, это всегда приведет к большому хаосу (основываясь на моем собственном опыте)

но бывают ситуации, когда вы просто не можете этого избежать. в таких случаях - это то, что я делаю - я избавляюсь от кода и просто помещаю этот код в сам файл aspx / ascx. таким образом, когда мне нужно изменить свой пользовательский интерфейс, основываясь на бесконечных клиентских запросах, мне не нужно перекомпилировать мой код - я просто заменяю свои файлы aspx / ascx на промежуточном / производственном сервере.

Вы знаете, каковы клиенты: хммм, вы можете сделать черную полосу похожей на серую, можете ли вы увеличить расстояние между строками, можете ли вы изменить текст этой гиперссылки ... запросы, подобные этим, никогда не заканчиваются: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...