当前位置: 首页 > 编程语言 > C#

ServiceStack支持在每次调用的基础上有条件地忽略REST响应中的字段分享

时间:2023-04-10 21:18:17 C#

C#学习教程:ServiceStacksupportsconditionallyignoringfieldsinRESTresponsesonper-call每次呼叫的响应(请参阅下面的字段)。理想情况下,我想使用ServiceStack来实现支持以下所有要点的REST服务。更新虽然我真的很喜欢ServiceStack的方法,但如果可能的话,我更愿意使用它,如果它不是特别适合这些想法,我宁愿不向后弯腰让它工作。如果是这样,任何人都可以指出另一个可能更合适的c#框架吗?当然,我正在积极探索其他选择。在这个名为“设计REST+JSONAPI”的演讲中,演示者描述了他在JSON中的资源引用策略(通过资源上的href属性)。除其他外,他描述了两个查询参数(fields和expand),用于控制对REST服务的调用响应中包含的数据。我一直在努力深入研究ServiceStack框架以提供字段支持,但到目前为止一直没有成功。目前这在ServiceStack中可行吗?理想情况下,该解决方案将与格式无关,因此可以使用所有ServiceStack支持的输出格式。我认为expand将使用相同的策略。我将在此处描述这些功能,但我认为链接中的谈话更好地解释了它们。假设我们有一个具有以下属性的Profiles资源:givenName、surname、gender和favColor。Profiles资源还在socialNetworks属性中包含用户所属的社交网络列表。href-(视频中的42:22)每个资源都包含REST服务的完整链接。将返回对GET/profiles/123{"href":"https://host/profiles/123","givenName":"Bob","surname":"Smith","gender":"male","favColor":"red","socialNetworks":{"href":"https://host/socialNetworkMemberships?profileId=123"}}请注意,socialNetworks属性返回的对象仅填充了href值。这允许更短和更集中的响应,同时还为最终用户提供足够的信息,以便在需要时满足进一步的请求容易(无论如何在概念上)。fields–(视频中的55:44)查询字符串参数,指示服务器在REST响应中仅包含所需资源的指定属性。对GET/profiles/123的正常响应将包括资源的所有属性,如上所示。当请求中包含fields查询参数时,仅返回指定的字段。'获取/propfiles/123?fields=surname,favColor'将返回{"href":"https://host/profiles/123","surname":"Smith","favColor":"red"}展开–(视频中的45:53)指示服务器丰富结果中指定子资源的查询字符串参数。使用我们的示例,如果您要调用GET/profiles/123?expand=socialNetworks,您可能会收到类似{"href":"https://host/profiles/123","givenName":"Bob","surname":"Smith","gender":"male","favColor":"red","socialNetworks":{"href":"https://host/socialNetworkMemberships?profileId=123","items":[{"href":"https://host/socialNetworkMemberships/abcde","siteName":"Facebook","profileUrl":"http://www.facebook.com/..."},...]}}所以...在我看来,ServiceStack的最佳特性是它使通过HTTP发送、接收和处理POCO变得非常容易。如何设置POCO以及它们之间的操作(在“服务”中)由您决定。SS有意见吗?是的。你必须同意他们吗?不。(但你可能应该:))我认为扩展如下所示的东西会让你接近你想要处理api的方式。可能不是ServiceStack的最佳示例,但ServiceStack代码/要求几乎不会被注意到并且不会妨碍您(AppHost配置未显示)。您可以在其他.NET框架(MVC/WebAPI/等)中执行类似的操作,但在我看来,它看起来不像使用ServiceStack那样直接的C#/.NET代码。请申请课程[Route("/Profiles/{Id}")]publicclassProfiles{publicint?id{得到;放;}}[Route("/SocialNetworks/{Id}")]publicclassSocialNetworks{publicint?id{得到;放;}}基础响应类publicclassBaseResponse{protectedvirtualstringhrefPath{get{return"";}}公共字符串ID{得到;放;}publicstringhref{get{returnhrefPath+Id;}}}来自我展示的类publicclassProfile:BaseResponse{protectedoverridestringhrefPath{get{return"https://host/profiles/";}}公共字符串GivenName{得到;放;}publicstringSurName{get;放;}公共字符串性别{得到;放;}公共字符串FavColor{得到;放;}publicListSocialNetworks{get;放;}}publicclassSocialNetwork:BaseResponse{protectedoverridestringhrefPath{get{return"https://host/socialNetworkMemberships?profileId=";}}publicstringSiteName{get;放;}publicstringProfileUrl{get;放;}}服务publicclassProfileService:Service{publicobjectGet(配置文件请求){vartestProfile=newProfile{Id=“123”,GivenName=“Bob”,SurName=“Smith”,Gender=“Male”,FavColor=“Red”,SocialNetworks=newList{newSocialNetwork{Id="abcde",SiteName="Facebook",ProfileUrl="http://www.facebook.com/"}}};如果(!String.IsNullOrEmpty(this.Request.QueryString.Get("fields"))||!String.IsNullOrEmpty(this.Request.QueryString.Get("expand")))返回ServiceHelper.BuildResponseObject(testProfile,this.请求.QueryString);返回测试资料;}}publicclassSocialNetworkService:Service{publicobjectGet(SocialNetworksrequest){vartestSocialNetwork=newSocialNetwork{Id="abcde",SiteName="Facebook",ProfileUrl="http://www.facebook.com/"};如果(!String.IsNullOrEmpty(this.Request.QueryString.Get("fields"))||!String.IsNullOrEmpty(this.Request.QueryString.Get("expand")))返回ServiceHelper.BuildResponseObject(testSocialNetwork,this.请求.QueryString);返回测试So社交网络;}}反思助手类publicstaticclassServiceHelper{publicstaticobjectBuildResponseObject(TtypedObject,NameValueCollectionqueryString)whereT:BaseResponse{varnewObject=newExpandoObject()asIDictionary;newObject.Add("href",typedObject.href);if(!String.IsNullOrEmpty(queryString.Get("fields"))){foreach(varpropertyNameinqueryString.Get("fields").Split(',').ToList()){//可以检查'socialNetwork'并在需要时排除}}if(!String.IsNullOrEmpty(queryString.Get("expand"))){foreach(varpropertyNameinqueryString.Get("expand").Split(',').ToList()){newObject.Add(propertyName,typedObject.GetType().GetProperty(propertyName,BindingFlags.IgnoreCase|BindingFlags.Public|BindingFlags.Instance).GetValue(typedObject,null));}}返回新对象;通常,您可以通过设置DataMember属性来控制DTO的序列化使用这些属性,您可以控制属性是否应具有默认值。这意味着如果您只是不定义要返回的对象的属性,则不应对其进行序列化,因此不会出现在生成的Json中。ServiceStack内部使用标准的DataContract...Serializer,所以应该支持这个。否则,你也可以使用动态对象,只需在运行时编写对象,序列化并发送回来。这是一个非常基本的例子:以上是C#学习教程:ServiceStacksupportsconditionallyignoringfieldsinRESTresponsesonaper-callbasis注意教程—varseri=JsonSerializer.Create(newJsonSerializerSettings(){});使用(vartextWriter=newStringWriter()){varwriter=newJsonTextWriter(textWriter);动态项目=新{Id=id};seri.Serialize(作者,项目);返回textWriter.ToString();}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: