ASP.NET Model Binder忽略Bind(Exclude)和Bind(Include)并设置List<>为空

时间:2014-12-18 12:01:37

标签: c# asp.net asp.net-mvc entity-framework model-binding

我对ASP.NET Model Binder和(实体框架延迟加载)或忽略表单字段有问题...

重要的事情

型号Category

[Table("Category")]
public class Category
{
    public Category()
    {
        SellingRange = new Range();
        Products = new HashSet<Product>();
    }

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required, StringLength(100)]
    public string Name { get; set; }

    public Range SellingRange { get; set; }

    public virtual ICollection<Product> Products { get; set; }
}

型号Product

[Table("Product")]
public class Product
{
    public Product()
    {
        Categories = new HashSet<Category>();
    }

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required(ErrorMessage = "Name is required")]
    [StringLength(255, ErrorMessage = "Max length of name is 255.")]
    public string Name { get; set; }

    public virtual ICollection<Category> Categories { get; set; }
}

型号Range

public class Range
{
    public DateTime? Opening { get; set; }
    public DateTime? Closure { get; set; }
}

控制器发布操作:

[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public virtual ActionResult Edit(Category category, [Bind(Prefix = "SellingRange")] Range sellingRange, Guid[] products)
{
    category.SellingRange = sellingRange;

    // [...] ***********************************************************************************
}

从html表单提交数据:

Id=dd1e055d-f851-4880-a88a-cfa01e8b2cd6
Name=Test
SellingRange.Opening=01.12.2014
SellingRange.Closure=24.12.2014
products=79174475-5640-45ac-bb88-c983c4de5324
products=6fc64b68-e5f3-4ca3-9cf7-56237b16561a

查看:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Category>" %>
<%@ Import Namespace="stackoverflow.test" %>

<script type="text/javascript">
    $(function () {
        $('#products').tagsInput({ autocomplete_url: '<%= Url.Action("ProductsAC") %>' });
    });
</script>

<%= Html.HiddenFor(model => model.Id) %>
<%= Html.DisplayFor(model => model.Name) %>:<br />
<%= Html.TextBoxFor(model=> model.Name) %><br />    
<br />  
<%= Html.DisplayFor(model => model.Products) %>:<br />
<input name="products" id="products" value="<%= String.Join(",", Model.Products.Select(product => product.Name).toArray() %>" /><br />
<br />
<%= Html.DisplayFor(model => model.SellingRange.Opening) %>:<br />
<%= Html.JQueryUI().DatepickerFor(model => model.SellingRange.Opening).ToHtmlString() %><br />
<br />
<%= Html.DisplayFor(model => model.SellingRange.Closure) %>:<br />
<%= Html.JQueryUI().DatepickerFor(model => model.SellingRange.Closure).ToHtmlString() %>

顶视图:

using (Html.BeginForm("Edit", "Category", FormMethod.Post))
{
    %><% Html.RenderPartial("CategoryForm", Model); %><%
}

问题:

实体框架未在**************上方加载类别产品。 (在[...]之后)(在控制器中) 默认情况下,&#34;产品&#34;应该是new HashSet<Product>();。但是Model Binder制作了它们null。 我尝试在[Bind(Exclude="products")]前添加Category category。 - &GT;不工作! 然后我尝试包含一些重要的内容......在[Bind(Include="Id,Name")]前添加Category category。不工作了!

是否可以直接从post数组中添加ICollection<Products>,其中只包含产品中的GUID?那样就好了! :)

或者如何解决问题?我需要原始产品的完整产品清单。 类似于...... DbContext.Categories.Find(category.Id).Products,它不是空的;)

我不知道为什么Model Binder不能排除/包含产品并让它们成为new HashSet<Product>();。为什么Model Binder必须将产品设置为null?

在调试模式下,控制器中的category变量是一个类别的ProxyClass,除了产品之外,它是完全加载的(我认为)......

为什么我要拆分类别和产品

因为我检查了原始产品的产品,并在检查了我添加了Guid []列表的产品之后。在那里,我可以从数据库加载产品并将产品添加到列表中。你可以看看soldRange。销售范围由我添加,因为Model Binder无法将ComplexType绑定到Range-Class,因此我手动执行此操作。

这适用于DateTime? ...因为我不需要原始的销售范围...而且因为我不需要它们它可能是空的......但产品不应该!

提前致谢!

1 个答案:

答案 0 :(得分:0)

问题是深度嵌套的DefaultModelBinder ......我不知道有一个。

我有一个有效的Document,项目的ModelBinder用null覆盖所有内容。

自定义ModelBinder也会忽略[Bind(Exclude)]和Include! 因为我有这么多问题。

谢谢@Stephen Muecke。 现在绑定可以正确使用一个参数^^ 我优化了自定义ModelBinder:)