For serializing response just use any custom attribute on action and custom contract resolver (this is only solution, unfortunately, but I'm still looking for any more elegance one).  
Attribute:   
public class ReturnValueTupleAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        var content = actionExecutedContext?.Response?.Content as ObjectContent;
        if (!(content?.Formatter is JsonMediaTypeFormatter))
        {
            return;
        }
        var names = actionExecutedContext
            .ActionContext
            .ControllerContext
            .ControllerDescriptor
            .ControllerType
            .GetMethod(actionExecutedContext.ActionContext.ActionDescriptor.ActionName)
            ?.ReturnParameter
            ?.GetCustomAttribute<TupleElementNamesAttribute>()
            ?.TransformNames;
        var formatter = new JsonMediaTypeFormatter
        {
            SerializerSettings =
            {
                ContractResolver = new ValueTuplesContractResolver(names),
            },
        };
        actionExecutedContext.Response.Content = new ObjectContent(content.ObjectType, content.Value, formatter);
    }
}
ContractResolver:   
public class ValueTuplesContractResolver : CamelCasePropertyNamesContractResolver
{
    private IList<string> _names;
    public ValueTuplesContractResolver(IList<string> names)
    {
        _names = names;
    }
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);
        if (type.Name.Contains(nameof(ValueTuple)))
        {
            for (var i = 0; i < properties.Count; i++)
            {
                properties[i].PropertyName = _names[i];
            }
            _names = _names.Skip(properties.Count).ToList();
        }
        return properties;
    }
}
Usage:   
[ReturnValueTuple]
[HttpGet]
[Route("types")]
public IEnumerable<(int id, string name)> GetDocumentTypes()
{
    return ServiceContainer.Db
        .DocumentTypes
        .AsEnumerable()
        .Select(dt => (dt.Id, dt.Name));
}
This one returns next JSON:   
[  
   {  
      "id":0,
      "name":"Other"
   },
   {  
      "id":1,
      "name":"Shipping Document"
   }
]
Here the solution for Swagger UI:   
public class SwaggerValueTupleFilter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        var action = apiDescription.ActionDescriptor;
        var controller = action.ControllerDescriptor.ControllerType;
        var method = controller.GetMethod(action.ActionName);
        var names = method?.ReturnParameter?.GetCustomAttribute<TupleElementNamesAttribute>()?.TransformNames;
        if (names == null)
        {
            return;
        }
        var responseType = apiDescription.ResponseDescription.DeclaredType;
        FieldInfo[] tupleFields;
        var props = new Dictionary<string, string>();
        var isEnumer = responseType.GetInterface(nameof(IEnumerable)) != null;
        if (isEnumer)
        {
            tupleFields = responseType
                .GetGenericArguments()[0]
                .GetFields();
        }
        else
        {
            tupleFields = responseType.GetFields();
        }
        for (var i = 0; i < tupleFields.Length; i++)
        {
            props.Add(names[i], tupleFields[i].FieldType.GetFriendlyName());
        }
        object result;
        if (isEnumer)
        {
            result = new List<Dictionary<string, string>>
            {
                props,
            };
        }
        else
        {
            result = props;
        }
        operation.responses.Clear();
        operation.responses.Add("200", new Response
        {
            description = "OK",
            schema = new Schema
            {
                example = result,
            },
        });
    }