κατάσταση παρακολούθησης χρησιμοποιώντας ASP.NET AJAX / ICallbackEventHandler




Έχω ένα πρόβλημα με τη διατήρηση της κατάστασης σε μια σελίδα ASP.NET AJAX. Σύντομη έκδοση: Χρειάζομαι κάποιο τρόπο να ενημερώσετε το ViewState σελίδα μετά από μια επανάκλησης ασύγχρονη έχει γίνει, ώστε να αντικατοπτρίζει οποιαδήποτε κατάσταση αλλάζει το διακομιστή έκανε κατά τη διάρκεια της κλήσης ασύγχρονη.


Αυτό φαίνεται να είναι ένα κοινό πρόβλημα, αλλά θα περιγράψω το σενάριο μου για να εξηγήσει:


Έχω ένα πλέγμα που μοιάζει με τον έλεγχο που έχει κάποιες βελτιώσεις JavaScript - δηλαδή, η δυνατότητα να drag and drop στήλες και γραμμές. Όταν μια στήλη ή σειρά ρίπτεται σε μια νέα θέση, γίνεται επίκληση μία μέθοδος AJAX να κοινοποιήσει την πλευρά του διακομιστή ελέγχου φωτιάς και ένα αντίστοιχο server-side event ( «OnColumnMoved» ή «OnRowMoved»).


ASP.NET AJAX κλήσεις, εξ ορισμού, να στείλετε ολόκληρη τη σελίδα ως αίτημα. Με αυτόν τον τρόπο η σελίδα περνά μέσα από μια πλήρη κύκλο ζωής, viewstate είναι συνεχίστηκε και η κατάσταση του ελέγχου αποκατασταθεί πριν από την επίκληση της μεθόδου RaiseCallbackEvent.


Ωστόσο, δεδομένου ότι η κλήση AJAX δεν ενημερώνει τη σελίδα, το ViewState αντικατοπτρίζει την *αρχική* κατάσταση του ελέγχου, ακόμη και μετά τη στήλη ή γραμμή έχει μετακινηθεί. Έτσι, η δεύτερη φορά που συμβαίνει ένα client-side δράση, η αίτηση AJAX πηγαίνει στο διακομιστή και η σελίδα και ελέγχου είναι χτισμένα πίσω πάλι να αντανακλούν την *πρώτη* κατάσταση του ελέγχου, όχι το κράτος μετά την πρώτη στήλη ή γραμμή κινήθηκε.


Αυτό το πρόβλημα εκτείνεται σε πολλές επιπτώσεις. Για παράδειγμα, αν έχουμε ένα client-side / AJAX δράση για να προσθέσετε ένα νέο στοιχείο με το δίκτυο, και στη συνέχεια μια σειρά σέρνεται, το δίκτυο είναι ενσωματωμένο server-side με ένα λιγότερο στοιχείο από ό, τι στην πλευρά του πελάτη.


Και, τέλος, και πιο σοβαρά για συγκεκριμένο παράδειγμα μου, το πραγματικό αντικείμενο προέλευσης δεδομένων που ενεργούν κατόπιν αποθηκεύεται στη σελίδα ViewState. Αυτή ήταν η απόφαση του σχεδιασμού για να επιτρέψει τη διατήρηση ενός stateful αντίγραφο της χειραγωγείται δεδομένα τα οποία μπορούν είτε να δεσμευτεί για την DB μετά από πολλούς χειρισμούς ή να απορριφθεί αν ο χρήστης πλάτη έξω. Αυτό είναι πολύ δύσκολο να αλλάξει.


Έτσι, και πάλι, χρειάζομαι έναν τρόπο για το ViewState σελίδα να ενημερωθεί για επανάκληση μετά την μέθοδο AJAX ψήνεται.
Αν είστε ήδη ανακάτεμα της ViewState γύρω ούτως ή άλλως, ίσως και να χρησιμοποιήσετε ένα UpdatePanel. Μερική postbacks της **θα** ενημερώσει ViewState της σελίδας αυτόματα.
<p>είχα το ίδιο πρόβλημα χρησιμοποιώντας asp.net mvc και <a href="http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/">βρήκα τη λύση εδώ</a> </p><blockquote> <p>υπάρχει μεγάλη σύγχυση μεταξύ των νεοεισερχομένων στο <strong> angularjs </strong> για το γιατί οι <code>$http</code> λειτουργίες στενογραφίας της υπηρεσίας (<code>$http.post()</code>, κλπ.) δεν φαίνονται να είναι εναλλάξιμες με το <strong> ισοδύναμα jquery </strong> (<code>jquery.post()</code>, κ.λπ.)</p> <p>η διαφορά είναι στον τρόπο <strong> jquery </strong> και <strong> angularjs </strong> σειριοποίηση και μετάδοση των δεδομένων. βασικά, το πρόβλημα έγκειται στη γλώσσα του server σας που δεν είναι σε θέση να καταλάβει τη μετάδοση του angularjs με εγγενή ... από προεπιλογή, <strong> jquery </strong> μεταδίδει δεδομένα χρησιμοποιώντας</p> <pre><code>content-type: x-www-form-urlencoded </code></pre> <p>και την εξοικειωμένη σειριοποίηση <code>foo=bar&amp;baz=moe</code>.</p> <p><strong> το angularjs </strong>, ωστόσο, μεταδίδει δεδομένα χρησιμοποιώντας</p> <pre><code>content-type: application/json </code></pre> <p>και <code>{ "foo": "bar", "baz": "moe" }</code></p> <p>η σειριοποίηση json, η οποία, δυστυχώς, μερικές γλώσσες διακομιστή web - <em> και συγκεκριμένα η php </em> - δεν απομακρύνονται εγγενώς.</p> </blockquote><p>δουλεύει άψογα.</p><p><b>κωδικας</b></p><pre><code>// your app's root module... angular.module('mymodule', [], function($httpprovider) { // use x-www-form-urlencoded content-type $httpprovider.defaults.headers.post['content-type'] = 'application/x-www-form-urlencoded;charset=utf-8'; /** * the workhorse; converts an object to x-www-form-urlencoded serialization. * @param {object} obj * @return {string} */ var param = function(obj) { var query = '', name, value, fullsubname, subname, subvalue, innerobj, i; for(name in obj) { value = obj[name]; if(value instanceof array) { for(i=0; i&lt;value.length; ++i) { subvalue = value[i]; fullsubname = name + '[' + i + ']'; innerobj = {}; innerobj[fullsubname] = subvalue; query += param(innerobj) + '&amp;'; } } else if(value instanceof object) { for(subname in value) { subvalue = value[subname]; fullsubname = name + '[' + subname + ']'; innerobj = {}; innerobj[fullsubname] = subvalue; query += param(innerobj) + '&amp;'; } } else if(value !== undefined &amp;&amp; value !== null) query += encodeuricomponent(name) + '=' + encodeuricomponent(value) + '&amp;'; } return query.length ? query.substr(0, query.length - 1) : query; }; // override $http service's default transformrequest $httpprovider.defaults.transformrequest = [function(data) { return angular.isobject(data) &amp;&amp; string(data) !== '[object file]' ? param(data) : data; }]; }); </code></pre> Κάνατε πολύ καλή δουλειά στο να συνοψίσετε τι είναι φοβερό στο Node.js. Η αίσθησή μου είναι ότι το Node.js είναι ιδιαίτερα κατάλληλο για εφαρμογές όπου θα θέλατε να διατηρήσετε μια μόνιμη σύνδεση από το πρόγραμμα περιήγησης πίσω στον διακομιστή. Χρησιμοποιώντας μια τεχνική γνωστή ως ["long-polling"](https://en.wikipedia.org/wiki/Push_technology#Long_polling), μπορείτε να γράψετε μια εφαρμογή που στέλνει ενημερώσεις στον χρήστη σε πραγματικό χρόνο. Η πραγματοποίηση long polling σε πολλούς από τους γίγαντες του διαδικτύου, όπως το [Ruby on Rails](https://en.wikipedia.org/wiki/Ruby_on_Rails) ή το [Django](https://en.wikipedia.org/wiki/Django_%28web_framework%29), θα δημιουργούσε τεράστιο φόρτο στον διακομιστή, επειδή κάθε ενεργός πελάτης τρώει μια διεργασία του διακομιστή. Αυτή η κατάσταση ισοδυναμεί με επίθεση [tarpit](https://en.wikipedia.org/wiki/Tarpit_(networking)). Όταν χρησιμοποιείτε κάτι όπως το Node.js, ο διακομιστής δεν έχει ανάγκη να διατηρεί ξεχωριστά νήματα για κάθε ανοιχτή σύνδεση. 


Αυτό σημαίνει ότι μπορείτε να δημιουργήσετε μια [εφαρμογή συνομιλίας με βάση το πρόγραμμα περιήγησης](https://github.com/rivalslayer/node_chat) σε Node.js που δεν χρειάζεται σχεδόν καθόλου πόρους συστήματος για να εξυπηρετεί πολλούς πελάτες. Κάθε φορά που θέλετε να κάνετε αυτού του είδους τη μακροχρόνια αναζήτηση, το Node.js είναι μια εξαιρετική επιλογή. 


Αξίζει να αναφέρουμε ότι και η Ruby και η Python έχουν εργαλεία για να κάνουν κάτι τέτοιο ([eventmachine](http://rubyeventmachine.com/) και [twisted](https://twistedmatrix.com/trac/), αντίστοιχα), αλλά ότι το Node.js το κάνει εξαιρετικά καλά, και από την αρχή. Η JavaScript είναι εξαιρετικά καλά τοποθετημένη σε ένα μοντέλο ταυτόχρονης λειτουργίας βασισμένο σε callback, και υπερέχει εδώ. Επίσης, η δυνατότητα σειριοποίησης και αποσειριοποίησης με JSON εγγενές τόσο στον πελάτη όσο και στον διακομιστή είναι αρκετά έξυπνη.


Ανυπομονώ να διαβάσω άλλες απαντήσεις εδώ, αυτή είναι μια φανταστική ερώτηση.


Αξίζει να επισημάνουμε ότι το Node.js είναι επίσης εξαιρετικό για καταστάσεις στις οποίες θα επαναχρησιμοποιήσετε πολύ κώδικα σε όλο το χάσμα πελάτη/εξυπηρετητή. Το [Meteor framework](https://meteor.com) το κάνει αυτό πολύ εύκολο, και πολλοί άνθρωποι προτείνουν ότι αυτό μπορεί να είναι το μέλλον της ανάπτυξης ιστοσελίδων. Μπορώ να πω από την εμπειρία μου ότι είναι πολύ διασκεδαστικό να γράφεις κώδικα στο Meteor, και ένα μεγάλο μέρος αυτού είναι να ξοδεύεις λιγότερο χρόνο σκεπτόμενος πώς θα αναδομήσεις τα δεδομένα σου, ώστε ο κώδικας που εκτελείται στο πρόγραμμα περιήγησης να μπορεί εύκολα να τα χειριστεί και να τα μεταβιβάσει πίσω.


Εδώ είναι ένα άρθρο για το Pyramid και το long-polling, το οποίο αποδεικνύεται ότι είναι πολύ εύκολο να ρυθμιστεί με λίγη βοήθεια από το gevent: [*TicTacToe και Long Polling με την Pyramid*](http://michael.merickel.org/2011/6/21/tictactoe-and-long-polling-with-pyramid/). <p>το <strong>server</strong> (που αποστέλλεται το αίτημα post) πρέπει να περιλαμβάνει την κεφαλίδα <code>access-control-allow-headers</code> (κλπ) <strong>στην απάντησή του</strong>. η τοποθέτησή τους στο αίτημά σας από τον πελάτη δεν έχει καμία επίδραση.</p><p>αυτό οφείλεται στο γεγονός ότι εναπόκειται στον διακομιστή να καθορίσει ότι δέχεται αιτήσεις διασταυρούμενης προέλευσης (και ότι επιτρέπει την κεφαλίδα <code>content-type</code> αίτησης και ούτω καθεξής) - ο πελάτης δεν μπορεί να αποφασίσει για τον εαυτό του ότι ένας δεδομένος διακομιστής πρέπει να επιτρέπει την cors.</p> to ότι έγινε σήμερα αναβάθμιση και παρουσιάστηκε το πρόβλημα δείχνει ότι μπορεί να σχετίζεται με το γεγονός αλλά μπορεί και να είναι και σύμπτωση. εγώ παρ’ όλ’ αυτά πιστεύω ότι έχει να κάνει με την σύνδεση σου, παρά το γεγονός ότι έχεις καλές ταχύτητες στον browser. θα δοκίμαζα ένα reset στο router … Οι άνθρωποι διακομιστής πήρε πίσω σε μένα. Θα αλλάξει το «ιστοσελίδα στο 4,0 Ολοκληρωμένη αγωγού λειτουργία.» και όλα τα έργα τώρα. Πηγαίνετε σχήμα.


Είμαι βέβαιος ότι είχα ελέγξει ότι ήταν σε κατάσταση Ολοκληρωμένη Pipeline, αλλά hey ho. βρήκα τη λύση. έχει δηλωθεί ως bug και υπάρχει προσωρινό workaround:

<https://bugs.archlinux.org/task/64175#comment182833> <p>το .net 4.0 επιτρέπει στα πρωτεύοντα σύνολα interop (ή μάλλον, τα bits που χρειάζεστε) να ενσωματωθούν στη συνέλευση σας, ώστε να μην χρειάζεται να τα αναπτύξετε παράλληλα με την εφαρμογή σας.</p><p>για οποιονδήποτε λόγο, αυτή η συνέλευση δεν μπορεί να ενσωματωθεί - αλλά αυτό ακούγεται σαν να μην είναι πρόβλημα για εσάς. ανοίξτε την καρτέλα ιδιότητες για τη συνέλευση στο visual studio 2010 και ορίστε "ενσωμάτωση τύπων interop" σε "false".</p><p>edit: δείτε επίσης την <a href="https://stackoverflow.com/a/4553402/641833">απάντηση</a> του michael gustus, καταργώντας το επίθημα <code>class</code> από τους τύπους που χρησιμοποιείτε.</p> Συχνά αυτό επιτυγχάνεται με τη χρήση [«Driven δεδομένων Συνδρομές»](https://msdn.microsoft.com/en-us/library/ms169673.aspx) , αλλά αυτή η λειτουργία είναι διαθέσιμη μόνο σε ορισμένες εκδόσεις του SQL: Enterprise και Business Intelligence, αλλά όχι στο πρότυπο.


Έτσι, υπάρχει μια σειρά από δημιουργικές λύσεις. Αλλά δεν μου αρέσει κάποια από αυτές, και απαιτούν ένα δίκαιο κομμάτι της εργασίας έξω από SSRS.


Οι λύσεις που έχω δει περιλαμβάνουν: Δημιουργία της εγγραφής και στη συνέχεια απενεργοποίηση ή επιτρέπουν την εργασία SQL που στέλνει τη συνδρομή (που προσδιορίζονται από GUID.)


Δημιουργήστε ένα .exe .NET περιτύλιγμα για να χειριστεί την αποστολή του email. Μπορεί να εκτελέσετε το ερώτημα πρώτα να δούμε πόσα επέστρεψε σειρές, και στη συνέχεια, αν χρειαστεί, να δημιουργήσει την έκθεση και να συμπεριληφθεί σε ένα email. μια λύση είναι να χρησιμοποιήσεις την web έκδοση. θέλει chrome που νομίζω υπάρχει ακόμα στα 32bit. το πρόβλημα μάλλον είναι ότι δεν κλείνει ουσιαστικά η εφαρμογή. είχα παρόμοιο θέμα πριν αρκετό καιρό(νομίζω κάποια στιγμή είχα απαντήσει εδώ σε ανάλογο θέμα). αυτό που έκανα εγώ και διόρθωσε το πρόβλημα ήταν η τροποποίηση της συντόμευσης για το άνοιγμα της εφαρμογής και η αλλαγή της γραμμής που ανοί…