ثبت اطلاعات Web Form به صورت خودکار

دوشنبه 7 تیر 1395

در این مقاله به شما آموزش داده خواهدشد که چگونه اطلاعات را در local storage ذخیره کنید و این اطلاعات ذخیره شده ی محلی را با استفاده از Ajax به پایگاه داده منتقل کنید.

ثبت اطلاعات Web Form به صورت خودکار

 در این مقاله نحوه ذخیره سازی اطلاعات ورودی کاربر زمانی که در حال واردکردن اطلاعات است توضیح داده میشود که برای فرم های طولانی بسیار مناسب است. این امر موجب میشود که ، اگر کاربر دکمه "ذخیره اطلاعات" را انتخاب نکرده باشد یا مرورگر دچار مشکل شود، اطلاعات از دست نرود. این تکنیک برای احراز هویت کاربران هم مورد استفاده قرار میگیرد برای مثال با استفاده از این تکنیک، کاربری که در سایت احراز هویت شده و وارد سایت شود و نمیتواند دوباره با همان هویت قبلی وارد سایت شود(حتی اگر از سیستم دیگری برای ورود به سایت اقدام کند). این قابلیت تا حدودی مشابه   ASP.NET 2.0 profiling می باشد.

ایده ای که برای طراحی این قابلیت، ارائه شد بدین صورت بود که ابتدا اطلاعات کاربر به صورت موقت به یک web server فرستاده و در آنجا ذخیره شود و بعد از آن به database منتقل شود و به صورت دائم در آنجا ذخیره شود.

JavaScript بر اطلاعات ورودی کاربر در مرورگر نظارت دارد و آنها را در داخل یک hash table  ذخیره میکند. در مدت زمان های مشخصی، این hash table ، به صورت یک query string سریال گذاری میشود وبا استفاده از شی از جنسXmlHttp   به یک صفحه ASPX (AutoSave.aspx) فرستاده میشود. AutoSave.aspx در یک memory object با مقادیری از query string قرار دارد. بعد از مدتی مشخص، مقادیر موردنظر به database انتقال پیدا میکند.

مراحل عملی:

1. هنگامیکه  کاربر اطلاعات را وارد یک فرم میکند. رویدادOnBlur  موجود در تمام کنترل­های ورودی را به یک hash table  ، متصل کنید.

2. اطلاعات کاربر را با استفاده از فراخوانی تابع AutoSave() به سرور بفرستید.

AutoSave.3 را قبل از اینکه مرورگر توسط کاربر بسته شود، فراخوانی کنید. برای مثال میتوانید مادر اینجا  برای اینکار از رویداد window.onbeforeunload استفاده کرده ایم.

//WebForm1.aspx

<script defer="defer" language="javascript">

    bindEvents(); //binds onblur events,  onchange for DropDown Lists 


    var xmlHttp; 
    xmlHttp = GetXmlHttpObject(CallbackMethod); 
                    
    function AutoSave()
    { 
        if (!Data.isEmpty()) {
            qstring = Data.toQueryString();
            SendXmlHttpRequest(xmlHttp, "AutoSave.aspx?" + 
                               qstring.substring(0,qstring.length-1)); 
            Data.clear();
        }
    } 
        
    function CallbackMethod() 
    { 
        try
        {
            //readyState of 4 or 'complete' represents 

            if (xmlHttp.readyState == 4 || xmlHttp.readyState == 'complete')
            {
                var response = xmlHttp.responseText; 
                if (response.length > 0)
                {
                    alert("Unable to Auto Save Data. Please " + 
                          "check your internet connectivity");
                } 
            }
        }
        catch(e){}
    }
            
    window.setInterval(AutoSave, 15000);
    window.onbeforeunload = AutoSave;
</script >

 

4. پیاده سازی  hash table در JavaScript

//WebForm1.aspx

<script defer="defer" language="javascript">

/*Bind event with Controls */

    function bindEvents(){
        var textBoxes = document.getElementsByTagName("input");
        for (i=0; i< textBoxes.length; i++){
            if (textBoxes[i].type == 'text' || textBoxes[i].type == 'radio'){
                textBoxes[i].onblur = updateHashTable;
            }
        }
        for (i=0; i< textBoxes.length; i++){
            if (textBoxes[i].type == 'checkbox'){
                textBoxes[i].onblur = updateHashTableforCheckBox;
            }
        }
    
        var comboBoxes = document.getElementsByTagName("select");
        for (j=0; j< comboBoxes.length; j++){
            comboBoxes[j].onchange = updateHashTableforCombo;
        }
    }

    var Data= new Hashtable();

    function updateHashTable(){
    Data.put(this.id, this.value);
    }
    function updateHashTableforCheckBox(){
    Data.put(this.id, this.checked);
    }
    function updateHashTableforCombo(){
        Data.put(this.id, this.options(this.selectedIndex).value);
    }
</script>

 

5. در ابتدا بررسی میکنیم که DTO در حال حاضر وجود دارد یا خیر. برای مثال ما کاربری داریم که اطلاعات مربوط به آن هنوز از بین نرفته است و یکsession  برای آن موجود است . ما آنرا به یک DTO که در حافظه موجود است متصل میکنیم. در غیر اینصورت، یک شی جدید درCache   ایجاد میکنیم تا اطلاعات کاربر را در آن نگه داری کنیم. Cache   به جای Session مورد استفاده قرار میگیرد و دلیل آن ادامه ی حیات آن در کنار sessions/logins کاربر می باشد و همچنین با استفاده ازCash میتوانیم از متد callback برای شبیه سازی رویداد Session_End نیز استفاده کنیم. متد CacheExpired زمانی فراخوانی میشود که زمان اجرای cache به پایان رسیده باشد و اطلاعات وارد database شده باشد.

//WebForm1.aspx.cs

private void Page_Load(object sender, System.EventArgs e){

    if (!Page.IsPostBack){
                
    UserData userData;
    if (Cache[Context.User.Identity.Name] == null){
        userData = new UserData();
        Cache.Insert(Context.User.Identity.Name, userData ,null, 
           Cache.NoAbsoluteExpiration, 
           TimeSpan.FromMinutes(Session.Timeout), 
           CacheItemPriority.Default, new  CacheItemRemovedCallback(CacheExpired));
    }
    else{
        userData = Cache[Context.User.Identity.Name] as UserData;
    }

    FillPage(userData); //to populate web form controls with values from DTO

}

internal void CacheExpired(string key, object val, CacheItemRemovedReason reason) {
    if (reason != CacheItemRemovedReason.Removed){
    //Save.aspx invokes userData.updateDB() to update data in database
        HttpContext.Current.Server.Execute("Save.aspx", new StringWriter());
    }
}

 

6. در صفحه AutoSave.aspx ، دوباره به سراغ مقادیر query string میرویم و propertyهای مربوط به DTO را تنظیم میکنیم سپس شی DTO در حافظه را بروز رسانی میکنیم.

//AutoSave.aspx.cs

private void Page_Load(object sender, System.EventArgs e)
{
    UserData userData = Cache[Context.User.Identity.Name] as UserData;
    for(int i=0; i < Request.QueryString.Count; i++){
        try{
            userData[Request.QueryString.GetKey(i)] = Request.QueryString.Get(i);
        }
        catch (Exception ex){
            continue;
        }
    }
        Cache[Context.User.Identity.Name] = userData;
    
}

7.یک DTO (Data Transfer Object) برای نگه داری اطلاعات در حافظه تعریف شده است. یک string indexer (نمایه ساز رشته) برای تعیین کردن مقادیر مربوط به propertyهای کلاس از query string پیاده سازی شده است.

8. متد updateDB() برای انتقال اطلاعات از حافظه به database ایجاد شده است. updateDB() تنها زمانی فراخوانی میشود که کاربر فرم را submit کرده باشد یا زمان کش DTO تموم شده باشد.

//DTO.cs

public class UserData {
    public string this[string paramName]{// string indexer

        get {
            return this.GetType().GetProperty(paramName).GetValue(
                                  this, null).ToString();
        }
        set{
            this.GetType().GetProperty(paramName).SetValue(this,value,null);
        }
    }

    private string _LastName;
    public string LastName {
        get { return _LastName; }
        set { _LastName = value; }
    }

    private string _FirstName;
    public string FirstName {
        get { return _FirstName; }
        set { _FirstName = value; }
    }
        
    private string _Email;
    public string Email {
        get { return _Email; }
        set { _Email = value; }
    }
        
    public void updateDB() {
        
        /***here: invoke Stored Procedure to update data in database***/
        HttpContext.Current.Cache.Remove(HttpContext.Current.User.Identity.Name);
    }

محدودیت­ها­:

1.این روش برای صفحات وبی که به صورت خودکار در سمت client با استفاده از  نرم افزارهای خاصی پر میشوند کار نخواهد کرد.

2.اگر فیلدهای ورودی کاربر در درون کنترل هایی (ASCX) تعریف شده باشد که در مکان­های متفاوتی مورد استفاده قرار میگیرند، ممکن است نیاز باشد در این روش تغییراتی ایجاد شود، که به آن نگاشت (mapping) بین مقادیر اطلاعات و propertyهای DTO می گویند.

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید