5

在 Youtube API 中,可以请求“部分供稿”

这允许应用程序开发人员通过指定要返回的“字段”来定制返回数据的大小和结构。

即将返回一个仅包含和字段GET api/person/1?fields=(id,email)的 DTO ,而不是整个人的响应。idemail

您将如何使用 ServiceStack 尝试此操作?是否有某种方法可以将回调附加到序列化程序以控制要包含在响应对象中的属性?

4

4 回答 4

1

根据我的经验,servicestack 只返回实际包含数据的字段。如果我的经验是正确的,那么您需要做的就是找出构建请求的最佳方法,以便它要求返回特定的数据,这样您就只会用请求的数据填充响应,因此 servicestack 只会返回那个.

于 2013-02-08T12:04:51.370 回答
1

我为只返回 JSON 的 API 实现了这一点。

首先,我创建了两个结构来(反)序列化和解释“字段”查询参数递归语法:

  • FieldSelector,它指定了一个字段以及可能FieldSelection包含在括号之间的子项;
  • FieldsSelection,这是一个逗号分隔的列表FieldSelector

我使用了结构而不是类,因为根据 AFAIK,您无法覆盖 ServiceStack 中从/到 URL 的类(反)序列化。使用结构,您可以通过覆盖ToString(序列化程序)并提供一个接受字符串作为参数的构造函数(反序列化程序)来实现。

然后在每个返回 JSON 的请求 DTO 中包含它:

FieldsSelection Fields { get; set; }

在自定义上ServiceRunner<T>.OnAfterExecute,您将响应 DTO 序列化为 JSON,使用 ServiceStack.Text 解析它,JsonObject并使用如下方法递归应用字段选择:

private static JsonObject Apply(this JsonObject json, FieldsSelection fieldMask)
{
  IEnumerable<string> keysToRemove = json.Keys.ToList().Except(fieldMask.Keys);

  foreach (var key in keysToRemove)
    json.Remove(key);

  foreach (var selector in fieldMask.Selectors.Values.Where(s => s.HasSubFieldsSelection))
  {
    var field = json[selector.Field];
    if (field == null)
      continue;

    switch (field[0])
    {
      case '{':
        json[selector.Field] = Apply(json.Object(selector.Field), selector.SubFieldsSelection).ToJson();
        break;
      case '[':
        var itensArray = json.ArrayObjects(selector.Field);
        for (int i = 0; i < itensArray.Count; i++)
          itensArray[i] = Apply(itensArray[i], selector.SubFieldsSelection);
        json[selector.Field] = itensArray.ToJson();
        break;
      default:
        throw new ArgumentException("Selection incompatible with object structure");
    }
  }

  return json;
}

然后将结果作为响应 DTO 返回。我还实现了负字段选择器(fields=-foo选择除 foo 之外的所有 DTO 字段),但您明白了。

于 2014-05-22T23:40:25.440 回答
0

查看ServiceStack.Text.JsConfig属性,它们具有 ServiceStack 的文本序列化程序支持的所有钩子和自定义项。具体来说,允许您自定义反序列化的钩子是:

JsConfig<T>.DeserializeFn 
JsConfig<T>.RawDeSerializeFn 
JsConfig<T>.OnDeserializedFn
于 2013-02-08T15:52:41.560 回答
0

我们能够通过添加自定义服务运行器并在其中使用一些反射来构建ExpandoObject由响应 DTO 设置的必填字段来实现所述过滤。有关服务运行器的更多信息,请参阅此内容。

于 2013-07-15T10:36:43.670 回答