C# 如何实现指定在向RESTAPI发出get请求时接收哪些参数的功能?
因为我需要减少API的负载,所以我考虑实现一种可能性,指定您希望在请求时接收哪些属性 现在当用户向api请求获取产品时C# 如何实现指定在向RESTAPI发出get请求时接收哪些参数的功能?,c#,sql,rest,asp.net-web-api,C#,Sql,Rest,Asp.net Web Api,因为我需要减少API的负载,所以我考虑实现一种可能性,指定您希望在请求时接收哪些属性 现在当用户向api请求获取产品时 /api/products/{id} 它们获取整个产品信息(id、名称、创建日期、UpdateDate、deleted、active等等),因此我需要从数据库中提取所有这些属性 我想要实现的是,api用户可以选择他们想要接收的属性,而不是从服务器返回产品的所有属性。URL可以如下所示: /products/{id}/props={id,name,LastUpdated} [
/api/products/{id}
它们获取整个产品信息(id、名称、创建日期、UpdateDate、deleted、active等等),因此我需要从数据库中提取所有这些属性
我想要实现的是,api用户可以选择他们想要接收的属性,而不是从服务器返回产品的所有属性。URL可以如下所示:
/products/{id}/props={id,name,LastUpdated}
[Flags]
public enum Props
{
FirstName = 1,
Surname = 2,
Address = 4,
Occupation = 8
}
public string GetValues(int id, Props props)
{
var items = new Dictionary<string, string>();
if (props == 0 || props.HasFlag(Props.FirstName))
items.Add("FirstName", "Bob");
if (props == 0 || props.HasFlag(Props.Surname))
items.Add("Surname", "Smith");
if (props == 0 || props.HasFlag(Props.Address))
items.Add("Address", "London");
if (props == 0 || props.HasFlag(Props.Occupation))
items.Add("Occupation ", "Professional Tea Drinker");
//Using Newtonsoft Json:
return JsonConvert.SerializeObject(items);
}
GetValues(1, (Props)0)
GetValues(1, (Props)1)
GetValues(1, (Props)3)
因此,我只需要从数据库中选择id、name和LastUpdated就可以返回给API用户
如何以最智能的方式实际实现这样的功能?编辑:现在问题已经很好地描述了 我明白了。这只有在没有模型的情况下才可能实现。(我想) 我认为JObject是一个良好的开端,它可能是这方面测试最多的库 大致应该是这样的:
/products/{id}/props={id,name,LastUpdated}
[Flags]
public enum Props
{
FirstName = 1,
Surname = 2,
Address = 4,
Occupation = 8
}
public string GetValues(int id, Props props)
{
var items = new Dictionary<string, string>();
if (props == 0 || props.HasFlag(Props.FirstName))
items.Add("FirstName", "Bob");
if (props == 0 || props.HasFlag(Props.Surname))
items.Add("Surname", "Smith");
if (props == 0 || props.HasFlag(Props.Address))
items.Add("Address", "London");
if (props == 0 || props.HasFlag(Props.Occupation))
items.Add("Occupation ", "Professional Tea Drinker");
//Using Newtonsoft Json:
return JsonConvert.SerializeObject(items);
}
GetValues(1, (Props)0)
GetValues(1, (Props)1)
GetValues(1, (Props)3)
基本教程(来自官方网站):例如,您可以执行类似的操作,但需要进行编辑以满足您的api需求
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Reflection;
using System.Linq;
public class Program
{
public class Man
{
public int Id { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
}
public static void Main()
{
var man = new Man
{
Id = 2,
Name = "A Name",
Phone = "123456789"
};
var props = "id,name";
var customPropsArray = props.Split(',');
Type t = man.GetType();
PropertyInfo[] properties = t.GetProperties(
BindingFlags.NonPublic | // Include protected and private properties
BindingFlags.Public | // Also include public properties
BindingFlags.Instance // Specify to retrieve non static properties
);
var dynamicObject = new ExpandoObject() as IDictionary<string, Object>;
foreach (var p in properties.Where(x => customPropsArray.Contains(x.Name.ToLower())))
{
dynamicObject.Add(p.Name, p.GetValue(man));
}
}
}
使用系统;
使用System.Collections.Generic;
运用系统动力学;
运用系统反思;
使用System.Linq;
公共课程
{
公务舱员
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公用字符串电话{get;set;}
}
公共静态void Main()
{
var man=新人
{
Id=2,
Name=“A Name”,
电话=“123456789”
};
var props=“id,name”;
var customPropsArray=props.Split(',');
类型t=man.GetType();
PropertyInfo[]properties=t.GetProperties(
BindingFlags.NonPublic |//包括受保护和私有属性
BindingFlags.Public |//还包括公共属性
BindingFlags.Instance//指定以检索非静态属性
);
var dynamicObject=new ExpandoObject()作为IDictionary;
foreach(properties.Where(x=>customPropsArray.Contains(x.Name.ToLower())中的var p)
{
Add(p.Name,p.GetValue(man));
}
}
}
OData是一个好主意,但如果由于某种原因无法使用它,可以使用枚举来指定所需的属性,然后在API中通过字典将它们序列化为Json。类似如下:
/products/{id}/props={id,name,LastUpdated}
[Flags]
public enum Props
{
FirstName = 1,
Surname = 2,
Address = 4,
Occupation = 8
}
public string GetValues(int id, Props props)
{
var items = new Dictionary<string, string>();
if (props == 0 || props.HasFlag(Props.FirstName))
items.Add("FirstName", "Bob");
if (props == 0 || props.HasFlag(Props.Surname))
items.Add("Surname", "Smith");
if (props == 0 || props.HasFlag(Props.Address))
items.Add("Address", "London");
if (props == 0 || props.HasFlag(Props.Occupation))
items.Add("Occupation ", "Professional Tea Drinker");
//Using Newtonsoft Json:
return JsonConvert.SerializeObject(items);
}
GetValues(1, (Props)0)
GetValues(1, (Props)1)
GetValues(1, (Props)3)
返回:
{“名字”:“鲍勃”,“姓氏”:“史密斯”,“地址”:“伦敦”,“职业”:“专业饮茶者”}
{“FirstName”:“Bob”}
{“名字”:“鲍勃”,“姓氏”:“史密斯”}
你可能有两个模型。模型A的属性更少,模型B的属性更多,B当然继承自A。你总是将B保存到数据库中。所以,我们的想法只是与简单的模型A进行“约定”。然后在控制器上,你可以将A作为参数传递给Constructor,在Constructor上创建B。你可以使用映射库Reflection(需要缓存),或手工绘制的地图。如果你不喜欢这个想法,请告诉我,我会尝试更好的想法。@JuanCarlos如果我有一个简单的模型和完整的模型,它会起作用,但是如果我有20种不同的属性组合的可能性,那会怎么样?而不是我必须创建20种不同的模型。我考虑实施一种策略模式每种可能都有n个,但这将是20种不同的策略。@ivan yurchenko发布的OData也是一个好主意。可能实现起来更复杂,但也更健壮。OData现在不适合实现框架。但我可以使用您的approach@Timsen谢谢你把我的建议作为答案。让我知道你是否实施了它,以及你是如何做到的。