Один конкретный случай, где var является трудным: офлайн кодируйте обзоры, особенно те сделанные на бумаге.
Вы не можете полагаться на наведения мыши для этого.
Между завершенными приложениями и этими «половинными» состояниями может быть несколько отличий:
Поэтому я бы использовал другую базу данных с записью, содержащей несколько ключевых полей, таких как идентификатор пользователя, дата, вид формы, которую они заполняют, и т. д. и blob полей, которые они заполнили. Я занимаюсь Java, поэтому я не знаю, как .NET получить blob, но в Java я мог сериализовать объекты данных, поддерживающие форму.
Похоже, что в C # методы имеют некоторое сходство с Java, по крайней мере, я правильно понимаю эту статью .
Вы когда-нибудь думали об использовании Silverlight? Silverlight имеет изолированное хранилище, я видел несколько примеров, где разработчики использовали изолированное хранилище для хранения дорогостоящих клиентских данных.
А затем с помощью js для получения данных на выходе:
http://msdn.microsoft.com/en-us/library/cc221414%28VS.95 % 29.aspx
Это избавляет вас от необходимости в дополнительном пространстве БД, потому что все записи временных форм пользователя хранятся в изолированном хранилище, когда они возвращаются на страницу, вы спрашиваете пользователя, хотят ли они возобновить редактирование ... и затем заполните форму данными в изолированном хранилище ...
звучит более изящно, чем добавление новой базы данных?
Есть обратная сторона - машинно-зависимое решение. Это для того, чтобы его можно было поднять на других машинах? в таком случае это неправильное решение, а сохранение БД - лучшее зло.
Очевидно, вы не можете сохранить его в реальных таблицах данных, поэтому я бы создал отдельную таблицу с идентификатором пользователя, formid и двоичным типом данных. Объедините формы в некоторую сериализуемую структуру и сериализуйте их в db. Когда пользователь вернется, вы можете десериализовать и восстановить состояние формы.
Я боролся с той же проблемой. Одно отличие состоит в том, что мой метод включает автоматическое сохранение с помощью ajax, аналогичное тому, что вы видите в Gmail и Blogger. Но на самом деле это не должно изменить реализацию.
Проблема заключалась в том, что я не хотел сохранять в обычные таблицы, потому что для этого потребовалась бы проверка (проверка целых чисел, валют, дат и т. Д.). И я не хотел пилить пользователя по этому поводу, когда он на самом деле просто пытается уйти.
В конце концов я придумал таблицу под названием AjaxSavedData. Это постоянная таблица в базе данных, но данные, которые она содержит, обычно временные. Другими словами, он будет временно хранить данные пользователя, пока они не заполнят страницу и не перейдут к следующей.
Таблица состоит всего из нескольких столбцов:
AjaxSavedDataID - int:
Первичный ключ.
UserID - int:
Идентифицировать пользователя (достаточно просто).
PageName - varchar (100):
Необходимо, если вы работаете с несколько страниц.
ControlID - varchar (100):
Я называю это ControlID, но на самом деле это просто свойство ClientID, которое .NET предоставляет для всех WebControl. Так, если, например, txtEmail находится внутри пользовательского элемента управления с именем Contact, тогда ClientID будет Contact_txtEmail.
Значение - varchar (MAX):
Значение, введенное пользователем для данного поля или элемента управления.
DateChanged - datetime:
Дата добавления или изменения значения.
Наряду с некоторыми настраиваемыми элементами управления эта система позволяет легко «просто работать». На нашем сайте ClientID каждого текстового поля, раскрывающегося списка, списка радиообъектов, и т. д. гарантированно будет уникальным и непротиворечивым для данной страницы. Так что я смог написать все это так, чтобы извлечение сохраненных данных происходило автоматически. Другими словами, мне не нужно подключать эту функцию каждый раз, когда я добавляю несколько полей в форму.
Эта функция автоматического сохранения будет внедрена в очень динамичное онлайн-приложение для страхования бизнеса на сайте techinsurance.com чтобы сделать его немного более удобным для пользователя.
Если вам интересно, вот Javascript, который позволяет автосохранение:
function getNewHTTPObject() {
var xmlhttp;
/** Special IE only code */
/*@cc_on
@if (@_jscript_version >= 5)
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (E) {
xmlhttp = false;
}
}
@else
xmlhttp = false;
@end
@*/
/** Every other browser on the planet */
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
}
catch (e) {
xmlhttp = false;
}
}
return xmlhttp;
}
function AjaxSend(url, myfunction) {
var xmlHttp = getNewHTTPObject();
url = url + "&_did=" + Date();
xmlHttp.open("GET", url, true);
var requestTimer = setTimeout(function() { xmlHttp.abort(); }, 2000);
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2005 00:00:00 GMT");
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState != 4)
return;
var result = xmlHttp.responseText;
myfunction(result);
};
xmlHttp.send(null);
}
// Autosave functions
var SaveQueue = []; // contains id's to the DOM object where the value can be found
var SaveQueueID = []; // contains id's for binding references (not always the same)
function ArrayContains(arr, value) {
for (i = 0; i < arr.length; i++) {
if (arr[i] == value)
return true;
}
return false;
}
function GetShortTime() {
var a_p = "";
var d = new Date();
var curr_hour = d.getHours();
if (curr_hour < 12)
a_p = "AM";
else
a_p = "PM";
if (curr_hour == 0)
curr_hour = 12;
else if (curr_hour > 12)
curr_hour = curr_hour - 12;
var curr_min = d.getMinutes();
curr_min = curr_min + "";
if (curr_min.length == 1)
curr_min = "0" + curr_min;
return curr_hour + ":" + curr_min + " " + a_p;
}
function Saved(result) {
if (result == "OK") {
document.getElementById("divAutoSaved").innerHTML = "Application auto-saved at " + GetShortTime();
document.getElementById("divAutoSaved").style.display = "";
}
else {
document.getElementById("divAutoSaved").innerHTML = result;
document.getElementById("divAutoSaved").style.display = "";
}
}
function getQueryString(name, defaultValue) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == name) {
return pair[1];
}
}
return defaultValue;
}
function urlencode(str) {
return escape(str).replace(/\+/g, '%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40');
}
function AutoSave() {
if (SaveQueue.length > 0) {
var url = "/AjaxAutoSave.aspx?step=" + getQueryString("step", "ContactInformation");
for (i = 0; i < SaveQueue.length; i++) {
switch (document.getElementById(SaveQueue[i]).type) {
case "radio":
if (document.getElementById(SaveQueue[i]).checked)
url += "&" + SaveQueueID[i] + "=" + urlencode(document.getElementById(SaveQueue[i]).value);
break;
case "checkbox":
if (document.getElementById(SaveQueue[i]).checked)
url += "&" + SaveQueueID[i] + "=" + urlencode(document.getElementById(SaveQueue[i]).value);
default:
url += "&" + SaveQueueID[i] + "=" + urlencode(document.getElementById(SaveQueue[i]).value);
}
}
SaveQueue = [];
SaveQueueID = [];
AjaxSend(url, Saved);
}
}
function AddToQueue(elem, id) {
if (id == null || id.length == 0)
id = elem.id;
if (!ArrayContains(SaveQueueID, id)) {
SaveQueue[SaveQueue.length] = elem.id;
SaveQueueID[SaveQueueID.length] = id;
}
}
Добавьте это на свою страницу, чтобы эта работа работала:
window.setInterval("AutoSave()", 5000);
И применить это к Текстовое поле, DropdownList, Listbox или Checkbox вам просто нужно добавить этот атрибут:
onchange="AddToQueue(this)"
... или это для RadioButtonList или CheckBoxList:
onchange="AddToQueue(this, '" + this.ClientID + "')"
Я определенно сохраню его в базе данных. Ваш план сохранения с особым статусом (подойдет логический флаг Complete). Затем вы можете создать представление, которое извлекает только те элементы, для которых Complete = true, с именем CompletedApplications.