ASP.NET jQuery Таблица Ajax со входом сохраняется при завершении

У меня есть таблица с текстом ввода, который выглядит так:

<input type='text' value='{Value}' id='{Model.ID}' class='ChckNumber' />

имя класса отличается от того, в каком столбце оно находится, Model.ID отличается от строки, а столбец отличается от столбца и строки.

Когда текст ввода становится нефокусированным, я вызываю api для обновления значения с тем, что пользователь вводил так:

$("input[type=text]").on("focusout", function () {

        var id = $(this).attr("id");
        var column = $(this).attr("class");
        var value = $(this).val();

        if (typeof id !== "undefined" && typeof column !== "undefined" && typeof value !== "undefined") {

            $.ajax({
                url: "/api/Action/UpdateTable?id=" + id + "&column=" + column + "&value=" + value,
                type: "GET",
                error: function (request, status, error) {
                    InsertLogEntry(request.responseText + " From API Call /api/Action/UpdateTable");
                },
                success: function (data) {
                }
            });
        }

    });

Вот его контроллер:

[HttpGet]
        public void UpdateTable(int id, string column, string value)
        {
            MethodClass method = new MethodClass();

            if(column != null && column != "" && id != 0)
            {
                method.UpdateTable(id, column, value);
            }
        }

и вот вызов метода, который я делаю:

public void UpdateTable(int id, string column, string value)
        {

            connection = new SqlConnection(connectionString);

            if(column.Contains("Date"))
            {
                DateTime dt = Convert.ToDateTime(value);

                command = new SqlCommand("UPDATE tblCheckTrackerRegister SET " + column + " = @Date WHERE ID = " + id);

                command.Parameters.Add("@Date", System.Data.SqlDbType.DateTime);

                command.Parameters["@Date"].Value = dt.Equals(DateTime.MinValue) ? (object)DBNull.Value : dt;

            }
            else
            {

                int result;

                if (int.TryParse(value, out result))
                {
                    command = new SqlCommand("UPDATE table SET " + column + " = " + value + " WHERE ID = " + id);
                }
                else
                {
                    command = new SqlCommand("UPDATE table SET " + column + " = '" + value + "' WHERE ID = " + id);
                }

            }

            command.Connection = connection;

            connection.Open();

            command.ExecuteNonQuery();

            connection.Close();

        }

Это хорошо работает, но я хочу улучшить его. Я искренне верю, что должен быть лучший способ сделать это, потому что мой код кажется беспорядочным для меня. Мой вопрос в том, может ли кто-нибудь предложить другой способ сделать то, что я пытаюсь выполнить?

Ответ 1

Первая

Ваш код подвержен атаке SQL Injection. Это красный флаг безопасности.

command = new SqlCommand("UPDATE tblCheckTrackerRegister SET " + column + " = @Date WHERE ID = " + id);
command = new SqlCommand("UPDATE table SET " + column + " = " + value + " WHERE ID = " + id);
command = new SqlCommand("UPDATE table SET " + column + " = '" + value + "' WHERE ID = " + id);

Предложение: Используйте запрос параметризации.

Второй

Вы обновляете запись, поэтому вам не следует использовать метод GET. Он нарушает базовый принцип REST - действие GET считается безопасным, и оно не должно ничего менять в системе.

Предложение: Используйте Ajax POST.

$.ajax({
  ...                
  type: "POST",
  ...            
});

Дизайн UX

Я не знаю причины, почему каждое текстовое поле обновляется сразу же после фокуса. Это не общий подход. С точки зрения пользователя, это не дружелюбно, потому что они не уведомлены об изменениях, которые сохраняются.

Обычно мы обновляем группу элементов управления за раз или одну строку за раз в Grid.

Предложение: Не предложение; это просто личное предпочтение, так что не поймите меня неправильно. Мне лично нравится обновлять кусок управления в то время, как прикрепленный скриншот StackOver -

введите описание изображения здесь

Ответ 2

Попробуйте определить набор условий в JS-коде, чтобы использовать несколько контроллеров в соответствии с потребностями определения столбца, например:

$("input[type=text]").on("focusout", function () {

        var id = $(this).attr("id");
        var column = $(this).attr("class");
        var value = $(this).val();
        var controler = "UpdateTable";
        if(column=='Delete'){
           controler = "DeleteTable";
        }
        if(column=='Mail'){
           controler = "SendMail";
        }
        if (typeof id !== "undefined" && typeof column !== "undefined" && typeof value !== "undefined") {

            $.ajax({
                url: "/api/Action/" + controler + "?id=" + id + "&column=" + column + "&value=" + value,
                type: "GET",
                error: function (request, status, error) {
                    InsertLogEntry(request.responseText + " From API Call /api/Action/" + controler);
                },
                success: function (data) {
                }
            });
        }

    });

Ответ 3

используя структуру сущности, вы можете легко обновить таблицу, используя гораздо более чистый и простой код.

using (var db = new MyEntities())
{
    var result = db.YourTable.SingleOrDefault(b => b.column == finditembyid);
    if (result != null)
    {
        try
        {
            result.Date = new DateTime();
            db.SaveChanges();
        }
        catch (Exception ex)
        {
            throw;
        }
    }
}

Ответ 4

Главное, о чем я могу думать, почему бы не использовать "change" вместо "focusout"? Focusout будет запускать ваш код, даже если значение не изменилось, вам это нужно?

Другое дело:

var id = $(this).attr("id");
var column = $(this).attr("class");
var value = $(this).val();

Может быть улучшено до:

var $this = $(this);
var id = $this.attr("id");
var column = $this.attr("class");
var value = $this.val();