Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何让后期操作方法将原始viewmodel的子对象作为参数?_C#_Asp.net Mvc_Viewmodel - Fatal编程技术网

C# 如何让后期操作方法将原始viewmodel的子对象作为参数?

C# 如何让后期操作方法将原始viewmodel的子对象作为参数?,c#,asp.net-mvc,viewmodel,C#,Asp.net Mvc,Viewmodel,这是我的模型: public class IndexViewModel { public FilterConditions conditions { get; set } public IEnumerable<SelectListItem> Countries { get; set } } public class FilterConditions { public string condition11 { get; set } // ... }

这是我的模型:

public class IndexViewModel
{
    public FilterConditions conditions { get; set }
    public IEnumerable<SelectListItem> Countries { get; set }
}

public class FilterConditions
{
    public string condition11 { get; set }
    // ...
}
该视图以filterconditions作为输入类型呈现窗体

现在,我希望通过以下操作方法处理来自该表单的帖子:

[HttpPost]
public ActionResult Index(FilterConditions model)
{
    // do some magic with model and return another view here
}
这实际上是可行的,我在方法中放了一个断点,然后调用它,但是我的模型的属性总是空的默认值,而它们应该包含表单发布的值

当我修改动作方法时,如下所示:

[HttpPost]
public ActionResult Index(IndexViewModel model)
{
    // do some magic with model.conditions and return another view here
}
[HttpPost]
public ActionResult Index(FilterConditions filterConditions)
{
    // do some magic with model and return another view here
    // now the filterConditions variable actually contains values!
}
这一切都像它应该的那样工作,但这不是正确的IMHO,因为我不需要返回的“国家”列表,我只需要选择的国家,这是条件之一

在不必将整个原始viewmodel作为输入参数的情况下,实现此功能的最佳实践方法是什么

顺便说一句,我使用的是ASP.NET MVC 2,我认为这并不重要,因为我认为MVC 3中也存在同样的问题,但我不能完全确定这一点

我一直在互联网上寻找关于asp.net mvc中DropDownList和viewmodels的最佳实践,但我发现不同的建议并不完全一致,很多建议也已经过时。我没有找到官方的最佳实践。我希望我正在朝着正确的方向前进,将列表作为我的viewmodel的一部分,如果我没有这样做,请随时纠正我的错误。如果您知道任何关于这方面的最佳实践,请随时向我指出

更新:

我发现我可以使用带有filterconditions前缀的[Bind]属性。这确实适用于这种观点。但我承认我原来的问题,它并没有包括在我的问题并没有解决


碰巧,这个特定的操作方法也从另一个视图调用。这是一个ajax调用,它没有前缀,在这种情况下,它现在不再工作了。有什么建议吗?

嗨,fretje:现在我可以用你的方式来解决你的问题,首先我有两个模型IndexViewModel&Index,DropDownlit不重要,只提供下拉项:

public class IndexViewModel : Index
{
   //public  int value { get; set; }
   public   List<System.Web.Mvc.SelectListItem> items { get; set; }
}

public class Index
{
    public int value { get; set; }
}


class DropDownList
{
   public List<System.Web.Mvc.SelectListItem> GetDropDownList()
   {
       List<System.Web.Mvc.SelectListItem> result = new List<System.Web.Mvc.SelectListItem>();
       result.Add(new System.Web.Mvc.SelectListItem
       {
           Value = "1",
           Text = "Apple"
       });
       result.Add(new System.Web.Mvc.SelectListItem
       {
           Value = "2",
           Text = "Milk"
       });
       return result;
   }
}
测试的观点是:

<% using (Html.BeginForm()) {%>
    <%: Html.ValidationSummary(true) %>        
    <fieldset>
        <legend>Fields</legend>            
        <div class="editor-field">
                    <%: Html.DropDownListFor(m=>m.value, Model.items )%>
        </div>            
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
<% } %>
嗨~ 您不需要将整个SelectListItem组合到ViewModel,实际上您的ViewModel只有一个字段来存储用户的选项、整数或字符串,然后使用DropDownList进行类似操作:

<%: Html.DropDownListFor(item.WeaponID, MyApplication.Models.DropDownList.GetDropDownList() )%>
请看我在blogspot上的帖子,我用一个非常简单的例子来解释:


如果您有任何问题,请告诉我:

我找到了解决方案

显然,当我对参数变量使用与类型名称相同的名称时,大小写不必匹配,如下所示:

[HttpPost]
public ActionResult Index(IndexViewModel model)
{
    // do some magic with model.conditions and return another view here
}
[HttpPost]
public ActionResult Index(FilterConditions filterConditions)
{
    // do some magic with model and return another view here
    // now the filterConditions variable actually contains values!
}
如果我的filterConditions的值不再为空/null,一切都会正常工作。显然,默认modelbinder使用参数的名称作为绑定的潜在前缀

我很高兴我发现了这一点,但如果能在某个地方更清楚地记录下来,那就太好了。这一点都不明显

编辑: 请求时:这是我的视图aspx中的代码:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyProject.Models.IndexViewModel>" %>

<%-- ... more stuff here ... --%>

<% using (Html.BeginForm())
   {%>
    <%= Html.ValidationSummary(true)%>

    <fieldset>
        <div class="editor-label">
            <%= Html.LabelFor(model => model.FilterConditions.Country)%>
        </div>
        <div class="editor-field">
            <%= Html.DropDownListFor(model => model.FilterConditions.Country, Model.Countries)%>
            <%= Html.ValidationMessageFor(model => model.FilterConditions.Country)%>
        </div>

        <div class="editor-label">
            <%= Html.LabelFor(model => model.FilterConditions.Make)%>
        </div>
        <div class="editor-field">
            <%= Html.TextBoxFor(model => model.FilterConditions.Make)%>
            <%= Html.ValidationMessageFor(model => model.FilterConditions.Make)%>
        </div>

        <%-- ... more fields inserted here ... --%>

        <p>
            <input type="submit" value="  Search...  " />
        </p>
    </fieldset>

<% } %>

据我所知,最佳实践是控制器应收集所有数据并将其传递给视图。在您的示例中,视图本身正在查询模型。我认为在ASP.NET MVC中,这不是正确的做法。您也可以同时传递两个模型进行查看,一个是我们的视图模型,另一个是列表模型,这很好。@Maidot:这正是我的问题。要传递这两个模型,在我的例子中,您必须将它们封装在包装类DefaultViewModel中,这样我的模型实际上是DefaultViewModel的子对象。对不起,我太笨了:,您尝试过[BindExclude=blah]吗。但我不确定这是否是您想要的,因为它可能会将所有信息传递给服务器端。@Maidot:我想要的是将DefaultViewModel作为我的操作方法的参数去掉。所以排除不是我需要的。虽然我发现我可以使用前缀,但后来我遇到了另一个问题,请看我更新的问题。听起来你想用两种方式来称呼它。。。也许您可以在每种方式中使用一个参数,并根据设置的值选择要使用的参数。您是使用AjaxForm进行ajax调用还是使用jQuery ajax?@nEEbz:我使用jQuery ajax,但这并不重要,因为我也有不使用ajax的问题。我发现这有点难以理解。对于public ActionResult IndexIndexViewModel模型,您是否尝试只发送筛选条件而不发送国家/地区?我认为模型绑定器只会智能地绑定FilterConditions条件,并将国家列表保留为空。@nEEbz:我只发送条件。这实际上是通过发布表单自动完成的,由于表单上的字段仅来自筛选条件,模型的其他字段将填充我的下拉列表,因此仅发送这些字段。我的问题是,如果我只将FilterConditions模型指定为action方法的参数,则默认的模型绑定器不会将它们解析到模型对象中。它确实起作用
当我指定FilterConditions时,FilterConditions可以看到我的答案。您更改了参数的名称,它开始工作了吗?我可能很烦人,你能给我们看一下你的表单/视图吗?它包含过滤条件元素。只是为了我们的学习目的。我一直认为模型绑定器使用name属性将元素绑定到控制器参数名称。@nEEbz:好了。更新了我的答案。
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyProject.Models.IndexViewModel>" %>

<%-- ... more stuff here ... --%>

<% using (Html.BeginForm())
   {%>
    <%= Html.ValidationSummary(true)%>

    <fieldset>
        <div class="editor-label">
            <%= Html.LabelFor(model => model.FilterConditions.Country)%>
        </div>
        <div class="editor-field">
            <%= Html.DropDownListFor(model => model.FilterConditions.Country, Model.Countries)%>
            <%= Html.ValidationMessageFor(model => model.FilterConditions.Country)%>
        </div>

        <div class="editor-label">
            <%= Html.LabelFor(model => model.FilterConditions.Make)%>
        </div>
        <div class="editor-field">
            <%= Html.TextBoxFor(model => model.FilterConditions.Make)%>
            <%= Html.ValidationMessageFor(model => model.FilterConditions.Make)%>
        </div>

        <%-- ... more fields inserted here ... --%>

        <p>
            <input type="submit" value="  Search...  " />
        </p>
    </fieldset>

<% } %>