简体   繁体   English

在 ASP.NET web 页面中存储数据的最佳实践

[英]Best Practice for storing data in an ASP.NET web page

I have a multi-user set of ASP.NET web pages.我有一组多用户 ASP.NET web 页面。 The pages use AJAX update panels so I can avoid updating the screen on every postback.这些页面使用 AJAX 更新面板,因此我可以避免在每次回发时更新屏幕。 The lifecycle of each page is as follows:每个页面的生命周期如下:
1. During Page_Load, get relevant data for user from a web service. 1. 在Page_Load期间,从web服务中获取用户的相关数据。
2. Store the data (quite large), and a service reference in a static dataset. 2. 将数据(相当大)和服务引用存储在 static 数据集中。
3. allow various edits to parts of the data via the screen controls (grids, text boxes) 3. 允许通过屏幕控制(网格、文本框)对部分数据进行各种编辑
4. validate data captured via form 4. 验证通过表单捕获的数据
5. send updated data back to service 5. 将更新的数据发送回服务

I am doing this using static variables in the Page class itself as follows:我正在使用页面 class 本身中的 static 变量执行此操作,如下所示:

public partial class MyPage : System.Web.UI.Page
{
    static xxxx.DataCaptureServiceClient  m_Service; //reference to web service
    static string m_PersonID = string.Empty;  //current person_id page is viewing
    static ServResponse m_ServiceResult = null;        // reference to our data to edit ( ServResponse is a large data contract)   
    static string m_SortExpression = "Reference"; //default sort expression for grid

    const int PERSONID_COLUMN = 0;        //column index in grid for the personID column
    const int STATUS_COLUMN = 4;          //column index in grid for the application status

    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            if (!Page.IsPostBack)
            {
                // Get new service instance.
                m_Service = new xxxx.DataCaptureServiceClient();

                ShowDataOnPage(); //get data in m_ServiceResult and bind to a grid on screen
            }
        }
        catch (Exception ex)
        {
            Response.Redirect("ErrorPage.aspx", false);
        }
    }

    protected void butNext_Click(object sender, EventArgs e)
    {
        try
        {
            Page.Validate();

            if (Page.IsValid)
            {
                // Use m_ServiceResult and m_Service to send a packaged submission to the service.
                SendDatatoService();
                Response.Redirect("TheNextPage.aspx", false);

            }
        }
        catch (Exception ex)
        {
           Response.Redirect("ErrorPage.aspx", false);
        }
}

//Other methods which allow edits to m_ServiceResult

I am wondering if:我想知道是否:

A) This is a good way to implement or are there better practices? A)这是一个很好的实施方式还是有更好的做法?
B) Should I clear down memory by setting all statics to NULL when I redirect to another page? B)当我重定向到另一个页面时,我是否应该通过将所有静态设置为 NULL 来清除 memory?
C) If I clear down the statics do I risk another user losing data? C) 如果我清除静态数据,我是否会冒另一个用户丢失数据的风险?

UPDATE更新

I have rewritten removing the statics, keeping the const values and passing data I need around as parameters.我重写了删除静态变量,保留常量值并将我需要的数据作为参数传递。 Where I need to keep data for updates I have kept the minimal amount I need in session[] variables.在我需要保留更新数据的地方,我在 session[] 变量中保留了我需要的最少数量。

A) No - what happens if a 2nd user opens a page while another one is busy? A) 否 - 如果第二个用户在另一个用户忙时打开一个页面会发生什么? The static dataset will be overwritten with the 2nd user's data, or is your static dataset somehow differentiating different users' data at the same time? static 数据集将被第二个用户的数据覆盖,或者您的 static 数据集是否以某种方式同时区分不同用户的数据?

B) If you absolutely must use statics / server side data, then yes, you should clear them somehow. B)如果您绝对必须使用静态/服务器端数据,那么是的,您应该以某种方式清除它们。 Guaranteeing that this happens is difficult however.然而,要保证这种情况发生是很困难的。 (Eg if one user just closes their browser) (例如,如果一个用户只是关闭了他们的浏览器)

C) Possibly, but if this is a concern then my question in A) is already going to cause greater problems for you. C)可能,但如果这是一个问题,那么我在 A)中的问题已经会给你带来更大的问题。

As a general answer, storing large amounts of data in memory on the server is generally bad practice.作为一般答案,在服务器上的 memory 中存储大量数据通常是不好的做法。 It does not scale well, and opens you up for many different types of errors.它不能很好地扩展,并为您打开许多不同类型的错误。 Your back-end should be stateless, and there are a number of ways you could achieve that, for example storing the records in a separate table in the DB, which only get finalised (and thus moved into the "real" tables) at the end of the several screens you have.您的后端应该是无状态的,并且有多种方法可以实现这一点,例如将记录存储在数据库中的单独表中,该表仅在结束您拥有的几个屏幕。

In direct answer to your questions, without opening a can of worms直接回答您的问题,无需打开一罐蠕虫

A) There is pretty much no worse way to implement data capture A) 实现数据捕获几乎没有比这更糟糕的方法了
B) Setting variables to null in .NET does not clear down memory. B) 在 .NET 中将变量设置为 null不会清除 memory。
C) Yes, yes you do. C) 是的,是的。 By definition every user is sharing the same static data.根据定义,每个用户都共享相同的 static 数据。

I would keep your service delcarations local, and only use global variables for the constants.我会将您的服务声明保留在本地,并且仅将全局变量用于常量。 You're not saving much by declaring them globally.通过在全球范围内声明它们并没有节省太多。 Also, I would use a const string instead of a static string.另外,我会使用 const 字符串而不是 static 字符串。

I think the others have answered your questions.我想其他人已经回答了你的问题。 My suggestion to help fix your code would be to do some of the following:我帮助修复代码的建议是执行以下一些操作:

  1. m_PersonID should not be static - keep it an instance property/field of the page and have it as static. m_PersonID不应为 static - 将其保留为页面的实例属性/字段并将其作为 static。 In fact, class-level variables in code behind can lend itself to fairly unreadable code very quickly.事实上,代码背后的类级变量可以很快地变成相当不可读的代码。 Does it really need to be class-level, or can it be defined in the method where you need it (and just, perhaps, passed as an argument to other methods)?它真的需要是类级别的,还是可以在您需要它的方法中定义(并且可能只是作为参数传递给其他方法)?
  2. m_ServiceResult - same for this. m_ServiceResult - 与此相同。 Not sure why you have it, and it doesn't need to be static.不知道你为什么拥有它,它不需要是 static。 Try to move it to a method-level variable.尝试将其移至方法级变量。
  3. m_SortExpression could just be a const m_SortExpression可能只是一个常量
  4. m_Service - again, I don't see the need for this to be a static. m_Service - 再一次,我不认为它需要成为 static。 If it's just a proxy to a service, I don't think you need to keep it in memory to avoid unnecessary overhead.如果它只是服务的代理,我认为您不需要将其保存在 memory 以避免不必要的开销。 I think they problems keeping it static far outweigh the small overhead of having the service client be a method-level variable.我认为他们保留它的问题 static 远远超过让服务客户端成为方法级变量的小开销。
  5. In regards to the static dataset, you may want to consider caching the large result set, if the data is fairly static for the user.关于 static 数据集,如果数据对用户来说相当 static,您可能需要考虑缓存大型结果集。 Or, really take a look at what you're returning and evaluate if you really need all that data.或者,真正看看您返回的内容并评估您是否真的需要所有这些数据。 If you're performing calculations in the code-behind, that's probably not the best place for it.如果您在代码隐藏中执行计算,那可能不是最好的地方。 Consider your service layer as the place for those calculations (or the db if you have a lot of your logic in stored procs - not saying that's the place for it, but just acknowledging that it's a possibility).将您的服务层视为进行这些计算的地方(如果您在存储过程中有很多逻辑,则将其视为数据库 - 并不是说这是它的地方,而只是承认这是一种可能性)。
  6. Also, a dataset is pretty large and bulky.此外,数据集非常庞大且庞大。 Do you need this structure, or is a set of streamlined entity objects more appropriate?你需要这种结构,还是一组精简的实体对象更合适? This item pretty much goes with #5, since you really should evaluate how you're retrieving data, storing it and acting upon it.这个项目与#5 差不多,因为你真的应该评估你是如何检索数据、存储数据并对其采取行动的。 A dataset may be the quick and dirty answer, but usually it's not the efficient answer.数据集可能是快速而肮脏的答案,但通常不是有效的答案。

In short, dump the statics and move to private, method-level variables where possible.简而言之,尽可能转储静态变量并转移到私有的方法级变量。 Try to reduce the amount of data you have coming back from the database.尝试减少从数据库返回的数据量。 Consider methods that take parameters instead of using class-level and/or global variables.考虑采用参数而不是使用类级别和/或全局变量的方法。

I hope this helps.我希望这有帮助。 Good luck!祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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