做一个HTTPPOST MVC2

时间:2011-04-06 10:33:03

标签: c# asp.net-mvc-2 http-post

我有一个MVC2应用程序。在这个应用程序中,我有一个强大的视图竞争模式NewHorseModel:

public class NewHorseModel
{
    public List<Category> Faehigkeit { get; set; }
}

public class Choice
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Beschreibung { get; set; }
    public bool Selected { get; set; }
}

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Beschreibung { get; set; }
    public List<Category> Subcategories { get; set; }
    public List<Choice> Choices { get; set; }
    public int Parent { get; set; }
}

View看起来像这样:

<p>
    <input faehigkeit_ID="1" id="Selected" name="Selected" type="checkbox" value="true" />
    <input name="Selected" type="hidden" value="false" />
    Mitteltrab
    <input id="Id" name="Id" type="hidden" value="1" />
</p>
<p>
    <input faehigkeit_ID="2" id="Selected" name="Selected" type="checkbox" value="true" />
    <input name="Selected" type="hidden" value="false" />
    Arbeitstrab
    <input id="Id" name="Id" type="hidden" value="2" />
</p>
<p>
    <input faehigkeit_ID="3" id="Selected" name="Selected" type="checkbox" value="true" />
    <input name="Selected" type="hidden" value="false" />
    Trab versammelt
    <input id="Id" name="Id" type="hidden" value="3" />
</p>
<p>
    <input faehigkeit_ID="11" id="Selected" name="Selected" type="checkbox" value="true" />
    <input name="Selected" type="hidden" value="false" />
    Trab
    <input id="Id" name="Id" type="hidden" value="11" />
</p>

视图的创建方式如下: Categories and Subcategories MVC2

现在我想做一个帖子,但是如何获取数据? 当我做这样的帖子时:

[HttpPost]
public void myAction(NewHorseModel newHorseModel)
{
    // ...
}

NewHorseModel中的Faehigkeit为空

这是我的ASPX代码:

<div id="Div2">
    <%
    foreach (Category item2 in Model.Faehigkeit)
    {
        Html.RenderPartial("Faehigkeit", item2);
    }
    %>
</div>

部分视图类别(强类型模型类别):

<%
if (Model.Choices != null)
{
    foreach (var item in Model.Choices)
    { 
        Html.RenderPartial("Choice", item);
    }
}
if (Model.Subcategories != null)
{
    foreach (var item in Model.Subcategories)
    {
        Html.RenderPartial("Faehigkeit", item);
    }
}
%>

andviewview Choices(strongtyped model choice)

<p>
    <%: Html.CheckBoxFor(m => m.Selected, new { faehigkeit_ID = Model.Id }) %>
    <%: Model.Name %>
    <%: Html.HiddenFor(u=>u.Id) %>
</p>

更新 下一个测试: 在Faehigkeit.ascx部分我添加了这段代码:

     <input type="hidden"  name="Faehigkeit[<%=Model.Id%>].Id" value="<%=Model.Id%>" />
<input type="hidden" name="Faehigkeit[<%=Model.Id%>].Name" value="<%: Model.Name%>" />

在Choices.ascx部分我添加了以下代码:

<input type="checkbox" name="Faehigkeit[0].Choices[<%=Model.Id%>].Selected" />

我不需要知道哪个选项属于哪个类别。我必须知道检查哪个选择ID以及哪个不是。

HTML-Output如下所示:

  <input type="hidden"  name="Faehigkeit[1].Id" value="1" />
<input type="hidden" name="Faehigkeit[1].Name" value="Qualit&#228;t der Gangarten" />
<input type="hidden" name="Faehigkeit[1].Choices[4].Id" value="4" />
<input type="checkbox" name="Faehigkeit[1].Choices[4].Selected" />

我的控制器看起来像这样:  [HttpPost]

public ActionResult CreateNewHorse(NewHorseModel collection)
    {
        if (User.Identity.IsAuthenticated)
        {


            return View();
        }
        else
        {
            return View("Account/LogOn");
        }

    }

如果我试图获得“Faehigkeit”的价值 - &gt; “选择”每件事都是空的(“Faehigkeit”的名称,“Faehigkeit”的ID,没有选择 在debuging期间显示NewHorseModel内容的图像: http://i.stack.imgur.com/6yLZW.png

非常感谢!

2 个答案:

答案 0 :(得分:0)

通常,如果您将HttpPost作为动作的属性,则其类似于:

[HttpPost]
public void myAction(NewHorseModel newHorseModel)
{;}

然后把类类型作为你的参数,为你自动绑定它,如果有什么需要做的疯狂,或者从外部非ASP页面发布到这个动作你可以只需使用FormCollection(我认为)作为您的参数,这是一个包含所有元素和值的美化词典。

答案 1 :(得分:0)

我写过2篇博文,可以解决您的问题:

  1. 如何将IList<T>发布到控制器操作上here,并指导您从头到尾,以便了解它的实际工作原理和原因。

  2. 由于您可能在客户端有复杂的JSON对象,并希望它们在您的操作方法中与服务器上的模型绑定(如您的情况),this post可能是这是一本有趣的读物。它解释了发送复杂JSON对象的问题,并提供了一个简单的jQuery插件,可以将客户端对象转换为一个很容易将数据绑定到强类型操作方法参数的表单。

  3.   

    注意:如Phil Haack所解释的,还有可能使用JsonValueProviderFactory,但该解决方案需要在客户端和服务器端进行更改(因为您正在使用MVC2)。

    根据您的代码

    您只提供了代码的某些部分(有些部分并不是真正相关的,但无论如何),我将对您的案例进行观察。

    您希望在服务器上建模的所有输入字段都需要具有正确的名称。从渲染的复选框名称中我们可以看出根本不是这种情况。

    根据您的模型,您的输入应该被命名为(不要介意输入类型,因为只有您知道应该呈现哪些类型以及哪种类型):

    <!-- erste fähigkeit -->
    <input name="Faehigkeit[0].Id" />
    <input name="Faehigkeit[0].Name" />
    <input name="Faehigkeit[0].Beschreibung" />
    <input name="Faehigkeit[0].Subcategories[0].Id" />
    <input name="Faehigkeit[0].Subcategories[0].Name" />
    ...
    <input name="Faehigkeit[0].Choices[0].Id" />
    <input name="Faehigkeit[0].Choices[0].Name" />
    <input name="Faehigkeit[0].Choices[0].Beschreibung" />
    <input name="Faehigkeit[0].Choices[0].Selected" />
    ...
    <input name="Faehigkeit[0].Choices[x].Id" /> <!-- "x" could be any number -->
    ...
    <input name="Faehigkeit[0].Parent" />
    <!-- zwite fähigkeit -->
    <input name="Faehigkeit[1].Id" />
    ...
    <!-- usw. -->
    

    基于这种复杂的层次模型,这种形式可能是巨大的。而且您可能不希望发送所有属性,因为您只需要一些相关的属性。但主要的是输入命名应该如上所述。

      

    非常重要:我应该指出索引(即。Faehigkeit[0])不应该与ID相关,而是数组/列表项索引。它们应该是连续的,因此它们应该总是从0开始并且应该增加1到最后 N 因此应该没有任何间隙。相信我,当我写博文时,我已经测试过了。否则,服务器上的模型绑定将失败。确保通过此要求!根据您编辑过的问题,情况并非如此,因为您输入的是ID而不是索引。

    如果您将数据作为JSON传输到客户端,则客户端上有一个对象:

    var data = {
        Faehigkeit: [
            {
                Id: 1,
                Name: "Some name",
                Beschreibung: "Some description",
                Subcategories: [
                    { ... },
                    { ... },
                    ...
                ],
                Choices: [
                    { ... },
                    { ... },
                    ...
                ]
            },
            { ... },
            ...
        ]
    };
    

    如果您的客户端视图直接操作此对象,则可以通过jQuery Ajax调用将其发送回服务器,即:

    $.ajax({
        type: "POST",
        url: "someController/myAction",
        data: $.toDictionary(data), // this is my jQuery plugin mentioned earlier
        success: function() { ... },
        error: function() { ... }
    });
    

    所以选择是你的,但在任何一种情况下,字段名称都应该是正确的,否则你的模型将不会被绑定到你的参数,你将无法使用它。

    您可以尝试<%= Html.EditorFor(m => m); %>,但这可能不是您想要使用的那种形式。在这种情况下,必须使用手动输入命名。或者您也可以编写一些自定义代码。

    其中一种方法是将部分视图模式类型转换为例如Tuple<string, Category>。字符串会告诉它string应该预先添加到你的字段名称。

    Html.RenderPartial("Faehigkeit", Tuple.New("Faehigkeit[0]", item2));
    

    然后当你继续前进时,应该总是添加以前的数据,这样你的子类别列表和他们受尊重的子对象将具有正确的输入表单名称。

    不好,但我认为这是制作它的唯一方法。