如何将用户输入的ID与存储在ASP MVC中的数据库中的ID进行比较

时间:2015-09-29 14:17:20

标签: c# asp.net-mvc razor

我有一个允许用户创建新供应商的表单。我希望用户在文本框中输入供应商的ID,但我需要确保在创建供应商之前尚未获取该ID。如果获取了ID,我想要显示一条消息,告诉用户该ID已被删除,并在输入有效ID之前禁用提交按钮。

我有一个从数据库中提取供应商ID的功能,并根据数据库中已有的ID列表检查用户输入的ID。它根据是否采用用户输入的ID返回一个布尔值。

我遇到的问题是它不允许我在我的javascript中调用此函数。运行应用程序时,它告诉我“JavaScript运行时错误:'IsIdTaken'未定义”。如何在我的javascript中调用该函数?或者我如何从数据库中获取ID以根据用户输入的ID进行检查?

以下是我的代码:

@model EnterpriseServices.Vendor.Vendor

@{
    ViewBag.Title = "Add Vendor";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@functions {
    public static bool IsIdTaken(string userEnteredId)
    {
        bool isTaken = false;
        List<string> IDs = new List<string>();
        var vendors = EnterpriseServices.Vendor.VendorUtility.GetVendorIDandName();

        foreach (var v in vendors)
        {
            IDs.Add(v.Id);
        }

        if(IDs.Contains(userEnteredId))
        {
            isTaken = true;
        }

        return isTaken;
    }
}

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Create Vendor</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.Label("Vendor ID: ", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Id, new { htmlAttributes = new { @class = "form-control", id = "IdTextBox" } }) <label style="color:red" id="idTaken">This ID is already taken</label>
                @Html.ValidationMessageFor(model => model.Id, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.Label("Name: ", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.Label("Notes: ", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Notes, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Notes, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.Label("Is Active: ", htmlAttributes: new { @class = "control-label col-md-2"})
            <div class="col-md-10">
                @Html.CheckBoxFor(model => model.IsActive, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.IsActive, "", new { @class = "text-danger"})
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input id="submitButton" type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

<script type="text/javascript" src="jquery-2.1.4.min.js"></script>
<script type="text/javascript">
    $(document).ready(function () {
        $('#idTaken').hide()
        $('#IdTextBox').focusout(function () {
            var textboxId = $('#IdTextBox').val($(this).val())
            if (textboxId != null)
            {
                //Check to see if the Vendor ID entered by the user is already being used
                if (IsIdTaken(textboxId.toString()))
                {
                    $('#idTaken').show()
                    $('#submitButton').disabled()
                }
                else
                {
                    $('#idTaken').hide()
                    $('#submitButton').enabled()
                }
            }
        })
    })
</script>

4 个答案:

答案 0 :(得分:3)

Razor在服务器端运行,Javascript在客户端运行。你不能在JavaScript中调用Razor函数,因为到那时,服务器已经不再需要了。您需要使用AJAX将带有id的请求发送到应用程序中的某个端点(控制器操作)。然后,从该端点返回一个JSON,指示该值是否有效。然后,您可以使用JavaScript根据返回的JSON显示/隐藏错误消息。您还想要限制您的AJAX,以便您只在输入一定的字符阈值或用户完全离开该字段后才发送请求。

答案 1 :(得分:1)

我会将所有供应商ID放在您的模型上,因此您只需调用一次(如果您真的希望它们在客户端上)。我会将您的IsIdTaken方法定义为javascript方法。

答案 2 :(得分:1)

我能够像使用Chris Pratt建议的那样使用AJAX工作。

我的JavaScript:

<script type="text/javascript">
    $(document).ready(function () {
        $('#idTaken').hide()
        $('#IdTextBox').focusout(function () {
            $.ajax({
                type: "POST",
                url: '@Url.Action("CheckId", "VendorUI")'+ '?id=' + $('#IdTextBox').val(),
                contentType: "application/json; charset=utf-8",
                success: function(data) {
                    if (String(data) == "true")
                    {
                        $('#idTaken').show()
                        $('#submitButton').hide()
                        $('#IdTextBox').focus()
                    }
                    else
                    {
                        $('#idTaken').hide()
                        $('#submitButton').show()
                    }
                },
                error: function () {
                    alert('AJAX FAILED');
                }
            });
        })
    })
</script>

我的控制器:

public JsonResult CheckId(string id)
        {
            bool isTaken = false;
            List<string> IDs = new List<string>();
            IList<LightweightVendor> vendors = VendorUtility.GetVendorIDandName();

            foreach (var v in vendors)
            {
                IDs.Add(v.Id);
            }

                if (IDs.Contains(id))
            {
                isTaken = true;
            }

            return Json(isTaken);
        }

答案 3 :(得分:-1)

为什么不让数据库决定供应商的ID?如果您仍然想要调用数据库,则需要使用ajax查询,我认为@functions仅在razor构建页面时调用,并且在加载页面后无法使用javascript调用。如果您在发布之前在stackoverflow上搜索了许多示例。