1

私はここで私の会社でサービスのデータベース入力システムに取り組んでいます。各サービスは、必要な数の操作を行うことができます。同様に、各操作には必要な数のパラメーターを含めることができます。私がやろうとしているのは、動的フォームを使用して、サービス/編集ビュー内の操作のパラメーターのデータを更新することです。

サービスに操作を追加するために動的フォームを使用しましたが、サービスビューから投稿するのではなく、操作/作成から投稿していました。これは問題ではないはずですが、私はそれを指摘したいと思いました。

今、私が抱えている問題は、パラメータフォームからサーバーにデータを投稿することです。ModelState.isValidがfalseに戻ってきました。モデル状態を見ると、すべてのサービスデータメンバーと操作データメンバーがありますが、すべてのパラメーターデータメンバーが失われています。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; }
    }
4

1 に答える 1

2

あなたが呼んでいる:

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

...これにより、投稿されたパラメータは規則に従いますParameters[i].DataMembers。ただし、長期的にバインドするモデルは個別ではありません。プロパティを持つのOperationは全体であり、各操作にはプロパティがあります。したがって、投稿されたパラメータをのように見せたいと思います。ServiceOperationsParametersOperations[i].Parameters[i].DataMembers

これを行うには、エディターを呼び出すときにhtmlFieldNameを指定する必要があります。

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

もちろん、上記の行は0番目の操作でのみ機能します。エディターを作成する操作のインデックスを渡すために、文字列を動的に作成する必要があります。これには、最初にインデックスをコントローラーに渡すために元のAJAXリンクを取得するために追加の調整が必要になる可能性がありますが、それを理解できるはずです。

于 2012-07-05T17:43:34.333 に答える