如何防止将多个参数传递给控制器

本文关键字:参数传递 控制器 何防止 | 更新日期: 2023-09-27 17:59:43

现在我有一个表单,其中包含6个安全问题和6个安全答案。我一直在尝试重构我的代码,但我遇到了一个有趣的情况,我不确定如何继续。

这是我的观点:

var RequestSecurityQuestions_Submit = function () {
        ValidationAttribute.BlankValue(true);
        var form = $('form#RequestSecurityQuestions');
        $.validator.unobtrusive.parse(form);
        var d = $('form#RequestSecurityQuestions').serialize();
        SecurityQuestionsValid = true;
        var inputs = $('form#RequestSecurityQuestions').find('input[data-val]');
        $.each(inputs, function (index) {
            var input = inputs[index];
            if (!$(input).valid()) {
                SecurityQuestionsValid = false;
            }
        });
        var dataObject = {}, dropdowns = $("input.customdropdownlist");
    for (var i = 0; i < 6; i++) {
        dataObject['question' + i] = $(dropdowns[i]).data("kendoDropDownList").value()
    }
    for (var i = 1; i < 7; i++) {
        dataObject['answer' + i] = $('#idAnswer' + i).val();
    }
    var dataToPass = JSON.stringify(dataObject);
        if (SecurityQuestionsValid) {
            $.ajax({
                url: Url.getFullUrl('Account/RequestSecurityQuestions_Submit'),
                type: 'Post',
                data: { securityInfo: dataToPass },
                dataType: 'json',
                cache: false,
                success: function (data) {
                    //Next Dialog
                },
                error: AjaxLog.HandleAjaxCallFail
            });
        }
        return SecurityQuestionsValid;
    }

我得到一个dataObject,它包含我视图中的所有值,我想把它传递给控制器。

目前这项工作:

        [AllowAnonymous]
        [HttpPost]
        public ActionResult RequestSecurityQuestions_Submit(string answer1, string answer2, string answer3, string answer4, string answer5, string answer6, string question1, string question2, string question3, string question4, string question5, string question6)
        {
            SecurityQuestions securityQuestions = new SecurityQuestions();
            if (!string.IsNullOrEmpty(answer1))
            {
                securityQuestions.ChallengeA1 = answer1;
            }
            if (!string.IsNullOrEmpty(answer2))
            {
                securityQuestions.ChallengeA2 = answer2;
            }
            if (!string.IsNullOrEmpty(answer3))
            {
                securityQuestions.ChallengeA3 = answer3; 
            }
            //etc....
}

然而,我正在将12个参数传递给我的控制器,这听起来像是"不"。有没有其他方法可以将我的数据从我的视图传递到我的控制器而不必传递12个参数?

编辑:

新控制器尝试:

/*Problem: securityInfo array looks like: ""{'"question0'":'"2'",'"question1'":'"3'",'"question2'":'"4'",'"question3'":'"5‌​'",'"question4'":'"7'",'"question5'":'"1'",'"answerswer1'":'"fgfg'",'"answerswer2'":'"fgf‌​gf'",'"answerswer3'":'"fgfg'",'"answerswer4'":'"fgfgfg'",'"answerswer5'":'"fgfg'",'"answerswer6'"‌​:'"fggf'"}"" */
[AllowAnonymous]
        [HttpPost]
        public ActionResult RequestSecurityQuestions_Submit(string[] securityInfo)
        {
            SecurityQuestions securityQuestions = new SecurityQuestions();
}

如何防止将多个参数传递给控制器

当然,有多种方法可以实现这一点,下面就是其中之一。更好的方法是根据其他答案/注释重新构造代码。

// Creating your array
var dataObject = [], 
dropdowns = $("input.customdropdownlist");
//Populate your array. [0-5] will be questions and [6-11] will be answers .
    for (var i = 0; i < 6; i++) {
        if (i < 6){
            dataObject[i] = $(dropdowns[i]).data("kendoDropDownList").value()
        }
        else {
            var d = i - 5;
            dataObject[i] = $('#idAnswer' + d).val();
        }
    }
// Your AJAX call with contentType
            $.ajax({
                url: Url.getFullUrl('Account/RequestSecurityQuestions_Submit'),
                type: 'Post',
                data: JSON.Stringify(dataObject), //Change data format to JSON array, will be received as array in backend
                contentType: "application/json",
                cache: false,
                success: function (data) {
                    //Next Dialog
                },
                error: AjaxLog.HandleAjaxCallFail
            });

只需在后端中接收阵列

public ActionResult RequestSecurityQuestions_Submit(List<String> data)
        {
//Your code here
        }

Mate,好吧,我不明白为什么你有N个参数,它们有相同类型的数据——这才是类的真正意义。

简单的回答是,你可以创建一个包含这些参数的模型,然后在你的控制器上,只需RequestSecurityQuestions_Submit(Model postedModel)

然后访问里面的参数,比如postedModel.parameter1…在ajax调用中,它看起来像

 $.ajax({
            url: Url.getFullUrl('Account/RequestSecurityQuestions_Submit'),
            type: 'Post',
            data: {parameter1:'',parameter2:''...},
            cache: false,
            success: function (data) {
                //Next Dialog
            },

任何函数的多参数(n>3)在理论和实践中都是不好的,

您可以通过正确使用模型、绑定到模型并发布回您的模型来简化这一切。

查看型号

public class SecurityAnswerVM
{
    [Required(ErrorMessage="Please select a question")]
    [Display(Name = "Question")]
    public int? QuestionID { get; set; }
    [Required(ErrorMessage = "Please enter an answer")]
    public string Answer { get; set; }
}
public class SecurityLoginVM
{
    public SelectList QuestionList { get; set; }
    public List<SecurityAnswerVM> SelectedQuestions { get; set; }
}

控制器

[HttpGet]
public ActionResult Index()
{
    SecurityLoginVM model = new SecurityLoginVM();
    // Populate SelectedQuestions and QuestionList from the database
    return View(model);
}
[HttpPost]
public ActionResult Index(SecurityLoginVM model)
{
    // model.SelectedQuestions contains the 6 objects containing the QuestionID and the users Answer
    ....
}

编辑器模板(/Views/Shared/EditorTemplates/SecurityAnswerVM.cshtml

@model yourAssembly.SecurityAnswerVM
@Html.LabelFor(m => m.QuestionID)
@Html.DropDownListFor(m => m.QuestionID, (SelectList)ViewData["options"], "Please select", new { @class = "question" })
@Html.ValidationMessageFor(m => m.QuestionID)
@Html.LabelFor(m => m.Answer)
@Html.TextAreaFor(m => m.Answer)
@Html.ValidationMessageFor(m => m.Answer)

主视图

@model yourAssembly.SecurityLoginVM
@using(Html.BeginForm())
{
    @Html.EditorFor(m => m.SelectedQuestions, new { options = Model.QuestionList })
    <button id="save type="submit">Save</button> // or type="button" is posting via ajax
}

如果你想使用ajax发布数据

var url = '@Url.Action("Index")';
$('#save').click(function() {
    $.post(url, $('form').serialize(), function(data) {
        // Next Dialog
    });
});

更少的代码、强类型模型绑定、客户端和服务器端验证以及使用MVC的所有其他有益功能!

为什么不做这样的事情-

    public class QA {
         public int QId {get;set;}
         public string Answer {get;set;}
    }
    [AllowAnonymous]
    [HttpPost]
    public ActionResult RequestSecurityQuestions_Submit(QA[] answers)
    {
        for (var qa in answers){
             //do what ever you like
        }
    }

然后在js-中

// Creating your array
var dataObject = [], 
var dropdowns = $("input.customdropdownlist");
for (var i = 0; i < 6; i++) {
    dataObject[i] = {
        'QId': $(dropdowns[i]).data("kendoDropDownList").value(),
        'Answer': dataObject[i] = $('#idAnswer' + i).val();
    };
}

$.ajax({
    url: Url.getFullUrl('Account/RequestSecurityQuestions_Submit'),
    type: 'Post',
    data: JSON.stringify(dataObject),
    contentType: "application/json",
    cache: false,
    success: function (data) {
    },
    error: function(data){
    }
});