如何保存在 ASP.NET MVC 中以表单编辑的多个模型?

发布于 2024-10-16 13:31:51 字数 317 浏览 2 评论 0 原文

我需要创建一个支持批量插入对象的视图。我将存储库模式与实体框架 4 一起使用。

由于视图中将有多个单独的模型,因此如何处理将视图的模型绑定到发送到存储库的内容?

如何将表单中的输入值检索到控制器中?


我已成功完成视图,但无法从控制器检索数据。我使用了以下语句,但在发布后它碰巧变成了空

    public ActionResult AddPaymentForRoot_post(PaymentViewModelObject payments) {


        return null;

    }

I need to make a view which will support bulk inserting of objects. I am using the repository pattern with Entity Framework 4.

Since there will be multiple individual models in the View, how do I handle binding the view's model to what get's sent to the Repository?

How do I retreive the input values from the form into the controller?


I have managed to do the view but I am unable to retrieve the data from controller. I used the folowing statement but after the post it heppens to be nul

    public ActionResult AddPaymentForRoot_post(PaymentViewModelObject payments) {


        return null;

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

裸钻 2024-10-23 13:31:51

我还没有使用过 EF,但我在我们的网站上有类似的需求。我通过将 View 指定为继承 System.Web.Mvc.ViewPage> 来完成此操作,然后使用 for 循环构建多个输入部分,利用允许模型所需的命名约定绑定器来构建可枚举。

我更喜欢创建一个具有可枚举属性的视图模型(请参阅下面的更新 2)。在此示例中,我们可以说它是带有名为 MyModelObjectsIEnumerable 属性的 MyViewModel 对象。在这种情况下,视图将如下所示...

具体来说,请确保为每个输入部分包含一个名为 MyModelObjects.Index 的隐藏字段,然后将您的属性输入命名为 MyModelObjects[ 0].MyProperty,其中 Index 隐藏字段的值对应于属性名称中的数组索引。

你最终会得到这样的结果,例如:

<div>
    <input type="hidden" name="MyModelObjects.Index" value="0" />
    Name: <input type="text" name="MyModelObjects[0].Name" /><br />
    Value: <input type="text" name="MyModelObjects[0].Value" />
</div>
<div>
    <input type="hidden" name="MyModelObjects.Index" value="1" />
    Name: <input type="text" name="MyModelObjects[1].Name" /><br />
    Value: <input type="text" name="MyModelObjects[1].Value" />
</div>
<div><a href="#" id="addItem">Add another item</a></div>

在某些情况下,我还有 javascript(由上面标记中的锚链接触发),它将克隆模板输入部分,修改名称以填充索引值,以及将其添加到 DOM。通过这种方式,用户可以动态地将记录添加到视图中。

根据您处理模型的方式,您还可以传入具有 IEnumerable 属性的 ViewModel。视图的类型会改变,但从根本上来说视图的设计不会改变。

更新
使用上面的示例,下面是我用来添加项目的 jQuery 代码的快速片段。我假设这是一个插入,但如果您也想支持这种类型的编辑界面,请注意注释。

首先,我设置了一个模板。虽然这可以完全用 jQuery 构建,但我发现更容易进行标记和操作名称。

<div id="templateDiv" style="display: none;">
    <input type="hidden" name="MyModelObjects.Index" value="0T" />
    Name: <input type="text" name="MyModelObjects[0T].Name" /><br />
    Value: <input type="text" name="MyModelObjects[0T].Value" />
</div>

您还可以在其中指定 ID...这可能是一个很好的做法,但为了简洁起见,我将在示例中省略它。

这样,您就可以按如下方式设置 jQuery 函数:

var currentIndex = 1 // if you were using this for editing, this would be dynamically set to the number of items you have
var doAddItem =
    function() {
        currentIndex++;
        var newItem = $("#templateDiv").clone();
        newItem.attr("id", "item" + currentIndex); // reset the ID here
        newItem.find("input[name=MyModelObjects.Index]").val(currentIndex);
        newItem.find("input[name$=.Name]").attr("name", "MyModelObjects[" + currentIndex + "].Name");
        newItem.find("input[name$=.Value]").attr("name", "MyModelObjects[" + currentIndex + "].Value");
        newItem.insertBefore($(this).closest("div")); // insert it before the div containing the add link...adjust appropriate to your layout
        return false;
    }

$(document).ready(function() {
    $("#addItem").click(doAddItem);
    // In a real-world app you'd probably want to have a delete option, too
});

UPDATE 2
那里有一点错误 - 如果您的视图输入到 IEnumerable那么您的字段名称最终将只是 Index[0 ].名称 / [0].值。在我的实际应用程序中,我使用的视图模型具有一个本身就是可枚举的属性,因此我实际上将页面键入为 。在上面的示例中,该视图模型对象将具有一个名为 MyModelObject 的属性,该属性将是一个可枚举的(更实际地称为 MyModelObjects 复数)。

I haven't used EF yet, but I have a similar requirement on our site. I accomplished it by specifying the View as inheriting System.Web.Mvc.ViewPage<IEnumerable<MyModelObject>> then use a for loop to build multiple input sections, utilizing the naming conventions required to allow the model binder to build the enumerable.

I prefer to create a view model with a property that is an enumerable (see update 2 below). In this example we could say it would be the MyViewModel object with an IEnumerable<MyModelObject> property called MyModelObjects. In this case, the view would play out as follows...

Specifically, make sure to include for each input section a hidden field named MyModelObjects.Index, then have your property inputs named MyModelObjects[0].MyProperty, where the value of the Index hidden field corresponds to the array index in the property names.

What you would end up with would look like this, for example:

<div>
    <input type="hidden" name="MyModelObjects.Index" value="0" />
    Name: <input type="text" name="MyModelObjects[0].Name" /><br />
    Value: <input type="text" name="MyModelObjects[0].Value" />
</div>
<div>
    <input type="hidden" name="MyModelObjects.Index" value="1" />
    Name: <input type="text" name="MyModelObjects[1].Name" /><br />
    Value: <input type="text" name="MyModelObjects[1].Value" />
</div>
<div><a href="#" id="addItem">Add another item</a></div>

In some cases I also have javascript (triggered by the anchor link in the markup above) that will clone a template input section, modify the names to populate the index value, and add it to the DOM. In this way users can dynamically add records to the view.

Depending on how you are handling your models, you may also pass in a ViewModel that has a property that is IEnumerable. The typing for the view would change, but fundamentally the design of the view wouldn't.

UPDATE
Using the example above, here's a quick snippet of the jQuery code I use to add items. I'm assuming this is an insert, but note the comments if you wanted to support this type of interface for editing as well.

First, I set up a template. While this could be built totally in jQuery, I just find it easier to do the markup and manipulate the names.

<div id="templateDiv" style="display: none;">
    <input type="hidden" name="MyModelObjects.Index" value="0T" />
    Name: <input type="text" name="MyModelObjects[0T].Name" /><br />
    Value: <input type="text" name="MyModelObjects[0T].Value" />
</div>

You can also specify IDs in there...probably a good practice, but in the interest of brevity I'll leave it out for the example.

With that, you can set up the jQuery function as follows:

var currentIndex = 1 // if you were using this for editing, this would be dynamically set to the number of items you have
var doAddItem =
    function() {
        currentIndex++;
        var newItem = $("#templateDiv").clone();
        newItem.attr("id", "item" + currentIndex); // reset the ID here
        newItem.find("input[name=MyModelObjects.Index]").val(currentIndex);
        newItem.find("input[name$=.Name]").attr("name", "MyModelObjects[" + currentIndex + "].Name");
        newItem.find("input[name$=.Value]").attr("name", "MyModelObjects[" + currentIndex + "].Value");
        newItem.insertBefore($(this).closest("div")); // insert it before the div containing the add link...adjust appropriate to your layout
        return false;
    }

$(document).ready(function() {
    $("#addItem").click(doAddItem);
    // In a real-world app you'd probably want to have a delete option, too
});

UPDATE 2
There's a bit of an error up there - if your view is typed to an IEnumerable<object> then your field names will end up just being Index and [0].Name / [0].Value. In my actual app I use a view model that has a property that is itself an enumerable, so I actually type my pages as <MyViewModelObject>. In the example above, that view model object would have a property called MyModelObject, which would be an enumerable (and more realistically called MyModelObjects plural).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文