c# - How can I allow a client to specify the fields they want returned from my api? -


i'd mimic popular apis , 1 of things see lot client query web api , specify fields return. instance, looking user's details have ton of info, or basic info. rather creating separate endpoints different levels of detail, i'd able allow client request information need. private api.

so on server, i'd use users complete data (eagerly loaded or lazy loaded; hasn't been determined yet), once have object, i'd use fields specified in client's request build response object.

is there library this? or popular techniques or articles helpful. tia

this kind of involved process want loop objects returned if properties passed in , return dictionary of properties. created extension method doing it.

using system; using system.collections; using system.collections.generic; using system.globalization; using system.linq; using system.reflection; using system.text; using system.threading.tasks; using newtonsoft.json.linq;  namespace yournamespace.extensions {     public enum propertyformat     {         asis,         pascalcase,         camelcase     }      public static class datashapingextensions     {         public static object todatashape<objectin>(this objectin objecttoshape, string fields, propertyformat propertyformat = propertyformat.asis) objectin : class         {             var listoffields = new list<string>();              if (!string.isnullorwhitespace(fields))             {                 listoffields = fields.tolower().split(',').tolist();             }              if (listoffields.any())             {                 var objecttoreturn = new jobject();                  //====                 var enumerable = objecttoshape ienumerable;                  if (enumerable != null)                 {                     var listofobjects = new list<jobject>();                      foreach (var item in enumerable)                     {                         var objecttoreturn2 = new jobject();                          listoffields.foreach(field =>                         {                             try                             {                                 var prop = item.gettype()                                     .getproperty(field, bindingflags.ignorecase | bindingflags.public | bindingflags.instance);                                  var fieldname = prop.name;                                 var fieldvalue = prop.getvalue(item, null);                                  fieldname = getname(fieldname, propertyformat);                                 objecttoreturn2.add(new jproperty(fieldname, fieldvalue));                             }                             catch (exception ex) { }                         });                          listofobjects.add(objecttoreturn2);                     }                      return listofobjects.convertall(o => o);                 }                 //====                  listoffields.foreach(field =>                 {                     try                     {                         var prop = objecttoshape.gettype()                             .getproperty(field, bindingflags.ignorecase | bindingflags.public | bindingflags.instance);                          var fieldname = prop.name;                         var fieldvalue = prop.getvalue(objecttoshape, null);                          fieldname = getname(fieldname, propertyformat);                         objecttoreturn.add(new jproperty(fieldname, fieldvalue));                     }                     catch (exception ex) { }                 });                  return objecttoreturn;             }              return objecttoshape;         }          private static string getname(string field, propertyformat propertyformat)         {             switch (propertyformat)             {                 case propertyformat.asis: return field;                 case propertyformat.pascalcase: return field.topascalcase();                 case propertyformat.camelcase: return field.tocamelcase();                 default: return field;             }         }     } } 

to use check passed in fields on route.

[httpget, route("/api/yourroute")] public async task<ihttpactionresult> getlistofyourobjects(string fields = null) {     try     {         var yourobject = await repo.getyourlistfromrepo();          if (fields.hasvalue())         {            return ok(yourobject.todatashape(fields, propertyformat.camelcase));         }          return ok(yourobject);     }     catch (exception)     {          return internalservererror();     } } 

then shape data returned when call route ajax pass in fields want.

$.ajax({    url: "/api/yourroute?fields=field1,field2" }) 

which return object fields.

{   field1: "",   field2: "" } 

Comments

Popular posts from this blog

java - Static nested class instance -

c# - Bluetooth LE CanUpdate Characteristic property -

JavaScript - Replace variable from string in all occurrences -