【问题标题】:MVC3- Posting dynamic form data back to the server using AJAXMVC3-使用 AJAX 将动态表单数据发布回服务器
【发布时间】:2012-07-05 14:16:54
【问题描述】:

我正在为我公司的服务开发数据库输入系统。每个服务可以根据需要进行任意数量的操作。同样,每个操作可以根据需要具有任意数量的参数。我正在尝试做的是使用动态表单来更新我的服务/编辑视图中操作参数的数据。

我使用动态表单向服务添加操作,但不是从我的服务视图发布它们,而是从操作/创建发布它们。这应该不是问题,但我想我会指出这一点。

现在,我遇到的问题是将参数表单中的数据发送回服务器。 ModelState.isValid 返回错误。当我查看我的模型状态时,我的所有服务数据成员和我的操作数据成员都在那里,但是我所有的参数数据成员都丢失了。我使用 FormCollection 检查动态表单的名称,它们实际上遵循 MVC 的模型绑定命名约定 (Parameters[i].DataMembers)。

希望有人可以为我提供一些见解。下面是一些可能有用的代码:

在我的服务控制器中:

    public ActionResult Edit(int id = 0)
    {
        if (id == 0)
        {
            return HttpNotFound();
        }

        //Eager loads the operations and parameters for this service
        var service = db.Services.Include(s => s.Operations.Select(o => o.Parameters)).Where(s => s.ServiceID == id).Single();

        if (service == null)
        {
            return HttpNotFound();
        }

        return View(service);
    }

在我的服务/编辑视图中,我使用编辑器模板来显示操作的表单。我还在这个表单块之后放置了一个空 div,稍后通过 AJAX.ActionLink 填充参数表单:

    @Html.EditorFor(m => Model.Operations)

    <div id="parameter_container">
    </div>

然后在我的编辑器模板中设置我的 AJAX.ActionLink:

    @Ajax.ActionLink("Edit Parameters", "EditParams", "Services", new { opID = Model.OperationID, ViewContext.FormContext.FormId },
            new AjaxOptions
            {
                UpdateTargetId = "parameter_container",
                InsertionMode = InsertionMode.Replace,
                HttpMethod = "Post"
            })

然后回到我的服务控制器中:

    public PartialViewResult EditParams(int opID = 0)
    {
        if (opID == 0)
        {
            return PartialView();
        }

        var operation = db.Operations.Include(o => o.Parameters).Where(o => o.OperationID == opID).Single();

        if (operation.parameters == null)
        {
            return PartialView();
        }

        return PartialView("ParameterEditorRow", operation);
    }

ParameterEditorRow是强类型化到我的操作模型的局部视图(这个需要在操作后建模。将Model.Parameters传递到编辑器模板中会生成所需的命名约定(Parameters[i].DataMembers)。这很简单:

    @model InformationStore.Models.Operation
    @{if (this.ViewContext.FormContext == null)
        {
            this.ViewContext.FormContext = new FormContext();
        }  
     }
    <div class="editor_row">
       @Html.EditorFor(m => Model.Parameters)
    </div>

最后,我有一个用于参数的编辑器模板。我为这篇冗长的帖子道歉,但我已经坚持了几天了。我只是觉得我的方法存在根本性的问题。有什么建议吗?

编辑以响应 StriplingWarrior

在我的编辑视图中,我所有的输入字段都在这个表单中:

 @using (Html.BeginForm("edit", "services", new {Model.ServiceID}, FormMethod.Post))

并正在发布到:

    [HttpPost]
    public ActionResult Edit(Service service)
    {
        if(ModelState.IsValid)
        {
           //update db
        }
        return View(service)
    }

我使用 IE 网络捕获来查看回传的内容,但它只是在中断时显示待处理,然后锁定。我必须承认,我不经常使用它,所以这可能是我的问题。

模型类(省略了特定于类的成员):

    public class Service
    {
       [Key]
       public int ServiceID {get; set;}

       public virtual List<Operation> Operations {get; set;}
    }

    public class Operation
    {
       [Key]
       public int OperationID { get; set; }

       [Required]
       public int ServiceID { get; set; }

       [Required]
       public virtual Service Service { get; set; }

       public virtual ICollection<Parameter> Parameters { get; set; }
    }

    public class Parameter
    {
       [Key]
       public int ParameterID { get; set; }

       [Required]
       public int OperationID { get; set; }

       [Required]
       public virtual Operation Operation { get; set; }
    }

【问题讨论】:

  • "当我查看我的模型状态时,我的所有服务数据成员和我的操作数据成员都在那里,但我所有的参数数据成员都丢失了。" -- 这听起来像是模型绑定问题。您能否提供您要发布到的操作的代码以及您尝试绑定的任何模型类?还提供您看到离开浏览器的 POST 参数(通过 Firebug 或开发工具),并确定哪些参数是丢失的“参数数据成员”。
  • 很抱歉给您带来了困惑。 “参数数据成员”是指我的参数类的数据成员。

标签: asp.net-mvc model-binding mvc-editor-templates dynamic-forms asp.net-mvc-partialview


【解决方案1】:

你在打电话:

   @Html.EditorFor(m => Model.Parameters)

... 这导致发布的参数遵循约定Parameters[i].DataMembers。但是从长远来看,你绑定的模型并不是一个单独的Operation:它是整个Service,它有一个Operations 属性,每个操作都有一个Parameters 属性。所以你希望发布的参数看起来更像Operations[i].Parameters[i].DataMembers

为此,您需要在调用编辑器时指定 htmlFieldName:

   @Html.EditorFor(m => Model.Parameters, null, "Operations[0].Parameters")

当然,以上行只适用于第零个操作:您需要动态创建字符串以传入您正在为其创建编辑器的操作的索引。这可能需要额外的修改才能让原始 AJAX 链接首先将索引传递给控制器​​,但您应该能够弄清楚这一点。

【讨论】:

  • 您先生,是救生员。我从@ViewData.TemplateInfo.HtmlFieldPrefix 中解析出索引,传入你给我的字符串,现在添加到屏幕的参数字段绑定到它们对应的服务。感谢您的帮助。
  • @MrJones:没问题。用几分钟的指导来节省几个小时的头脑总是很好的。 :-)
猜你喜欢
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
  • 2020-02-12
  • 2017-10-03
  • 2020-06-14
  • 1970-01-01
  • 2021-09-15
  • 1970-01-01
相关资源
最近更新 更多