.net - ASP.NET MVC Posted Model 丢失接口(interface)属性值并且 ModelState 有错误。模型绑定(bind)限制?序列化问题?

标签 .net asp.net-mvc serialization model-binding modelstate

通过以下简单操作...

[HttpPost]
public PartialViewResult DoSomething(AnimalInfo animalInfo)
{
    // animalInfo.AnimalKey SHOULD == DogKey { Id = 1, Name = "Dog" }
    // BUT animalInfo.AnimalKey == null

    return Something();
}

发布到这个 Action 很好,大多数 animalInfo 的属性都可用,除了我自己创建的对象。我假设这是一个序列化问题,所以我在我的类中添加了一些基本的序列化,但我仍然得到 AnimalKey 对象的 null(在渲染时绝对不为 null)。

这是我定义 AnimalInfo 的方式:

[DataContract]
public class AnimalInfo : IAnimalInfo
{
    [DataMember]
    public IAnimalKey AnimalKey { get; set; }

    public string Name { get; set; }
}

[DataContract]
public class DogKey : IAnimalKey
{
    public DogKey(int id){ DogId = id; }

    [DataMember]
    public int DogId { get; set; }
}

然后我从这样的 View 发布到操作...

<% var currentAnimal = new AnimalInfo { AnimalKey = new DogKey(1), Name = "Dog" }; %>
<% using (Html.BeginForm("DoSomething", "Controller", currentAnimal.AnimalInfo))
{
    %><button type="submit">post</button><%
} %>

但是当我的 Action 被执行时,AnimalKey 已经变为 null,而 Name 是“Dog”。查看 ModelState 会发现相同的结果。它看起来像是一个序列化问题。是这样吗?如果是这样,DataContract 和 DataMember 是否不足以作为处理此问题的方法?


更新

作为替代方法,我尝试将其更改为强类型 View 并使用 HiddenFor 发布数据,但我仍然得到完全相同的结果。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Namespace.IAnimalInfo>" %>

<% using (Html.BeginForm("DoSomething", "OM", Model))
{
    Html.HiddenFor(m => m.AnimalKey);
    Html.HiddenFor(m => m.Name);
    %><button type="submit">revert</button><%
} %>
  • MVC HtmlHelpers 根本不序列化复杂对象吗?

  • 或者我是否需要为每个 AnimalKey 创建不同的模型才能取回这些值?

  • 或者甚至将我自己的序列化为隐藏的字符串,然后在返回时反序列化它?


可能的原因

经过更多的调整后,我很确定这是因为 IAnimalKey 是一个接口(interface)。当我将另一个名为 DogKey 的属性添加到我的模型时,该值被返回。所以它似乎不知道它是什么类型的对象,或者根本不支持接口(interface)。


脏修复

看我的回答

最佳答案

尚未收到特定问题的任何答案,可能是因为 ASP.NET MVC 不支持它,但我在 MSDN 上也找不到任何确认信息。因此,由于缺乏更好的答案,这是我的肮脏修复。基本上,我将 AnimalInfo 变成了一个抽象类,并实现了我称之为 Serialize 和 Deserialize 的方法,这些方法将每个 AnimalKey 转换为一个字符串,可用于稍后重新创建 AnimalKey。

这是有效的,因为在我用作 MVC 模型的新 AnimalInfo 类中,我有一个 SerializedKey 的属性,它在 Get 上尝试序列化 AnimalKey。使用 HtmlHelper 存储此属性将导致 Get 执行序列化,将产品存储在呈现的 View 中。 Set 方法将尝试将提供的字符串反序列化为 AnimialKey。因此,当发生 Post Action 时,MVC 会尝试设置 SerializedAnimalKey 并通过这样做调用 Deserialize 并使用我打算序列化的所有内容重新创建 AnimalKey 对象。

很想看到这个特定问题的其他答案,但现在这是我必须要做的。

public abstract class AnimalKey
{
    public abstract AnimalType AnimalType { get; }
    public abstract string Serialize();

    public static AnimalKey Deserialize(string serializedKey)
    {
        var split = serializedKey.Split('|');
        switch ((AnimalType)Convert.ToInt32(split[0]))
        {
            case AnimalType.Dog:
                var dogKey = new DogKey();
                var dogProperties = split[1].Split(',');
                dogKey.DogId = Convert.ToInt32(dogProperties[0]);
                return dogKey;
            // TODO: Other key implementations
        }
    }
}

public class AnimalInfo : IAnimalInfo
{
    public AnimalKey AnimalKey { get; set; }

    public string SerializedAnimalKey 
    {
        get { return AnimalKey != null 
            ? AnimalKey.Serialize() 
            : string.Empty;
        }
        set { AnimalKey = String.IsNullOrEmpty(value) ? null : AnimalKey.Deserialize(value); }
    }       
}

public class DogKey : AnimalKey
{
    [DataMember]
    public int DogId { get; set; }

    public override AnimalType AnimalType
    {
        get { return AnimalType.Dog; }
    }

    public override string Serialize()
    {
        var serializeBuilder = new StringBuilder();
        serializeBuilder.AppendFormat("{0}|", (int)AnimalType);
        serializeBuilder.AppendFormat("{0},", DogId);

        return serializeBuilder.ToString();
    }
}

关于.net - ASP.NET MVC Posted Model 丢失接口(interface)属性值并且 ModelState 有错误。模型绑定(bind)限制?序列化问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9520531/

相关文章:

c# - MediatR 不处理逆变通知

.net - Microsoft.Data.Tools.Schema.Sql.UnitTesting 程序集的程序集冲突解决

asp.net - .MSPX 文件扩展名是什么?

javascript - 是否可以切换到以前打开的选项卡而不是打开新选项卡?

asp.net-mvc - ASP.NET MVC 3 文件下载 : Not Working in IE8

asp.net-mvc - TS > 2.2 的 knockout Typescript 定义错误

hibernate - 如何在序列化过程中限制hibernate相关对象

.net - 为什么在 Web.config 中将 subStatusCode 设置为 -1?

c# - 在存储到 Redis 之前是否使用 protobuf-net 序列化原语

python - 序列化 Django 模型对象 : Referencing to self