如何使用带有 C# HttpClient 的 Get 发送复杂对象

How to send a complex object using Get with c# HttpClient

我有一个 c# 项目并希望使用 api。如果感兴趣,可以在此处查看文档:link

当我想获得 api 中所有“客户”的列表时,它具有一些必需的属性:

attention.self, currency, customerContact.self, customerGroup, customerGroup.self, defaultDeliveryLocation.self, invoices.self, layout.self, name, paymentTerms, paymentTerms.self, salesPerson.self, self, templates.self, totals.self, vatZone, vatZone.self

我有一个自定义对象,其命名与所需属性相同。该对象很复杂,因为它引用了“attention、customerContact、customerGroup、paymentTerms..”之类的对象,正如文档所述。

现在我必须使用的端点是带有 Get 的“\customers”,所以我必须参数化属性。

我一直在寻找将复杂对象转换为 uri 之类的解决方案 “?name=Mike¤cy=USD&..”,但不幸的是我只找到了一个解决方案,它可以将只有简单类型的自定义对象制作成格式化参数字符串。

所以我暂时放弃并尝试编写自己的硬编码 url 字符串,但是如何将复杂的对象添加到 url 查询中,例如“attention.self”?

“?attention.self=Something&..”会让 api 翻译它以便它知道“注意力”是另一个对象而“自我”是那个对象上的 属性 ?

任何有关如何更优化地执行此操作的建议都会很棒。

您可以使用 Reflection:

public IEnumerable<string> ToQueryStringItem<T>(T entity)
{
     foreach(var pi in typeof(T).GetProperties())
         yield return $"{pi.Name}={pi.GetValue(entity)}";
}

public IEnumerable<string> ToQueryString<T>(T entity)
     => $"?{string.Join("&", ToQueryString(entity).ToList())}";

现在您可以像这样操作:

string qs = ToQueryString(someClassInstance);

请注意,如果 class 属性不是原始类型,您将需要更复杂的反射代码。

而且如果你想要一些自定义值,它也是可行的,例如让我们说而不是 truefalse,你想要 10 :

foreach(var pi in typeof(T).GetProperties())
{
     switch(pi.PropertyType.ToString())
     {
          case "Boolean":
               yield return $"{pi.Name}={(pi.GetValue(entity)?1:0)};
          //....
          default:
               yield return $"{pi.Name}={pi.GetValue(entity)}";   
     }
}

您可能还想隐藏一些属性以防止在查询字符串中使用,为此您可以创建一个属性:

public class IgnoreInQueryStringAttribute: Attribute {}

并将其用于您不想出现在查询字符串中的任何 属性:

public class Customer
{
     [IgnoreInQueryString]
     public int Id { get; set; }
     public string Firstname { get; set; } 
}

然后:

foreach(var pi in typeof(T).GetProperties())
{
    if(pi.GetCustomAttributes(typeof(IgnoreInQueryString), false).Length == 0)     
    {
         //....
    }
}