【问题标题】:Model binding issue in Release mode发布模式下的模型绑定问题
【发布时间】:2015-01-07 15:05:44
【问题描述】:

我发现我们的一个 WebAPI 项目出现了一些奇怪的行为。其中一个资源有一个接受复杂 .Net 对象的 POST 操作,其中一个属性是这样的枚举:

public class MyComplexClass {
  public string Prop1 { get; set; }
  public MyEnum Val { get; set; }
}

public enum MyEnum {
   Val1,
   Val2
}

当我从另一个 .Net 项目调用此端点时,只要我的 WebAPI 项目已在 Debug 模式下编译和部署,它就可以正常工作。在我以 Release 模式编译它的那一刻,模型绑定开始表现得很奇怪。我的MyEnum 的值始终为Val1,即使我传入Val2 或1。我似乎无法解释这里发生了什么并且已经没有想法了。

编辑 我有一个助手可以序列化对象并将它们添加到正文并调用 WebAPI。我称之为类似于这样的东西:

client.Post<MyComplexClass, bool>(new MyComplexClass() { Prop1="Hello"; Val=MyEnum.Val2});

我在项目之间共享模型,并且在这种情况下,当我序列化它并在我的 Action 方法中接受它作为参数时,我使用相同的模型 MyComplexClass

[HttpPost]
public bool UpdateUserPassword(MyComplexClass request)
{
    Log(request.Val);
}

request.Val 的值根据是Debug还是Release模式编译不同。对于发布,它总是Val1 我猜是因为它被默认为 0 并将其解释为Val1

【问题讨论】:

  • 奇怪的问题,但我认为我们需要MCVE 来提供帮助。
  • 您是否尝试过跟踪服务以查看实际传递的内容。
  • 调用者将正文中完全相同的一组值传递给 WebAPI。但是 WebAPI 似乎读取了枚举为 0 的属性,因此将其设置为 Val1。
  • 你能举个例子吗?
  • 你有没有试过看看当你通过 fiddler 调用端点时会发生什么?

标签: c# .net asp.net-mvc asp.net-mvc-4 asp.net-web-api


【解决方案1】:
  1. 看看电线上实际发出了什么。使用浏览器测试工具或提琴手。
  2. 为了帮助诊断:显式初始化您的枚举并包含默认的0 值。 None=0,Val1=1,Val2=2 这将有助于确定它是绑定层、序列化层还是传输层(在您的应用程序内部,但在您的控制范围之外,如 asp.net 或 iis)。

如果看起来不错:

  1. 比较已安装和加载的程序集和版本,从开发到生产。
  2. 比较 web.config 文件。
  3. 比较 machine.config 文件
  4. 验证预期已部署的程序集是否已实际部署。
  5. 确保 prod 指向部署目标

【讨论】:

  • 除了我比较过的 machine.config 之外的所有这些。他们都是一样的。明显的区别是 Debug 和 Release 模式下的 dll 大小。除此之外,一切似乎都完全一样。
  • 包括通过网络发送的内容?发送的实际值?
  • 您是否从 prod 中复制了程序集并对其进行反汇编以比较这些代码段?
  • @Maslow OP 已经声明是 WebAPI 改变了它的配置而不是客户端,所以发送的数据不能不同。
  • @Maslow 是的,我已经反汇编比较过,它们还是一样的。
【解决方案2】:

因为你没有使用 WebAPI2,it's safe to assume 枚举值在 WebAPI 端没有被正确解析。为什么解析在调试模式下工作,但在同一台机器上不在发布模式下,这很奇怪。您可以尝试将枚举值作为字符串传递,然后执行Enum.Tryparse

public class MyComplexClass 
{
    public string Prop1 { get; set; }
    public string Val { get; set; }
}

在你的控制器中

[HttpPost]
public bool UpdateUserPassword(MyComplexClass request)
{
     MyEnum myenum = MyEnum.Val1; 
     if(Enum.Tryparse(request.Val,true, out myenum)
     {
          Log(myenum);
     }
     else
     {
          // invalid enum value POSTed
     }
}

【讨论】:

  • 我尝试了类似的方法。我尝试了 int,它总是得到一个 0。不确定 string 是否有帮助,但会试一试。
猜你喜欢
  • 2017-04-13
  • 2014-01-31
  • 1970-01-01
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多