public T ContentAs <T>() { EnsureNotDisposed(); //basic GET or other non-projection operation if (OpCode == OpCode.Get || OpCode == OpCode.ReplicaRead || OpCode == OpCode.GetL || OpCode == OpCode.GAT) { _logger.LogDebug("using the {transcoder} Transcoder.", _transcoder.GetType()); return(_transcoder.Decode <T>(_contentBytes.Memory, Flags, OpCode)); } //oh mai, its a projection ParseSpecs(); // normal GET if (_specs.Count == 1 && _projectList?.Count == 0) { var spec = _specs[0]; return(_transcoder.Decode <T>(spec.Bytes, Flags, OpCode.Get)); } var root = new JObject(); foreach (var spec in _specs) { //skip the expiry if it was included; it must fetched from this.Expiry if (spec.Path == VirtualXttrs.DocExpiryTime) { continue; } var content = _serializer.Deserialize <JToken>(spec.Bytes); if (spec.OpCode == OpCode.Get) { //a full doc is returned if the projection count exceeds the server limit //so we remove any non-requested fields from the content returned. if (_projectList?.Count > 16) { foreach (var child in content.Children()) { if (_projectList.Contains(child.Path)) { root.Add(child); } } //root projection for empty path return(root.ToObject <T>()); } } var projection = CreateProjection(spec.Path, content); try { root.Add(projection.First); } catch (Exception e) { //these are cases where a root attribute is already mapped //for example "attributes" and "attributes.hair" will cause exceptions _logger.LogInformation(e, "Deserialization failed."); } } if (root.Path == string.Empty && typeof(T).IsPrimitive) { return(root.First.ToObject <T>()); } return(root.ToObject <T>()); }