ASP.Net C# - 将代码从代码隐藏移动到类文件

发布于 2024-09-10 10:01:18 字数 1265 浏览 4 评论 0原文

一段时间以来,我试图弄清楚如何重构我的一些代码以减少整个应用程序的冗余。我刚刚学习 OOP 的基础知识,可以创建简单的类和方法,但我的知识在实际适用性方面有限。以下代码段说明了我的挫败感:

#region DELETE selected users - button

protected void btnDeleteSelected_Click(object sender, EventArgs e)
{
    try
    {
        foreach (GridViewRow row in GridView1.Rows)
        {
            CheckBox cb = (CheckBox)row.FindControl("chkRows");
            if (cb != null && cb.Checked)
            {
                // get the row index values (DataKeyNames) and assign them to variable
                string userName = GridView1.DataKeys[row.RowIndex].Value.ToString();

                // delete selected users and their profiles
                ProfileManager.DeleteProfile(userName);
                Membership.DeleteUser(userName);

                Msg.Text = "User(s) were sucessfully <b>DELETED</b>!";
                Msg.Visible = true;
            }
        }
    }
    catch (Exception ex)
    {
        Msg.Text = "Oops! " + ex.Message;
        Msg.Visible = true;
    }
    finally
    {
        // refresh gridview to reflect changes
        GridView1.DataBind();
    }
}

#endregion

这段代码在我的项目的页面代码隐藏文件中的几个页面上使用。我怎样才能将其移动到类文件中。我不知道如何在类中引用像 gridview 这样的对象,因为它不像实际页面上那样存在。

有人可以帮忙吗?谢谢。

For some time now I am trying to figure out how I can refactor some of my code to reduce redundancy throughout my application. I am just learning the basics of OOP and can create simple classes and methods but my knowledge is limited in terms of practical applicability. The following bit of code illustrates my frustration:

#region DELETE selected users - button

protected void btnDeleteSelected_Click(object sender, EventArgs e)
{
    try
    {
        foreach (GridViewRow row in GridView1.Rows)
        {
            CheckBox cb = (CheckBox)row.FindControl("chkRows");
            if (cb != null && cb.Checked)
            {
                // get the row index values (DataKeyNames) and assign them to variable
                string userName = GridView1.DataKeys[row.RowIndex].Value.ToString();

                // delete selected users and their profiles
                ProfileManager.DeleteProfile(userName);
                Membership.DeleteUser(userName);

                Msg.Text = "User(s) were sucessfully <b>DELETED</b>!";
                Msg.Visible = true;
            }
        }
    }
    catch (Exception ex)
    {
        Msg.Text = "Oops! " + ex.Message;
        Msg.Visible = true;
    }
    finally
    {
        // refresh gridview to reflect changes
        GridView1.DataBind();
    }
}

#endregion

This bit of code is used on several pages of my project in the pages codebehind file. How can I move this to a class file. I don't know how to reference an object like a gridview in a class because it does not exist like it does on the actual page.

Could some one help out please? Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

明天过后 2024-09-17 10:01:18

在尝试重构代码时通常会应用许多原则。目前,您正在尝试重构代码,以免违反 DRY 原则 ( DRY = 不要重复)。重构该代码将是一个伟大的举措。

但是,您可能需要考虑其他一些原则。 单一责任原则表明每种方法只做一件明确的事情。考虑一下您当前的方法执行的操作。它从 GridView 中提取用户名,然后删除与该用户关联的一些数据。两种方法可能会更好。

另外,松散耦合代码也很好。您不希望类之间存在大量依赖关系。例如,如果您将整个方法按原样移至单独的类或库,则该类或库将依赖于 ASP.NET 库,因为它对 GridView 进行了特定引用。控制。但它不需要。您可以使用一种单独的方法从 GridView 中提取用户名(此方法与 ASP.NET 紧密结合),然后使用一种单独的方法来执行其余操作(例如删除用户的数据),只需要用户名。第二种方法不会以任何方式耦合到 ASP.NET。因此,通过使用各自具有单一职责的单独方法,您将获得更松散耦合的代码。二合一。

至于你在这里所说的:

我不知道如何引用
类中类似 gridview 的对象
因为它并不像它那样存在
在实际页面上。

当您调用提取用户名的方法时,您只想传递对 GridView 的引用。像这样的事情:

public static class Util
{
    public static IEnumerable<string> GetUsernames(GridView gv)
    {
        List<string> userNames = new List<string>();
        foreach (GridViewRow row in gv.Rows)
        {
            CheckBox cb = (CheckBox)row.FindControl("chkRows");
            if (cb != null && cb.Checked)
            {
                // get the row index values (DataKeyNames) and assign them to variable
                string userName = gv.DataKeys[row.RowIndex].Value.ToString();
                userNames.Add(userName);
            }
        }
        return userNames;
    }
}

现在,在任何 ASP.NET 页面后面的代码中,您可以执行以下操作:

IEnumerable<string> usernames = Util.GetUsernames(GridView1);
foreach(string username in usernames)
    doSomething(username);

doSomething(username) 将调用其他执行删除操作的方法,或者执行任何您想要的操作。想。

希望这有帮助。

哦,如果你只是学习 OOP 的基础知识,我会推荐类似 Head第一本面向对象的分析和设计,或任何似乎充分涵盖该主题的书。我喜欢 O'Reilly Head First 系列。这些信息非常容易消化。

There are many principles that you generally apply when trying to refactor code. Currently, you're trying to refactor your code as to not violoate the DRY principle (DRY = don't repeat yourself). It would be a great move to refactor that code.

But, some other principals might come in to play that you might want to consider. The single responsibility principle would suggest that each method does only one unambiguous thing. Think about the operations your current method does. It extracts the usernames from the GridView, and then deletes some data associated with that user. That might be better off as two methods.

Also, loosely coupled code is good. You don't want a bunch of dependencies between your classes. For example, if you moved your whole method, as is, to a separate class or library, that class or library would be dependent on the ASP.NET libraries, because it makes a specific reference to the GridView control. But it doesn't need to. You could have a separate method that pulls the username out of the GridView (this method would be tightly coupled with ASP.NET), and then a separate one that does the rest of your actions (such as deleting the user's data), which only requires the username. That second method would not be coupled to ASP.NET in any way. So by having separate methods that each have a single responsibility, you'll have more loosely coupled code. Two for one.

As for what you said here:

I don't know how to reference an
object like a gridview in a class
because it does not exist like it does
on the actual page.

You'd just want to pass a reference to your GridView when you call the method that would extract the usernames. Something like this:

public static class Util
{
    public static IEnumerable<string> GetUsernames(GridView gv)
    {
        List<string> userNames = new List<string>();
        foreach (GridViewRow row in gv.Rows)
        {
            CheckBox cb = (CheckBox)row.FindControl("chkRows");
            if (cb != null && cb.Checked)
            {
                // get the row index values (DataKeyNames) and assign them to variable
                string userName = gv.DataKeys[row.RowIndex].Value.ToString();
                userNames.Add(userName);
            }
        }
        return userNames;
    }
}

Now, in any of your asp.net code behind pages, you can do:

IEnumerable<string> usernames = Util.GetUsernames(GridView1);
foreach(string username in usernames)
    doSomething(username);

The doSomething(username) would be a call to some other method that does your delete operations, or whatever you want.

Hope this helps.

Oh, and if you're just learning the basics of OOP, I would recommend something like Head First Object-Oriented Analysis and Design, or any book that seems to adequately cover the subject. I like the O'Reilly Head First series. The information is very digestible.

—━☆沉默づ 2024-09-17 10:01:18

在 Webforms 应用程序中,从后台代码中分解出应用程序和/或业务逻辑的常用技术是使用 MVP 模式。这并不意味着通常在代码隐藏中找到的所有代码都会被移动到另一个类,因为这实际上与代码隐藏没有任何不同。 UI 呈现逻辑(例如数据绑定设置、访问 UI 控件等)最好留给代码隐藏,但业务逻辑(在本例中为删除用户)由 Presenter 中的方法执行。

在您的例子中,我将构建一个用户名集合,并在 Presenter 上调用 RemoveUsers() 方法,传入用户名列表,这将处理与 ProfileManager 和 Membership 组件的接口(最好通过抽象)。这允许您为 Presenter 中的逻辑编写单元测试。

In Webforms applications, a common technique for factoring out application and/or business logic out of the code behind is to use the MVP pattern. This doesn't mean all the code typically found in the code-behind just gets moved to another class, as this really isn't any different than a code-behind. The UI rendering logic (e.g. Databinding setup, access to UI controls, etc.) is best left to the code-behind, but the business logic (in this case, the removal of users) is performed by a method within the Presenter.

In your case, I would build up a collection of usernames and call a RemoveUsers() method on the Presenter, passing in the list of usernames, which would handle interfacing with the ProfileManager and Membership components(ideally through abstractions). This allows you to write unit tests for the logic within the Presenter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文