1

当我在调试器中运行测试时,我的 ApiController 方法有时会收到空参数。但是,如果我触摸控制器文件并重新构建它,它可以在相同的测试中正常工作。一切都是一样的,只是它重新编译了 Web Api 项目的 DLL。我打开了跟踪,但除了参数是否为空之外,它什么也没告诉我。这怎么可能发生?

我猜它无法将 JSON 对象反序列化为参数类型,但我该如何解决这个问题?

编辑:添加代码

此方法有时会收到 value=null

public FilterItem Post(uint jobId, uint columnID, FilterItemDTO value)
    {
        // save a new FilterItem
    }

FilterItemDTO 是我创建的一个 DTO 类,只是因为 FilterItem 类有一堆不需要的继承字段,我无法在基类中对它们进行注释:

public class FilterItemDTO
{
    public uint Id;
    public uint ColumnID { get; set; }
    public FilterItem.FilterType Type;
    public string Value;

    //Date/Time Stamps
    public DateTime? CreatedDate = null;
    public string CreatedBy = null;
    public DateTime? ModifiedDate;
    public string ModifiedBy = null;
    public int FilterLevel = 0;

    public FilterItemDTO(FilterItem f)
    {
        Id = f.ID;
        ColumnID = f.ColumnID;
        Type = f.Type;
        Value = f.Value;
        FilterLevel = f.FilterLevel;
        CreatedDate = f.CreatedDate;
        CreatedBy = f.CreatedBy;
        ModifiedDate = f.ModifiedDate;
        ModifiedBy = f.ModifiedBy;
    }

    internal static FilterItem ToFilterItem(FilterItemDTO value)
    {
        FilterItem f = new FilterItem(value.Type, value.Value, value.FilterLevel);
        f.ID = value.Id;
        f.ColumnID = value.ColumnID;
        f.CreatedDate = value.CreatedDate;
        f.CreatedBy = value.CreatedBy;
        f.ModifiedDate = value.ModifiedDate;
        f.ModifiedBy = value.ModifiedBy;

        return f;
    }

    public FilterItem ToFilterItem()
    {
        return FilterItemDTO.ToFilterItem(this);
    }
}

这是我发送的请求(从 Fiddler 便笺簿复制)

POST http://localhost:56875/api/job/4513/column/21213/filter HTTP/1.1
Host: localhost:56875
Connection: keep-alive
Content-Length: 28
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://localhost:56875
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Content-Type: application/json
Referer: http://localhost:56875/Content/test.htm
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

{"type":"Equal","value":"1"}

这是我的格式化程序配置。type:"Equal" 值应该使用 StringEnumConverter 自动转换。

 public class FormatterConfig
{
    public static void RegisterGlobalFormatters(MediaTypeFormatterCollection formatters)
    {
        var jsonSerializerSettings = formatters.JsonFormatter.SerializerSettings;
        jsonSerializerSettings.Converters.Add(new IsoDateTimeConverter());

        // serialize every enum as a string
        jsonSerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());

        // include null value fields
        jsonSerializerSettings.NullValueHandling = NullValueHandling.Ignore;

        // use camel case
        jsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

        // indented formatting
        formatters.JsonFormatter.Indent = true;

        formatters.Remove(formatters.XmlFormatter);
    }
}
4

1 回答 1

1

我会先尝试隔离问题:

  • 注释掉一个控制器中除了一种方法之外的所有内容,看看它是否仍然受到影响

  • 对每个单独的方法做同样的事情

  • 如果它们孤立地很好,那么这意味着方法可能没有明确分开,也许有时 WebApi 选择了错误的方法(因为缺少属性或其他原因)

  • 如果它们仍然失败,并且失败仍然是随机的,我会检查是否有任何不可靠的对象传入 - 尝试使用 fiddler 多次重播请求并检查它们在失败时的差异(参数、cookie、接受/内容类型标头ETC。)

  • 从 app_start 调试,如果需要,可以多次调试——你可能很清楚你的失败模式,继续调试看看请求之间发生了什么变化

  • 检查是否有任何方法/测试没有以任何其他方式覆盖应用程序的任何配置/更改状态

  • 尝试从你的对象中删除复杂的属性,只保留原始类型,看看是否有帮助(如果有,这意味着类型的序列化可能存在问题(例如与继承相关))

  • 更改序列化程序

如果这些都没有帮助,请发布一些代码。

于 2013-04-18T19:24:28.213 回答