【问题标题】:MVC4: Model's properties are null - 2MVC4:模型的属性为空 - 2
【发布时间】:2014-05-29 15:35:34
【问题描述】:

由于某种原因,当我按下视图的任何按钮时,传递给操作方法的模型的所有属性都为空:

查看:

@using (Html.BeginForm("FolderChange", "EdiSender", FormMethod.Post, new {id = "ediFilesForm"}))
{
    var directoriesSelectList = new SelectList(Model.Directories);
    @Html.DropDownListFor(m => m.SelectedDirectory, directoriesSelectList, new {@Id = "Directories", @style = "width:Auto;", @size = 20, onchange = "$('#ediFilesForm').submit()", name = "action:FolderChange"})

    var ediFilesSelectList = new SelectList(Model.EdiFileNames);
    @Html.DropDownListFor(m => m.SelectedEdiFile, ediFilesSelectList, new {@Id = "EdiFileNames", @style = "width:Auto;", @size = 20})
}

<br/>
...

<form action="" method="post">
    <input type="submit" value="Send" name="action:Send" />
    <input type="submit" value="Delete" name="action:Delete" />
    <input type="submit" value="Refresh" name="action:Refresh" />
</form>

控制器:

    [HttpPost]
    [MultipleButton(Name = "action", Argument = "Send")]
    public ActionResult Send(EdiFileModel ediFileModel)
    {
           ....
    }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MultipleButtonAttribute : ActionNameSelectorAttribute
{
    public string Name { get; set; }
    public string Argument { get; set; }

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        var isValidName = false;
        var keyValue = string.Format("{0}:{1}", Name, Argument);
        var value = controllerContext.Controller.ValueProvider.GetValue(keyValue);

        if (value != null)
        {
            controllerContext.Controller.ControllerContext.RouteData.Values[Name] = Argument;
            isValidName = true;
        }

        return isValidName;
    }
}

当我的按钮在 Html.BeginForm() 块中时它曾经可以工作,但我不能再这样了,因为它现在的操作名称为 FolderChange(),这与例如不同。 Send() 或其他处理按钮按下的操作方法。

谢谢。

已编辑:

@section scripts
{
    <sctipt type="text/javascript">
    $("#Directories").change(function () {
        var selectedDirectory = $("#Directories").val();   

        $(function () {
            $.getJSON('/DoWork/FolderChangeAjaxCall?selectedDirectory=' + selectedDirectory, function (result) {
                var ddl = $('#EdiFileNames');
                ddl.empty();
                $(result).each(function () {
                    $(document.createElement('option'))
                .attr('value', this.Id)
                .text(this.Value)
                .appendTo(ddl);
                });
            });
        });
    });    
    </sctipt>
}

<h2>Existing EDI Files</h2>
@using (Html.BeginForm("FolderChange", "EdiSender", FormMethod.Post, new {id = "ediFilesForm"}))
{
    var directoriesSelectList = new SelectList(Model.Directories);
    @Html.DropDownListFor(m => m.SelectedDirectory, directoriesSelectList, new {@Id = "Directories", @style = "width:Auto;", @size = 20})

    var ediFilesSelectList = new SelectList(Model.EdiFileNames);
    @Html.DropDownListFor(m => m.SelectedEdiFile, ediFilesSelectList, new {@Id = "EdiFileNames", @style = "width:Auto;", @size = 20})

【问题讨论】:

  • 你回答了你自己的问题,你说当你的按钮在表单中时它会用它来工作。现在他们在表格之外并且知道您的模型或模型的属性是什么。您可以有 1 种形式的提交按钮,并且在控制器方法中您可以确定哪个被点击了
  • @C Sharper 我知道我可以有一种形式的按钮,但是当按钮采用相同的形式时,上面的下拉菜单不起作用,因为我需要在 Html.BeginForm() 操作中指定下拉菜单的特定名称。如果我没有指定动作名称,控制器将无法区分按钮和下拉菜单。
  • Idk 听起来你做的有点复杂,你有没有想过在 ddl 更改上使用 Ajax 调用而不是提交表单?
  • @C Sharper 不幸的是,我还不知道该怎么做。
  • 好吧,让我们来看看这个场景,你在每次下拉列表更改后发布到控制器正确吗?所以我猜它会用到一个名为FolderChange 的方法,你在里面做什么。你只是想获取 ddl 选择的值,然后呢

标签: asp.net-mvc-4


【解决方案1】:

在这里,它可能与您认为的答案相去甚远,但它会级联下拉菜单。您将不得不替换您的价值观和背景,但它会起作用。现在您可以将按钮放置在表单中,而不必让下拉菜单提交表单,这无论如何都是很糟糕的设计。

@Html.DropDownListFor(x => x.ddlID, Model.myDDLList, new { id = "ddl" }) 

@Html.DropDownListFor(x => x.myDDLList2, Model.myDDLList2, new { id = "foo" }) 

脚本

$("#ddl").change(function () {

        var Id = $("#ddl").val(); //1st dropdown Value        

        $(function () {
            $.getJSON('/DoWork/AjaxCall?Id=' + Id, function (result) {
                var ddl = $('#foo');
                ddl.empty();
                $(result).each(function () {
                    $(document.createElement('option'))
                .attr('value', this.Field1)
                .text(this.Field2)
                .appendTo(ddl);
                });
            });
        });
    });

控制器

public ActionResult AjaxCall(int Id)
    {
        using (PerformanceEntities context = new PerformanceEntities())
        {             
            return this.Json(
                  (from obj in context.ACCOUNT.Where(x => x.ACCT_ID == Id).ToList() 
                   select new
                   { 
                       Field1 = obj.ACCT_ID,
                       Field2 = obj.ACCT_NAME 
                   }),
                  JsonRequestBehavior.AllowGet
               );
        }         
    }

您可以查看this的帖子以供参考

【讨论】:

  • @C Sharper 谢谢。我试过了,但由于某种原因,脚本的内容显示在页面上......我做错了什么?我将我的代码添加到原始问题中。顺便说一句,我不在下拉列表中使用 Id 和 Value,目录和文件名是唯一的。
  • 它出现在页面上可能是因为您像这样关闭了脚本&lt;/sctipt&gt; 哈哈。我不确定,但您可能必须为下拉列表的文本和值字段提供一个字段
  • @C Sharper 是的,我拼错了。执行并没有到达 FolderChangeAjaxCall() 虽然......
  • 小心,您复制并粘贴了我的代码,并没有根据您的情况进行更改。看这里'/DoWork/FolderChangeAjaxCall?selectedDirectory 你试图调用一个名为DoWork 的控制器。同样,在您拥有 this.id/this.value 的每个函数中...您必须将 Id 和 Value 更改为您想要的,我将进行编辑以表明您可以定义您想要的任何字段
  • 根据 JQuery 的哪个版本,它是以下之一 $("select#foo").prop('selectedIndex', 0); $("select#foo").attr('selectedIndex', 0);
猜你喜欢
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
  • 1970-01-01
相关资源
最近更新 更多