【问题标题】:How to submit dynamic number of string inputs in ASP.NET Core MVC如何在 ASP.NET Core MVC 中提交动态数量的字符串输入
【发布时间】:2023-03-09 11:34:01
【问题描述】:

我的应用程序中有一个页面,允许用户对数据库运行存储过程,这样他们就可以在不使用 SSMS 的情况下管理他们的数据或进行更改。使用SqlCommandBuilder.DeriveParameters 方法,我能够成功地获取并显示选择标记中的所有存储过程,并显示它们的输入和输出参数。

这里是合约类:

public class DatabaseUpdateModel
{
    public int ClientId { get; set; }
    public string StoredProcedureName { get; set; }
    public List<SelectListItem> StoredProcedureNames { get; set; }
    public Dictionary<string, SqlParamCollection> StoredProcedures { get; set; }
    public Dictionary<int, string> ParameterInputs { get; set; }


    public DatabaseUpdateModel()
    {
        StoredProcedureNames = new List<SelectListItem>();
        StoredProcedures = new Dictionary<string, SqlParamCollection>();
        ParameterInputs = new Dictionary<int, string>();
    }
}

我分两步执行此操作 - 第 1 步发生在控制器的索引加载以获取存储过程名称:

服务方式:

    private DatabaseUpdateModel GetDatabaseUpdateStoredProcedureNames(string connectionString)
    {
        _logger.LogTrace("Begin GetDatabaseUpdateModel service method");
        SqlConnection connection = new SqlConnection(connectionString);
        DBConnectionSetter.SetDBConnection(_SqlHelper, connectionString);

        DatabaseUpdateModel model = new DatabaseUpdateModel();
        IDataReader reader = _SqlHelper.GetDataReader("SELECT name FROM sys.objects WHERE type = 'p' ORDER BY name ASC", CommandType.Text, _appSettings.CommandTimeoutInSeconds, out connection, null);

        while (reader.Read())
        {
            SelectListItem storedProcedure = new SelectListItem
            {
                Value = ((string)reader["name"]).Trim(' '),
                Text = (string)reader["name"]
            };

            model.StoredProcedureNames.Add(storedProcedure);
        }
        reader.Close();

        return model;
    }

选择存储过程时,第 2 步通过 Ajax 发生

 public DatabaseUpdateModel GetDatabaseUpdateProcedureParameters(string connectionString, string storedProcedureName)
    {
        _logger.LogTrace("Begin GetDatabaseUpdateProcedureParameters service method");
        SqlConnection connection = new SqlConnection(connectionString);
        DBConnectionSetter.SetDBConnection(_SqlHelper, connectionString);
        DatabaseUpdateModel model = GetDatabaseUpdateStoredProcedureNames(connectionString);
        connection.Open();

        Contract.Shared.SqlParamCollection collection = new Contract.Shared.SqlParamCollection();
        SqlCommand command = new SqlCommand();
        command.Connection = connection;
        command.CommandText = storedProcedureName;
        command.CommandType = CommandType.StoredProcedure;
        SqlCommandBuilder.DeriveParameters(command);
        foreach (SqlParameter param in command.Parameters)
        {
            if (param.Direction == ParameterDirection.Input)
            {
                collection.InputParameters.Add($"{param.ParameterName} - {param.SqlDbType}");
                collection.SqlParameters.Add(param);
            }
            else
            {
                collection.OutputParameters.Add($"{param.ParameterName} - {param.SqlDbType}");
            }
        }

        model.StoredProcedures.Add(storedProcedureName, collection);
        connection.Close();
        return model;
    }

这留给我的是:

现在我一直在关注各种文章和资源以达到这一点,但现在我在将这些输入正确绑定到要通过操作或通过 ajax 提交的模型时遇到问题。这是我当前在视图中的代码(注释掉的行是我最近尝试让它工作的一种)。

@model DatabaseUpdateModel

<form>
    <table id="summaryTable" class="table">
        <thead>
            <tr>
                <td>Input Parameters</td>
                <td>Output Parameters</td>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>
                    <ul>
                        @if (!string.IsNullOrEmpty(Model.StoredProcedureName))
                        {
                            for (int i = 0; i < Model.StoredProcedures[Model.StoredProcedureName].InputParameters.Count(); i++)
                            {
                        <li>
                            @Model.StoredProcedures[Model.StoredProcedureName].InputParameters[i].ToString()<br />
                            @*<input id="databaseUpdateParam[@i]" name="parameter[@i]" asp-for="@Model.ParameterInputs[@i]" type="text" />*@
                            <input id="databaseUpdateParam[@i]"type="text" />
                        </li>
                            }
                        }
                    </ul>
                </td>
                <td>
                    <ul>
                        @if (!string.IsNullOrEmpty(Model.StoredProcedureName))
                        {
                            foreach (var param in Model.StoredProcedures[Model.StoredProcedureName].OutputParameters)
                            {
                                <li>
                                    @param
                                </li>
                            }
                        }
                    </ul>
                </td>
            </tr>
        </tbody>
    </table>
</form>
@if (Model.StoredProcedures[Model.StoredProcedureName].InputParameters.Count() > 0)
{
    <button type="submit" asp-action="Foo">Submit</button>
}

选择值时运行的 Ajax 函数:

function selectDatabaseUpdateStoredProcedure(clientId, storedProcedureName) {
    var selected = $("#clientStoredProcedurePicker option:selected").val();
    console.log(selected); // Selected Stored Procedure Name
    $.ajax({
        url: "/Process/GetDatabaseUpdateProcedureParameters?ClientId=" + clientId + "&StoredProcedureName=" + storedProcedureName,
        success: function (data) {
            console.log(data);
            $("#summaryTableDiv").html(data);
        }
    });
}

我的假设,以及到目前为止我阅读的所有内容都表明,我应该能够简单地使用 name 属性来表示字典的键,并且标签中的值将对应于表单中输入的值提交。然而,我为实现这一目标所做的所有尝试都遇到了错误(例如,字典中不存在索引)。

如何通过控制器操作或 ajax 来实现?

【问题讨论】:

  • @Seabizkit 是的,我看到了那个帖子并尝试了一些非常相似的东西。我尝试将我的字典从 更改为 并多次更改我的输入标签助手以尝试获取提交的值。我目前正在阅读链接的博客文章。
  • @Seabizkit 好吧,我觉得自己像个白痴。在下面发布我的答案。
  • 很高兴你把它分类了,是的,我可以为你做,但是当你和它斗争时你会学到很多东西,然后当你想出你喜欢的 yippy,我只是想让你有一个链接可以关注某些东西,我记得大约 10 年前我试图解决这个问题时......为什么链接更少,我也尝试了感觉像一百万种方法。一旦你知道它是如何工作的,你就可以将模型绑定到其他动态类型列表......
  • 是的,这是我偶然发现的第一个链接。我在阅读之前写下了这个问题,因为这是我过去一两天一直在努力解决的问题。 :)

标签: c# jquery ajax asp.net-core


【解决方案1】:

我想提出这个问题,以便如果有更多知识渊博的人遇到它,我可能会获得一些见解,从而为自己节省更多时间摸不着头脑。在阅读了this question 中链接的article 之后,我发现我错过了如何呈现 HTML 的关键部分,并想出了这样的东西,现在可以正确地在输入中发布值。我仍然需要处理和处理模型中其他缺失的部分,但至少这让我得到了前进所需的东西。

这里是允许它工作的相关代码。创建一个隐藏输入来自行存储 ID 并允许用户输入字符串值似乎完全符合我的预期和希望。

<td>
  <ul>
    @if (!string.IsNullOrEmpty(Model.StoredProcedureName))
    {
       for (int i = 0; i < Model.StoredProcedures[Model.StoredProcedureName].InputParameters.Count(); i++)
       {
         <li>
              @Model.StoredProcedures[Model.StoredProcedureName].InputParameters[i].ToString()<br />
              <input hidden id="databaseUpdateParamKey[@i]" name="ParameterInputs[@i].Key" value="@i" />
              <input id="databaseUpdateParamValue[@i]" name="ParameterInputs[@i].Value" type="text" />
         </li>
        }
     }
  </ul>
</td>

【讨论】:

    猜你喜欢
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 2015-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多