MVC5控制器:在保存之前检查数据库中是否存在重复?

时间:2015-03-12 16:12:12

标签: c# json asp.net-mvc linq controller

在我的View我有一个按钮,用于通过JSON向[description]提交Controller值,然后用于创建新的Table记录。例如:

    [HttpPost]
    public JsonResult createNewStatus(string description)
    {
        INV_Statuses status = new INV_Statuses()
        {
            // ID auto-set during save
            status_description = description,
            created_date = DateTime.Now,
            created_by = System.Environment.UserName
        };

        //var allErrors = ModelState.Values.SelectMany(x => x.Errors);

        try
        {
            if (ModelState.IsValid)
            {
                db.INV_Statuses.Add(status);
                db.SaveChanges();
            }

        }
        catch (Exception ex)
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
        }

        return Json(new { ID = status.Id, Text = status.status_description }, JsonRequestBehavior.AllowGet);
    }

我现在要做的事情(在将状态保存到数据库之前)运行检查以查看INV_Statuses表中的任何其他记录是否具有与提交的值匹配的[description]值到新创作的功能。如果匹配,我想返回error/validation?消息并提醒用户提交的值已存在,并从视图上的DropDownList中选择。

任何人都可以提供一个如何在我的MVC控制器中使用LINQ进行此操作的示例吗?


编辑:添加了我的View JS代码,用于提交新状态:

        $('#createNewStatus').click(function () {
            $('#createStatusFormContainer').show();
        })

        $('#cancelNewStatus').click(function () {
            $('#createStatusFormContainer').hide();
        })

        $('#submitNewStatus').click(function () {
            var form = $(this).closest('form');
            var data = { description: document.getElementById('textNewStatus').value };

            $.ajax({
                type: "POST",
                dataType: "JSON",
                url: '@Url.Action("createNewStatus", "INV_Assets")',
                data: data,
                success: function (resp) {
                    $('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
                    form[0].reset();
                    $('#createStatusFormContainer').hide();
                    var count = $('#selectStatus option').size();
                    $("#selectStatus").prop('selectedIndex', count - 1);
                },
                error: function () {
                    alert("ERROR!");
                }
            });
        });

EDIT2

Adricadar的建议:

        INV_Statuses status = new INV_Statuses()
        {
            // ID auto-set during save
            status_description = description,
            created_date = DateTime.Now,
            created_by = System.Environment.UserName
        };

        try
        {
            var existingStatus = db.INV_Statuses.FirstOrDefault(x => x.status_description.ToUpper() == status.status_description.ToUpper());
            var isDuplicateDescription = existingStatus != null;

            if (isDuplicateDescription)
            {
                ModelState.AddModelError("Error", "[" + status.status_description + "] already exists in the database. Please select from the DropDownList.");
            }
            else if (ModelState.IsValid)
            {
                db.INV_Statuses.Add(status);
                db.SaveChanges();
            }
        }
        catch (Exception ex)
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
        }

        return Json(new { ID = status.Id, Text = status.status_description }, JsonRequestBehavior.AllowGet);

我在Controller中的比较中添加了.ToUpper(),但即使识别出与.ToUpper()的匹配,ModelState.AddModelError()代码也会触发,然后代码返回并且不会发出错误消息?

值(虽然重复)仍然通过我当前的JS代码添加到下拉列表中(在视觉上,而不是在DB中):

        $('#createNewStatus').click(function () {
            $('#createStatusFormContainer').show();
        })

        $('#cancelNewStatus').click(function () {
            $('#createStatusFormContainer').hide();
        })

        $('#submitNewStatus').click(function () {
            var form = $(this).closest('form');
            var data = { description: document.getElementById('textNewStatus').value };

            $.ajax({
                type: "POST",
                dataType: "JSON",
                url: '@Url.Action("createNewStatus", "INV_Assets")',
                data: data,
                success: function (resp) {
                    $('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
                    form[0].reset();
                    $('#createStatusFormContainer').hide();
                    var count = $('#selectStatus option').size();
                    $("#selectStatus").prop('selectedIndex', count - 1);
                },
                error: function () {
                    alert("ERROR!");
                }
            });
        });

2 个答案:

答案 0 :(得分:1)

检查现有状态并将状态设置如下:

var existingStatus = db.INV_Statuses.FirstOrDefault(s => s.status_description == description);

if (existingStatus ==null)
{
   db.INV_Statuses.Add(status);
   db.SaveChanges();
}
else 
{ 
   // set the status back to existing
   status = existingStatus;   
}

在回复中设置现有标记:

return Json(new { ID = status.Id, Text = status.status_description, AlreadyExists = (existingStatus != null)  }, JsonRequestBehavior.AllowGet);

然后在您的响应JavaScript中,只需解析返回的数据:

success: function (resp) {

if (resp.AlreadyExists != true)
{
     $('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
     form[0].reset();
     $('#createStatusFormContainer').hide();
     var count = $('#selectStatus option').size();
     $("#selectStatus").prop('selectedIndex', count - 1);
      }
      else
      {
         alert(resp.status_description + " already exists");
         $("#selectStatus").val(resp.Id);
      }
 }

答案 1 :(得分:1)

您可以在数据库中查询具有现有描述的状态(如果存在)和模型状态错误。

请注意字符串比较区分大小写

[HttpPost]
public JsonResult createNewStatus(string description)
{
    INV_Statuses status = new INV_Statuses()
    {
        // ID auto-set during save
        status_description = description,
        created_date = DateTime.Now,
        created_by = System.Environment.UserName
    };

    //var allErrors = ModelState.Values.SelectMany(x => x.Errors);

    try
    {
        var existingStatus = db.INV_Statuses.FirstOrDefault(x => x.status_description.ToUpper() == status.status_description.ToUpper());
        var isDuplicateDescription = existingStatus != null;

        string error = String.Empty;
        if (isDuplicateDescription)
        {
           error = "[" + status.status_description + "] already exists in the database. Please select from the DropDownList.";
        }
        else if (ModelState.IsValid)
        {
            db.INV_Statuses.Add(status);
            db.SaveChanges();
        }

    }
    catch (Exception ex)
    {
        Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
    }

    return Json(new { ID = status.Id, Text = status.status_description, Error = error , IsDuplicate = isDuplicateDescription }, JsonRequestBehavior.AllowGet);
}

javascript中验证响应是否为IsDuplicate = true如果为真,则跳过需要在下拉列表中添加元素的部分。

    $('#createNewStatus').click(function () {
        $('#createStatusFormContainer').show();
    })

    $('#cancelNewStatus').click(function () {
        $('#createStatusFormContainer').hide();
    })

    $('#submitNewStatus').click(function () {
        var form = $(this).closest('form');
        var data = { description: document.getElementById('textNewStatus').value };

        $.ajax({
            type: "POST",
            dataType: "JSON",
            url: '@Url.Action("createNewStatus", "INV_Assets")',
            data: data,
            success: function (resp) {
                if(resp.IsDuplicate)
                {
                     //display error from response
                     //display resp.Error
                } else {
                    $('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
                    form[0].reset();
                    $('#createStatusFormContainer').hide();
                    var count = $('#selectStatus option').size();
                    $("#selectStatus").prop('selectedIndex', count - 1);
                }
            },
            error: function () {
                alert("ERROR!");
            }
        });
    });