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

时间:2015-06-26 03:07:31

标签: javascript c# jquery asp.net-mvc asp.net-mvc-4

现在我有一个包含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\",\"answer1\":\"fgfg\",\"answer2\":\"fgf‌​gf\",\"answer3\":\"fgfg\",\"answer4\":\"fgfgfg\",\"answer5\":\"fgfg\",\"answer6\"‌​:\"fggf\"}"" */

[AllowAnonymous]
        [HttpPost]
        public ActionResult RequestSecurityQuestions_Submit(string[] securityInfo)
        {
            SecurityQuestions securityQuestions = new SecurityQuestions();

}

4 个答案:

答案 0 :(得分:1)

当然,有多种方法可以实现这一目标,以下是其中之一。更好的方法是根据其他答案/评论重新构建代码。

// 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
        }

答案 1 :(得分:1)

Mate,嗯,我不明白为什么你有N个参数,这些参数具有相同类型的数据 - 这就是这个类应该来的地方。

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

然后在内部访问您的参数,例如postingModel.parameter1 ...在您的ajax调用中,它看起来像

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

                //Next Dialog
            },

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

答案 2 :(得分:1)

您可以通过正确使用模型,绑定到模型并回发模型来简化所有这些。

查看模型

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
    ....
}

EditorTemplate(/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的所有其他有益功能!

答案 3 :(得分:0)

为什么不做这样的事情 -

    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){
    }
});