├── .gitignore ├── Example1 ├── App.config ├── Example1.csproj ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Settings.Designer.cs │ └── Settings.settings ├── TestBacking.cs └── packages.config ├── Example2.Core ├── Example2.Core.xproj ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── project.json ├── Gedcomx.Api.Lite.Core ├── Environment.cs ├── FamilySearchSDK.cs ├── Gedcomx.Api.Lite.Core.nuspec ├── Gedcomx.Api.Lite.Core.xproj ├── MediaType.cs ├── Properties │ ├── AssemblyInfo.cs │ └── launchSettings.json └── project.json ├── Gedcomx.Api.Lite.Tests ├── AuthenticationTests.cs ├── Gedcomx.Api.Lite.Tests.csproj ├── PersonTests.cs ├── PortraitTests.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Settings.Designer.cs │ └── Settings.settings ├── TestBacking.cs ├── app.config └── packages.config ├── Gedcomx.Api.Lite.sln ├── Gedcomx.Api.Lite ├── Gedcomx.Api.Lite.csproj ├── Gedcomx.Api.Lite.nuspec ├── Properties │ └── AssemblyInfo.cs └── packages.config └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | -------------------------------------------------------------------------------- /Example1/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | username 15 | 16 | 17 | password 18 | 19 | 20 | applicationKey 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Example1/Example1.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {9CD0258C-FC2D-493A-8D27-F6BD06C6776D} 8 | Exe 9 | Properties 10 | Example1 11 | Example1 12 | v4.6 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\Gedcomx.Model.1.0.6144.20322\lib\net45\Gedcomx.Model.dll 38 | True 39 | 40 | 41 | ..\packages\Gedcomx.Model.Fs.1.0.6144.20322\lib\net45\Gedcomx.Model.Fs.dll 42 | True 43 | 44 | 45 | ..\packages\Gedcomx.Model.Rs.1.0.6144.20322\lib\net45\Gedcomx.Model.Rs.dll 46 | True 47 | 48 | 49 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 50 | True 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | True 67 | True 68 | Settings.settings 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | SettingsSingleFileGenerator 77 | Settings.Designer.cs 78 | 79 | 80 | 81 | 82 | {dc9c289b-4ecc-41c5-8845-d29bedacd45e} 83 | Gedcomx.Api.Lite 84 | 85 | 86 | 87 | 94 | -------------------------------------------------------------------------------- /Example1/Program.cs: -------------------------------------------------------------------------------- 1 | using Example1.Properties; 2 | using Gedcomx.Api.Lite; 3 | using Gx.Common; 4 | using Gx.Fs.Tree; 5 | using Newtonsoft.Json; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Threading.Tasks; 10 | 11 | namespace Example1 12 | { 13 | class Program 14 | { 15 | public static JsonSerializerSettings jsettings = new JsonSerializerSettings 16 | { 17 | NullValueHandling = NullValueHandling.Ignore // Trims the extra content not needed in this case making things even faster with less content. 18 | }; 19 | 20 | static void Main(string[] args) 21 | { 22 | var ft = new FamilySearchSDK(Settings.Default.UserName, Settings.Default.Password, Settings.Default.ApplicationKey, "Example1", "1.0.0", Gedcomx.Api.Lite.Environment.Integration); 23 | 24 | // Create a Person 25 | var gedcomx = new Gx.Gedcomx(); 26 | gedcomx.AddPerson(TestBacking.GetCreateMalePerson()); 27 | 28 | // Now post two of them to family search asynchronously 29 | var postTask = ft.Post("/platform/tree/persons", JsonConvert.SerializeObject(gedcomx), MediaType.X_GEDCOMX_v1_JSON); 30 | var postTask2 = ft.Post("/platform/tree/persons", JsonConvert.SerializeObject(gedcomx), MediaType.X_GEDCOMX_v1_JSON); 31 | Task.WaitAll(postTask, postTask2); 32 | var postResultSon = postTask.Result; 33 | var postResultFather = postTask2.Result; 34 | 35 | // Or if only one and you want synchronous results 36 | var postResults3 = ft.Post("/platform/tree/persons", JsonConvert.SerializeObject(gedcomx), MediaType.X_GEDCOMX_v1_JSON).Result; 37 | 38 | // Now get the new person. 39 | string personId = ((string[])postResultSon.Headers.Location.ToString().Split('/')).Last(); 40 | var response = ft.Get("/platform/tree/persons/" + personId).Result; 41 | 42 | // By presuming we have single element. 43 | Console.WriteLine(response.persons[0].id + " - " + response.persons[0].display.name); 44 | 45 | // Get a person's portrait 46 | var portraitResponse = ft.Get($"/platform/tree/persons/{personId}/portrait", MediaType.X_FS_v1_JSON); 47 | var portrait = portraitResponse.Result; 48 | //Console.WriteLine(response.persons[0].id + " - " + response.persons[0].display.name); 49 | 50 | // Set parentage 51 | List relationships = new List(); 52 | relationships.Add(new ChildAndParentsRelationship() 53 | { 54 | Father = new ResourceReference(postResultFather.Headers.Location.ToString()), 55 | Child = new ResourceReference(postResultSon.Headers.Location.ToString()) 56 | }); 57 | // use an array wrapper as we have to name the array. 58 | var content = JsonConvert.SerializeObject(new { childAndParentsRelationships = relationships }, jsettings); 59 | 60 | var rel = ft.Post("/platform/tree/relationships", content, MediaType.X_FS_v1_JSON); 61 | var results = rel.Result; 62 | 63 | // Now read the relationship back. (the Son) 64 | var anc = ft.Get("/platform/tree/ancestry?person=" + personId).Result; 65 | Console.WriteLine($"For {personId} then have these ancestors"); 66 | foreach (var a in anc.persons) 67 | { 68 | Console.WriteLine(a.id + " - " + a.display.name); 69 | } 70 | 71 | 72 | // Now search! 73 | //platform/tree/search?q=motherGivenName%3AClarissa~%20fatherSurname%3AHeaton~%20motherSurname%3AHoyt~%20surname%3AHeaton~%20givenName%3AIsrael~%20fatherGivenName%3AJonathan~ 74 | var encoded = Uri.EscapeDataString("motherGivenName:Clarissa~ fatherSurname:Heaton~ motherSurname:Hoyt~ surname:Heaton~ givenName:Israel~ fatherGivenName:Jonathan~"); 75 | var searchResult = ft.Get("/platform/tree/search?q=" + encoded, MediaType.X_GEDCOMX_ATOM_JSON).Result; 76 | 77 | Console.WriteLine($"Found close hits {searchResult.searchInfo[0].closeHits} with {searchResult.searchInfo[0].totalHits} total"); 78 | 79 | var stopCount = 1000; 80 | var totalFetched = 0; 81 | while (searchResult != null && 82 | (totalFetched <= Convert.ToInt32(searchResult.results) || totalFetched > stopCount)) 83 | { 84 | totalFetched = (searchResult.index + searchResult.entries.Count); 85 | foreach (var e in searchResult.entries) 86 | { 87 | var p = e.content.gedcomx.persons[0]; 88 | Console.WriteLine($"{p.id} - {p.display.name} birthDate {p.display.birthDate} birthPlace {p.display.birthPlace}"); 89 | } 90 | 91 | // Advance & get the next search results if there. 92 | if (searchResult.results > (searchResult.index + searchResult.entries.Count)) 93 | { 94 | Console.WriteLine($"fetching another. total={totalFetched}"); 95 | searchResult = ft.Get(searchResult.links.next.href.Value, MediaType.X_GEDCOMX_ATOM_JSON).Result; 96 | } 97 | } 98 | 99 | Console.WriteLine("Press Enter to Exit"); 100 | Console.ReadLine(); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Example1/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Example1")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Example1")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("9cd0258c-fc2d-493a-8d27-f6bd06c6776d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Example1/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Example1.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.ApplicationScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("username")] 29 | public string UserName { 30 | get { 31 | return ((string)(this["UserName"])); 32 | } 33 | } 34 | 35 | [global::System.Configuration.ApplicationScopedSettingAttribute()] 36 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 37 | [global::System.Configuration.DefaultSettingValueAttribute("password")] 38 | public string Password { 39 | get { 40 | return ((string)(this["Password"])); 41 | } 42 | } 43 | 44 | [global::System.Configuration.ApplicationScopedSettingAttribute()] 45 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 46 | [global::System.Configuration.DefaultSettingValueAttribute("applicationKey")] 47 | public string ApplicationKey { 48 | get { 49 | return ((string)(this["ApplicationKey"])); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example1/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | username 7 | 8 | 9 | password 10 | 11 | 12 | applicationKey 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example1/TestBacking.cs: -------------------------------------------------------------------------------- 1 | using Gx.Common; 2 | using Gx.Conclusion; 3 | using Gx.Source; 4 | using Gx.Types; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | namespace Example1 10 | { 11 | public static class TestBacking 12 | { 13 | public static Person GetPersonForDeepCompare() 14 | { 15 | return new Person() 16 | { 17 | Living = false, 18 | Gender = new Gender() 19 | { 20 | KnownType = Gx.Types.GenderType.Male, 21 | Fields = new List(), 22 | Sources = new List(), 23 | Notes = new List(), 24 | Links = new List(), 25 | ExtensionElementsXml = new List(), 26 | }, 27 | Names = new List() 28 | { 29 | new Name() 30 | { 31 | KnownType = Gx.Types.NameType.BirthName, 32 | NameForms = new List() 33 | { 34 | new NameForm() 35 | { 36 | FullText = "GedcomX User", 37 | Parts = new List() 38 | { 39 | new NamePart() 40 | { 41 | KnownType = Gx.Types.NamePartType.Given, 42 | Value = "GedcomX", 43 | ExtensionElementsXml = new List(), 44 | Fields = new List(), 45 | Qualifiers = new List(), 46 | }, 47 | new NamePart() 48 | { 49 | KnownType = Gx.Types.NamePartType.Surname, 50 | Value = "User", 51 | ExtensionElementsXml = new List(), 52 | Fields = new List(), 53 | Qualifiers = new List(), 54 | }, 55 | }, 56 | ExtensionElementsXml = new List(), 57 | Fields = new List(), 58 | }, 59 | new NameForm() 60 | { 61 | FullText = "GedcomX2 User", 62 | Parts = new List() 63 | { 64 | new NamePart() 65 | { 66 | KnownType = Gx.Types.NamePartType.Given, 67 | Value = "GedcomX2", 68 | ExtensionElementsXml = new List(), 69 | Fields = new List(), 70 | Qualifiers = new List(), 71 | }, 72 | new NamePart() 73 | { 74 | KnownType = Gx.Types.NamePartType.Surname, 75 | Value = "User", 76 | ExtensionElementsXml = new List(), 77 | Fields = new List(), 78 | Qualifiers = new List(), 79 | }, 80 | }, 81 | ExtensionElementsXml = new List(), 82 | Fields = new List(), 83 | }, 84 | }, 85 | Preferred = true, 86 | Sources = new List(), 87 | Notes = new List(), 88 | Links = new List(), 89 | ExtensionElementsXml = new List(), 90 | }, 91 | }, 92 | Facts = new List() 93 | { 94 | new Fact() 95 | { 96 | KnownType = Gx.Types.FactType.Birth, 97 | Date = new DateInfo() 98 | { 99 | Original = "June 1800", 100 | NormalizedExtensions = new List(), 101 | Fields = new List(), 102 | ExtensionElementsXml = new List(), 103 | }, 104 | Place = new PlaceReference() 105 | { 106 | Original = "Provo, Utah, Utah, United States", 107 | NormalizedExtensions = new List(), 108 | Fields = new List(), 109 | ExtensionElementsXml = new List(), 110 | }, 111 | Qualifiers = new List(), 112 | Fields = new List(), 113 | Sources = new List(), 114 | Notes = new List(), 115 | Links = new List(), 116 | ExtensionElementsXml = new List(), 117 | }, 118 | new Fact() 119 | { 120 | KnownType = Gx.Types.FactType.Christening, 121 | Date = new DateInfo() 122 | { 123 | Original = "1802", 124 | NormalizedExtensions = new List(), 125 | Fields = new List(), 126 | ExtensionElementsXml = new List(), 127 | }, 128 | Place = new PlaceReference() 129 | { 130 | Original = "American Fork, Utah, Utah, United States", 131 | NormalizedExtensions = new List(), 132 | Fields = new List(), 133 | ExtensionElementsXml = new List(), 134 | }, 135 | Qualifiers = new List(), 136 | Fields = new List(), 137 | Sources = new List(), 138 | Notes = new List(), 139 | Links = new List(), 140 | ExtensionElementsXml = new List(), 141 | }, 142 | new Fact() 143 | { 144 | KnownType = Gx.Types.FactType.Residence, 145 | Date = new DateInfo() 146 | { 147 | Original = "4 Jan 1896", 148 | NormalizedExtensions = new List(), 149 | Fields = new List(), 150 | ExtensionElementsXml = new List(), 151 | }, 152 | Place = new PlaceReference() 153 | { 154 | Original = "Provo, Utah, Utah, United States", 155 | NormalizedExtensions = new List(), 156 | Fields = new List(), 157 | ExtensionElementsXml = new List(), 158 | }, 159 | Qualifiers = new List(), 160 | Fields = new List(), 161 | Sources = new List(), 162 | Notes = new List(), 163 | Links = new List(), 164 | ExtensionElementsXml = new List(), 165 | }, 166 | new Fact() 167 | { 168 | KnownType = Gx.Types.FactType.Death, 169 | Date = new DateInfo() 170 | { 171 | Original = "July 14, 1900", 172 | NormalizedExtensions = new List(), 173 | Fields = new List(), 174 | ExtensionElementsXml = new List(), 175 | }, 176 | Place = new PlaceReference() 177 | { 178 | Original = "Provo, Utah, Utah, United States", 179 | NormalizedExtensions = new List(), 180 | Fields = new List(), 181 | ExtensionElementsXml = new List(), 182 | }, 183 | Qualifiers = new List(), 184 | Fields = new List(), 185 | Sources = new List(), 186 | Notes = new List(), 187 | Links = new List(), 188 | ExtensionElementsXml = new List(), 189 | }, 190 | new Fact() 191 | { 192 | KnownType = Gx.Types.FactType.Burial, 193 | Date = new DateInfo() 194 | { 195 | Original = "1900", 196 | NormalizedExtensions = new List(), 197 | Fields = new List(), 198 | ExtensionElementsXml = new List(), 199 | }, 200 | Place = new PlaceReference() 201 | { 202 | Original = "Sandy, Salt Lake, Utah, United States", 203 | NormalizedExtensions = new List(), 204 | Fields = new List(), 205 | ExtensionElementsXml = new List(), 206 | }, 207 | Qualifiers = new List(), 208 | Fields = new List(), 209 | Sources = new List(), 210 | Notes = new List(), 211 | Links = new List(), 212 | ExtensionElementsXml = new List(), 213 | } 214 | }, 215 | ExtensionElementsXml = new List(), 216 | Fields = new List(), 217 | Evidence = new List(), 218 | Media = new List(), 219 | Identifiers = new List(), 220 | Sources = new List(), 221 | Notes = new List(), 222 | Links = new List(), 223 | DiscussionReferences = new List(), 224 | }; 225 | } 226 | 227 | public static Person GetCreateMalePerson() 228 | { 229 | return new Person() 230 | .SetLiving(false) 231 | .SetGender(new Gender().SetType(GenderType.Male)) 232 | .SetName(new Name() 233 | .SetType(NameType.BirthName) 234 | .SetNameForm(new NameForm() 235 | .SetFullText("GedcomX User") 236 | .SetPart(new NamePart(NamePartType.Given, "GedcomX")) 237 | .SetPart(new NamePart(NamePartType.Surname, "User"))) 238 | .SetNameForm(new NameForm() 239 | .SetFullText("GedcomX2 User") 240 | .SetPart(new NamePart(NamePartType.Given, "GedcomX2")) 241 | .SetPart(new NamePart(NamePartType.Surname, "User"))) 242 | .SetPreferred(true)) 243 | .SetFact(new Fact() 244 | .SetType(FactType.Birth) 245 | .SetDate(new DateInfo().SetOriginal("June 1800")) 246 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 247 | .SetFact(new Fact() 248 | .SetType(FactType.Christening) 249 | .SetDate(new DateInfo().SetOriginal("1802")) 250 | .SetPlace(new PlaceReference().SetOriginal("American Fork, Utah, Utah, United States"))) 251 | .SetFact(new Fact() 252 | .SetType(FactType.Residence) 253 | .SetDate(new DateInfo().SetOriginal("4 Jan 1896")) 254 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 255 | .SetFact(new Fact() 256 | .SetType(FactType.Death) 257 | .SetDate(new DateInfo().SetOriginal("July 14, 1900")) 258 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 259 | .SetFact(new Fact() 260 | .SetType(FactType.Burial) 261 | .SetDate(new DateInfo().SetOriginal("1900")) 262 | .SetPlace(new PlaceReference().SetOriginal("Sandy, Salt Lake, Utah, United States"))); 263 | } 264 | 265 | public static Person GetCreateFemalePerson() 266 | { 267 | return new Person() 268 | .SetLiving(false) 269 | .SetGender(new Gender().SetType(GenderType.Female)) 270 | .SetName(new Name() 271 | .SetType(NameType.BirthName) 272 | .SetNameForm(new NameForm() 273 | .SetFullText("GedcomX User") 274 | .SetPart(new NamePart(NamePartType.Given, "GedcomX")) 275 | .SetPart(new NamePart(NamePartType.Surname, "User"))) 276 | .SetNameForm(new NameForm() 277 | .SetFullText("GedcomX2 User") 278 | .SetPart(new NamePart(NamePartType.Given, "GedcomX2")) 279 | .SetPart(new NamePart(NamePartType.Surname, "User"))) 280 | .SetPreferred(true)) 281 | .SetFact(new Fact() 282 | .SetType(FactType.Birth) 283 | .SetDate(new DateInfo().SetOriginal("June 1800")) 284 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 285 | .SetFact(new Fact() 286 | .SetType(FactType.Christening) 287 | .SetDate(new DateInfo().SetOriginal("1802")) 288 | .SetPlace(new PlaceReference().SetOriginal("American Fork, Utah, Utah, United States"))) 289 | .SetFact(new Fact() 290 | .SetType(FactType.Residence) 291 | .SetDate(new DateInfo().SetOriginal("4 Jan 1896")) 292 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 293 | .SetFact(new Fact() 294 | .SetType(FactType.Death) 295 | .SetDate(new DateInfo().SetOriginal("July 14, 1900")) 296 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 297 | .SetFact(new Fact() 298 | .SetType(FactType.Burial) 299 | .SetDate(new DateInfo().SetOriginal("1900")) 300 | .SetPlace(new PlaceReference().SetOriginal("Sandy, Salt Lake, Utah, United States"))); 301 | } 302 | 303 | public static SourceReference GetPersonSourceReference() 304 | { 305 | return new SourceReference() 306 | .SetAttribution(new Attribution() 307 | .SetChangeMessage("Family is at the same address found in other sources associated with this family. Names are a good match. Estimated births are reasonable.")) 308 | .SetDescriptionRef("https://sandbox.familysearch.org/platform/sources/descriptions/MMH1-PNF"); 309 | } 310 | 311 | public static Person GetCreatePersonConclusion(string personId) 312 | { 313 | return new Person() 314 | { 315 | Id = personId, 316 | Facts = new List() 317 | { 318 | new Fact() 319 | { 320 | Attribution = new Attribution() 321 | { 322 | ChangeMessage = "Change message", 323 | }, 324 | KnownType = Gx.Types.FactType.Birth, 325 | Date = new DateInfo() 326 | { 327 | Original = "3 Apr 1836", 328 | Formal = "+1836", 329 | }, 330 | Place = new PlaceReference() 331 | { 332 | Original = "Moscow, Russia", 333 | }, 334 | } 335 | } 336 | }; 337 | } 338 | 339 | public static Person GetCreateDiscussionReference(string personId) 340 | { 341 | return new Person() 342 | { 343 | Id = personId, 344 | Attribution = new Attribution() 345 | { 346 | ChangeMessage = "Change message", 347 | }, 348 | // TODO: discussion-references 349 | }; 350 | } 351 | 352 | public static Note GetCreateNote() 353 | { 354 | return new Note() 355 | .SetSubject("Sample") 356 | .SetText("Sample note text " + DateTime.Now.Ticks) 357 | .SetAttribution(new Attribution() 358 | .SetContributor(new ResourceReference("https://api.familysearch.org/platform/users/agents/MM6M-8QJ").SetResourceId("MM6M-8QJ"))); 359 | } 360 | 361 | public static Fact GetBirthFact() 362 | { 363 | return new Fact() 364 | { 365 | Attribution = new Attribution() 366 | { 367 | ChangeMessage = "Change message", 368 | }, 369 | KnownType = Gx.Types.FactType.Birth, 370 | Date = new DateInfo() 371 | { 372 | Original = "3 Apr 1836", 373 | Formal = "+1836", 374 | }, 375 | Place = new PlaceReference() 376 | { 377 | Original = "Moscow, Russia", 378 | }, 379 | }; 380 | } 381 | 382 | public static Fact GetCustomFact() 383 | { 384 | return new Fact() 385 | { 386 | Attribution = new Attribution() 387 | { 388 | ChangeMessage = "Change message", 389 | }, 390 | Type = "data:,Eagle%20Scout", 391 | Qualifiers = new List() 392 | { 393 | new Qualifier() 394 | { 395 | Name = "http://www.familysearch.org/v1/Event", 396 | Value = bool.FalseString.ToLower(), 397 | }, 398 | }, 399 | }; 400 | } 401 | 402 | public static Gx.Gedcomx GetCreatePersonLifeSketch(string personId) 403 | { 404 | return new Gx.Gedcomx() 405 | { 406 | Persons = new List() 407 | { 408 | new Person() 409 | { 410 | Id = personId, 411 | Facts = new List() 412 | { 413 | new Fact() 414 | { 415 | Attribution = new Attribution() 416 | { 417 | ChangeMessage = "...change message...", 418 | }, 419 | Type = "http://www.familysearch.org/v1/LifeSketch", 420 | Value = "What a long and colorful life this person had!\nDetails are numerous and humorous.", 421 | }, 422 | }, 423 | }, 424 | }, 425 | }; 426 | } 427 | 428 | public static Gx.Gedcomx GetUpdatePersonLifeSketch(string personId, string factId) 429 | { 430 | var result = GetCreatePersonLifeSketch(personId); 431 | 432 | result.Persons[0].Facts[0].Id = factId; 433 | 434 | return result; 435 | } 436 | 437 | public static string GetFactId(Person person, string factType) 438 | { 439 | string result = null; 440 | 441 | if (person != null && person.Facts != null) 442 | { 443 | result = person.Facts.Where(x => x.Type == factType).Select(x => x.Id).FirstOrDefault(); 444 | } 445 | 446 | return result; 447 | } 448 | 449 | public static Fact GetMarriageFact() 450 | { 451 | return new Fact() 452 | { 453 | Attribution = new Attribution() 454 | { 455 | ChangeMessage = "Change message", 456 | }, 457 | KnownType = Gx.Types.FactType.Marriage, 458 | Date = new DateInfo() 459 | { 460 | Original = "3 Apr 1930", 461 | Formal = "+1930", 462 | }, 463 | Place = new PlaceReference() 464 | { 465 | Original = "Moscow, Russia", 466 | }, 467 | }; 468 | } 469 | 470 | public static Relationship GetCreateInvalidRelationship() 471 | { 472 | return (Relationship)new Relationship().SetLink("relationship", new Uri("https://sandbox.familysearch.org/platform/tree/couple-relationships/XXX-XXXX")); 473 | } 474 | 475 | public static Fact GetBiologicalParentFact() 476 | { 477 | return new Fact() 478 | { 479 | Attribution = new Attribution() 480 | { 481 | ChangeMessage = "Change message", 482 | }, 483 | KnownType = Gx.Types.FactType.BiologicalParent, 484 | }; 485 | } 486 | 487 | public static Name GetCreateName(String name, NameType type, bool preferred) 488 | { 489 | var nameParts = GetNameParts(name); 490 | return new Name() 491 | { 492 | KnownType = type, 493 | NameForms = new List() 494 | { 495 | new NameForm() 496 | { 497 | FullText = name, 498 | Parts = nameParts, 499 | }, 500 | }, 501 | Preferred = preferred, 502 | }; 503 | } 504 | 505 | public static List GetNameParts(String name) 506 | { 507 | var result = new List(); 508 | var parts = name.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 509 | 510 | foreach (var part in parts) 511 | { 512 | if (result.Count < parts.Length - 1) 513 | { 514 | result.Add(new NamePart() { KnownType = NamePartType.Given, Value = part }); 515 | } 516 | else 517 | { 518 | result.Add(new NamePart() { KnownType = NamePartType.Surname, Value = part }); 519 | } 520 | } 521 | 522 | return result; 523 | } 524 | 525 | public static SourceDescription GetCreateSourceDescription() 526 | { 527 | return new SourceDescription() 528 | .SetCitation("\"United States Census, 1900.\" database and digital images, FamilySearch (https://www.familysearch.org/: accessed 17 Mar 2012), Ethel Hollivet, 1900; citing United States Census Office, Washington, D.C., 1900 Population Census Schedules, Los Angeles, California, population schedule, Los Angeles Ward 6, Enumeration District 58, p. 20B, dwelling 470, family 501, FHL microfilm 1,240,090; citing NARA microfilm publication T623, roll 90.") 529 | .SetTitle("1900 US Census, Ethel Hollivet") 530 | .SetNote("Ethel Hollivet (line 75) with husband Albert Hollivet (line 74); also in the dwelling: step-father Joseph E Watkins (line 72), mother Lina Watkins (line 73), and grandmother -- Lina's mother -- Mary Sasnett (line 76). Albert's mother and brother also appear on this page -- Emma Hollivet (line 68), and Eddie (line 69).") 531 | .SetAttribution(new Attribution() 532 | .SetContributor(new ResourceReference("https://api.familysearch.org/platform/users/agents/MM6M-8QJ").SetResourceId("MM6M-8QJ")) 533 | .SetModified(DateTime.Now) 534 | .SetChangeMessage("This is the change message")); 535 | } 536 | 537 | public static SourceDescription GetCreateUserSourceDescription(string memoryUri) 538 | { 539 | return new SourceDescription() 540 | { 541 | About = memoryUri, 542 | Titles = new List() 543 | { 544 | new TextValue() 545 | { 546 | Value = "Grandpa's Birth Certificate", 547 | } 548 | }, 549 | Notes = new List() 550 | { 551 | new Note() 552 | { 553 | Text = "This is an image of Grandpa's birth certificate.", 554 | } 555 | } 556 | }; 557 | } 558 | 559 | public static Gx.Gedcomx GetGedcomxObjectForDeepCompare() 560 | { 561 | return new Gx.Gedcomx() 562 | { 563 | Persons = new List() { 564 | TestBacking.GetPersonForDeepCompare() 565 | }, 566 | Relationships = new List(), 567 | SourceDescriptions = new List(), 568 | Agents = new List(), 569 | Events = new List(), 570 | Places = new List(), 571 | Documents = new List(), 572 | Collections = new List(), 573 | Fields = new List(), 574 | RecordDescriptors = new List(), 575 | Links = new List(), 576 | ExtensionElementsXml = new List(), 577 | }; 578 | } 579 | } 580 | } 581 | -------------------------------------------------------------------------------- /Example1/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Example2.Core/Example2.Core.xproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | 577081fc-d9a1-4aff-b5df-fea1e8aa2234 11 | Example2.Core 12 | .\obj 13 | .\bin\ 14 | v4.6 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Example2.Core/Program.cs: -------------------------------------------------------------------------------- 1 | using Gedcomx.Api.Lite; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Example2.Core 8 | { 9 | public class Program 10 | { 11 | public static void Main(string[] args) 12 | { 13 | var ft = new FamilySearchSDK("username", "password", "applicationKey", "Example2.Core", "1.0.0", Gedcomx.Api.Lite.Environment.Integration); 14 | 15 | // Search for a Person 16 | var searchString = $" surname:Smith~ givenName:John~"; 17 | var encoded = Uri.EscapeDataString(searchString); 18 | var searchResult = ft.Get("/platform/tree/search?q=" + encoded, MediaType.X_GEDCOMX_ATOM_JSON).Result; 19 | 20 | var stopCount = 1000; 21 | var totalFetched = 0; 22 | while (searchResult != null && 23 | (totalFetched <= searchResult.results.Value || totalFetched > stopCount)) 24 | { 25 | totalFetched = (searchResult.index + searchResult.entries.Count); 26 | foreach (var e in searchResult.entries) 27 | { 28 | var p = e.content.gedcomx.persons[0]; 29 | Console.WriteLine($"{p.id} - {p.display.name} birthDate {p.display.birthDate} birthPlace {p.display.birthPlace}"); 30 | } 31 | 32 | // Advance & get the next search results if there. 33 | if (searchResult.results > (searchResult.index + searchResult.entries.Count)) 34 | { 35 | Console.WriteLine($"fetching another. total={totalFetched}"); 36 | searchResult = ft.Get(searchResult.links.next.href.Value, MediaType.X_GEDCOMX_ATOM_JSON).Result; 37 | } 38 | } 39 | 40 | Console.ReadLine(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Example2.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("Example2.Core")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("577081fc-d9a1-4aff-b5df-fea1e8aa2234")] 20 | -------------------------------------------------------------------------------- /Example2.Core/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | "buildOptions": { 4 | "emitEntryPoint": true 5 | }, 6 | 7 | "dependencies": { 8 | "Gedcomx.Api.Lite.Core": "1.0.0-*", 9 | "Microsoft.NETCore.App": { 10 | "type": "platform", 11 | "version": "1.0.0" 12 | } 13 | }, 14 | 15 | "frameworks": { 16 | "netcoreapp1.0": { 17 | "imports": "dnxcore50" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Core/Environment.cs: -------------------------------------------------------------------------------- 1 | namespace Gedcomx.Api.Lite 2 | { 3 | public enum Environment 4 | { 5 | Production, 6 | Beta, 7 | Integration 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Core/FamilySearchSDK.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Net; 5 | using System.Net.Http; 6 | using System.Net.Http.Headers; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Gedcomx.Api.Lite 11 | { 12 | public class FamilySearchSDK 13 | { 14 | private HttpClient _client = null; 15 | private Uri _baseUrl; 16 | private string _accessToken = null; 17 | 18 | /// 19 | /// Access Token for instancing other SDKs without having to authenticate 20 | /// 21 | public string AccessToken { get { return _accessToken; } } 22 | 23 | /// 24 | /// Main Constructor taking in credentials and supplying a client to make authenticated calls with. 25 | /// 26 | /// a user name 27 | /// the password for the user 28 | /// the application key, client key or developer key as refered to in other documentation 29 | /// the application name preferably from the dev registration site, but could be anything header friendly 30 | /// the version of the application for debugging purposes such as 1.0.0 31 | /// the environment such as integration (was sandbox), beta and production 32 | public FamilySearchSDK(string username, string password, string applicationKey, string applicationName, string version, 33 | Environment environment = Environment.Integration) 34 | { 35 | IDictionary formData = new Dictionary(); 36 | formData.Add("grant_type", "password"); 37 | formData.Add("username", username); 38 | formData.Add("password", password); 39 | formData.Add("client_id", applicationKey); 40 | 41 | GetAccessToken(formData, environment); 42 | 43 | InitClient(applicationName, version, applicationKey, environment); 44 | } 45 | 46 | /// 47 | /// Secondary constructor taking in the authentication token and supplying an internal authenticated client 48 | /// 49 | /// the access token supplied by a another family search sdk instance 50 | /// the application key, client key or developer key as refered to in other documentation 51 | /// the application name preferably from the dev registration site, but could be anything header friendly 52 | /// the version of the application for debugging purposes such as 1.0.0 53 | /// the environment such as integration (was sandbox), beta and production 54 | public FamilySearchSDK(string accessToken, string applicationKey, string applicationName, string version, 55 | Environment environment = Environment.Integration) 56 | { 57 | _accessToken = accessToken; 58 | InitClient(applicationName, version, applicationKey, environment); 59 | } 60 | 61 | private void InitClient(string applicationName, string version, string applicationKey, Environment environment) 62 | { 63 | switch (environment) 64 | { 65 | case Environment.Production: 66 | _baseUrl = new Uri("https://api.familysearch.org/"); 67 | break; 68 | case Environment.Beta: 69 | _baseUrl = new Uri("https://apibeta.familysearch.org/"); 70 | break; 71 | case Environment.Integration: 72 | _baseUrl = new Uri("https://api-integ.familysearch.org/"); 73 | break; 74 | default: // Do nothing 75 | throw new Exception("Unexpected environment"); 76 | } 77 | 78 | var cookieContainer = new CookieContainer(); 79 | _client = new HttpClient() { BaseAddress = _baseUrl }; 80 | _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken); 81 | 82 | // Add User Agent Details 83 | _client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(new ProductHeaderValue(applicationName, version))); 84 | _client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(new ProductHeaderValue(applicationKey))); 85 | } 86 | 87 | private static string GetAcceptContentType(MediaType mediaType) 88 | { 89 | switch (mediaType) 90 | { 91 | case MediaType.APPLICATION_JSON: 92 | return "application/json"; 93 | case MediaType.X_GEDCOMX_v1_JSON: 94 | return "application/x-gedcomx-v1+json"; 95 | case MediaType.X_GEDCOMX_RECORDS_v1_JSON: 96 | return "application/x-gedcomx-records-v1+json"; 97 | case MediaType.X_GEDCOMX_ATOM_JSON: 98 | return "application/x-gedcomx-atom+json"; 99 | case MediaType.X_FS_v1_JSON: 100 | return "application/x-fs-v1+json"; 101 | default: 102 | throw new Exception("Bad MediaType"); 103 | } 104 | } 105 | 106 | private string SetMediaType(MediaType mediaType) 107 | { 108 | var type = GetAcceptContentType(mediaType); 109 | _client.DefaultRequestHeaders.Accept.Clear(); 110 | _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(type)); 111 | return type; 112 | } 113 | 114 | private void GetAccessToken(IDictionary formData, Environment environment) 115 | { 116 | using (var httpClient = new HttpClient()) 117 | { 118 | using (var content = new FormUrlEncodedContent(formData)) 119 | { 120 | content.Headers.Clear(); 121 | content.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); 122 | httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 123 | 124 | string url = ""; 125 | switch (environment) 126 | { 127 | case Environment.Production: 128 | //url = "https://integration.familysearch.org/cis-web/oauth2/v3/token"; 129 | url = "https://ident.familysearch.org/cis-web/oauth2/v3/token"; 130 | break; 131 | case Environment.Beta: 132 | url = "https://identbeta.familysearch.org/cis-web/oauth2/v3/token"; 133 | break; 134 | case Environment.Integration: 135 | url = "https://identint.familysearch.org/cis-web/oauth2/v3/token"; 136 | break; 137 | default: // Do nothing 138 | throw new Exception("Unexpected environment"); 139 | } 140 | 141 | var response = httpClient.PostAsync(url, content).Result; 142 | 143 | if ((int)response.StatusCode >= 200 && (int)response.StatusCode < 300) 144 | { 145 | var accessToken = JsonConvert.DeserializeObject>(response.Content.ReadAsStringAsync().Result); 146 | 147 | if (accessToken.ContainsKey("access_token")) 148 | { 149 | _accessToken = accessToken["access_token"] as string; 150 | } 151 | 152 | if (_accessToken == null && accessToken.ContainsKey("token")) 153 | { 154 | //workaround to accommodate providers that were built on an older version of the oauth2 specification. 155 | _accessToken = accessToken["token"] as string; 156 | } 157 | 158 | if (_accessToken == null) 159 | { 160 | throw new Exception("Illegal access token response: no access_token provided."); 161 | } 162 | } 163 | else 164 | { 165 | throw new Exception("Unable to obtain an access token. Check username, password and applicationKey"); 166 | } 167 | } 168 | } 169 | } 170 | 171 | /// 172 | /// Adds the specified header and its values into the System.Net.Http.Headers.HttpHeaders collection 173 | /// 174 | /// the name of the value 175 | /// the value of the name 176 | public void AddClientHeader(string name, string value) 177 | { 178 | _client.DefaultRequestHeaders.Add(name, value); 179 | } 180 | 181 | /// 182 | /// Adds the specified header and its values into the System.Net.Http.Headers.HttpHeaders collection 183 | /// 184 | /// the name of the value 185 | /// the values of the name 186 | public void AddClientHeader(string name, IEnumerable values) 187 | { 188 | _client.DefaultRequestHeaders.Add(name, values); 189 | } 190 | 191 | /// 192 | /// Gets any content as a dynamic from the api route passed in by media type 193 | /// 194 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 195 | /// the media type defining the type of content expected of and enumerable MediaType 196 | /// Task containing dynamic object ready for referencing 197 | public async Task Get(string apiRoute, MediaType mediaType = MediaType.APPLICATION_JSON) 198 | { 199 | SetMediaType(mediaType); 200 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 201 | var response = await _client.GetAsync(url).ConfigureAwait(false); 202 | var s = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync(); 203 | return JsonConvert.DeserializeObject(s); 204 | } 205 | 206 | /// 207 | /// Gets any content as an object T from the api route passed in by media type 208 | /// 209 | /// 210 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 211 | /// the media type defining the type of content expected of and enumerable MediaType 212 | /// Task containing object T ready for referencing 213 | public async Task Get(string apiRoute, MediaType mediaType = MediaType.APPLICATION_JSON) 214 | { 215 | SetMediaType(mediaType); 216 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 217 | var response = await _client.GetAsync(url).ConfigureAwait(false); 218 | var s = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync(); 219 | return JsonConvert.DeserializeObject(s); 220 | } 221 | 222 | public async Task Head(string apiRoute, MediaType mediaType = MediaType.APPLICATION_JSON) 223 | { 224 | SetMediaType(mediaType); 225 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 226 | return await _client.GetAsync(url).ConfigureAwait(false); 227 | } 228 | 229 | /// 230 | /// Puts any string content from the api route passed in by media type. 231 | /// 232 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 233 | /// the string content likely as a JSON string 234 | /// the media type defining the type of content expected of and enumerable MediaType 235 | /// a dynamic object defined by the apiRoute 236 | public async Task Put(string apiRoute, string content, MediaType mediaType) 237 | { 238 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 239 | var body = new StringContent(content, Encoding.UTF8, SetMediaType(mediaType)); 240 | var response = await _client.PutAsync(url, body).ConfigureAwait(false); 241 | var s = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync(); 242 | if (string.IsNullOrEmpty(s)) 243 | { 244 | return response; // No content is sent back, so send the response. 245 | } 246 | return JsonConvert.DeserializeObject(s); 247 | } 248 | 249 | /// 250 | /// Puts any string content from the api route passed in by media type. 251 | /// 252 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 253 | /// the string content likely as a JSON string 254 | /// the media type defining the type of content expected of and enumerable MediaType 255 | /// an object T defined by the apiRoute 256 | public async Task Put(string apiRoute, string content, MediaType mediaType) 257 | { 258 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 259 | var body = new StringContent(content, Encoding.UTF8, SetMediaType(mediaType)); 260 | var response = await _client.PutAsync(url, body).ConfigureAwait(false); 261 | var s = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync(); 262 | return JsonConvert.DeserializeObject(s); 263 | } 264 | 265 | /// 266 | /// Puts any string content from the api route passed in by media type. 267 | /// 268 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 269 | /// the string content likely as a JSON string 270 | /// the media type defining the type of content expected of and enumerable MediaType 271 | /// a dynamic object defined by the apiRoute 272 | public async Task Post(string apiRoute, string content, MediaType mediaType) 273 | { 274 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 275 | var body = new StringContent(content, Encoding.UTF8, SetMediaType(mediaType)); 276 | var response = await _client.PostAsync(url, body).ConfigureAwait(false); 277 | var s = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync(); 278 | if (string.IsNullOrEmpty(s)) 279 | { 280 | return response; // No content is sent back, so send the response. 281 | } 282 | return JsonConvert.DeserializeObject(s); 283 | } 284 | 285 | /// 286 | /// Posts any string content from the api route passed in by media type. 287 | /// 288 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 289 | /// the string content likely as a JSON string 290 | /// the media type defining the type of content expected of and enumerable MediaType 291 | /// an object T defined by the apiRoute 292 | public async Task Post(string apiRoute, string content, MediaType mediaType) 293 | { 294 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 295 | var body = new StringContent(content, Encoding.UTF8, SetMediaType(mediaType)); 296 | var response = await _client.PostAsync(url, body).ConfigureAwait(false); 297 | var s = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync(); 298 | return JsonConvert.DeserializeObject(s); 299 | } 300 | 301 | /// 302 | /// Deletes any content from the api route passed in 303 | /// 304 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 305 | /// 306 | public async Task Delete(string apiRoute) 307 | { 308 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 309 | var response = await _client.DeleteAsync(url).ConfigureAwait(false); 310 | var s = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync(); 311 | if (string.IsNullOrEmpty(s)) 312 | { 313 | return response; // No content is sent back, so send the response. 314 | } 315 | return JsonConvert.DeserializeObject(s); 316 | } 317 | 318 | #region Uncommon Calls 319 | 320 | /// 321 | /// (Uncommon) Posts any string content from the api route passed in by media type. 322 | /// 323 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 324 | /// the string content likely as a JSON string 325 | /// the media type defining the type of content expected of and enumerable MediaType 326 | /// only the response portion of the message 327 | public async Task Post_GetResponse(string apiRoute, string content, MediaType mediaType) 328 | { 329 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 330 | var body = new StringContent(content, Encoding.UTF8, SetMediaType(mediaType)); 331 | return await _client.PostAsync(url, body).ConfigureAwait(false); 332 | } 333 | 334 | /// 335 | /// (Uncommon) Posts any string content from the api route passed in by media type. 336 | /// 337 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 338 | /// the string content likely as a JSON string 339 | /// the media type defining the type of content expected of and enumerable MediaType 340 | /// only the content portion of the message 341 | public async Task Post_GetContent(string apiRoute, string content, MediaType mediaType) 342 | { 343 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 344 | var body = new StringContent(content, Encoding.UTF8, SetMediaType(mediaType)); 345 | var response = await _client.PostAsync(url, body).ConfigureAwait(false); 346 | var s = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync(); 347 | return JsonConvert.DeserializeObject(s); 348 | } 349 | 350 | /// 351 | /// (Uncommon) Puts any string content from the api route passed in by media type. 352 | /// 353 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 354 | /// the string content likely as a JSON string 355 | /// the media type defining the type of content expected of and enumerable MediaType 356 | /// only the response portion of the message 357 | public async Task Put_GetResponse(string apiRoute, string content, MediaType mediaType) 358 | { 359 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 360 | var body = new StringContent(content, Encoding.UTF8, SetMediaType(mediaType)); 361 | return await _client.PutAsync(url, body).ConfigureAwait(false); 362 | } 363 | 364 | /// 365 | /// (Uncommon) Puts any string content from the api route passed in by media type. 366 | /// 367 | /// any family search api route such as /platform/tree/persons/L11X-X11 refer to www.familysearch.org/developers/docs/api/resources 368 | /// the string content likely as a JSON string 369 | /// the media type defining the type of content expected of and enumerable MediaType 370 | /// only the content portion of the message 371 | public async Task Put_GetContent(string apiRoute, string content, MediaType mediaType) 372 | { 373 | var url = new Uri(_baseUrl, apiRoute.Replace(_baseUrl.OriginalString, "")); 374 | var body = new StringContent(content, Encoding.UTF8, SetMediaType(mediaType)); 375 | var response = await _client.PutAsync(url, body).ConfigureAwait(false); 376 | var s = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync(); 377 | return JsonConvert.DeserializeObject(s); 378 | } 379 | 380 | #endregion 381 | } 382 | } 383 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Core/Gedcomx.Api.Lite.Core.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | 1.0.1 6 | $title$ 7 | $author$ 8 | $author$ 9 | https://github.com/FamilySearch/csharp-lite 10 | false 11 | This is the C# Lite Core version to contact the Family Search GEDCOM X APIs. It will help with authentication and media types through HttpClient. 12 | Update to Proper Repo and copyright 13 | Copyright 2017 14 | 15 | 16 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Core/Gedcomx.Api.Lite.Core.xproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 8335f096-efdd-4380-b576-032c25d0939a 10 | Gedcomx.Api.Lite 11 | .\obj 12 | .\bin\ 13 | v4.6 14 | 15 | 16 | 2.0 17 | 18 | 19 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Core/MediaType.cs: -------------------------------------------------------------------------------- 1 | namespace Gedcomx.Api.Lite 2 | { 3 | /// 4 | /// A collection of accept or content types to use in REST API requests. 5 | /// 6 | public enum MediaType 7 | { 8 | X_GEDCOMX_v1_JSON, 9 | X_GEDCOMX_RECORDS_v1_JSON, 10 | X_GEDCOMX_ATOM_JSON, 11 | APPLICATION_JSON, 12 | X_FS_v1_JSON, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("Family Search")] 10 | [assembly: AssemblyProduct("Gedcomx.Api.Lite.Core")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("8335f096-efdd-4380-b576-032c25d0939a")] 20 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Core/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": {} 3 | } -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Core/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.1-*", 3 | 4 | "dependencies": { 5 | "NETStandard.Library": "1.6.0", 6 | "Newtonsoft.Json": "9.0.1" 7 | }, 8 | 9 | "frameworks": { 10 | "netstandard1.6": { 11 | "imports": "dnxcore50" 12 | } 13 | }, 14 | "scripts": { 15 | "postcompile": [ 16 | "dotnet pack --no-build --configuration %compile:Configuration%" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Tests/AuthenticationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Gedcomx.Api.Lite.Tests.Properties; 4 | 5 | namespace Gedcomx.Api.Lite.Tests 6 | { 7 | [TestClass] 8 | public class AuthenticationTests 9 | { 10 | [TestMethod] 11 | public void AuthenticateTest() 12 | { 13 | var ft = new FamilySearchSDK(Settings.Default.UserName, Settings.Default.Password, Settings.Default.ApplicationKey, 14 | TestBacking.AppName, TestBacking.AppVersion, Environment.Integration); 15 | 16 | Assert.IsNotNull(ft.AccessToken, "Authentication needs an access token. Check username and password"); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Tests/Gedcomx.Api.Lite.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {8371A813-0389-4A98-B9D7-986BF98C5AD4} 7 | Library 8 | Properties 9 | Gedcomx.Api.Lite.Tests 10 | Gedcomx.Api.Lite.Tests 11 | v4.6 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | ..\packages\Gedcomx.Model.1.0.6144.20322\lib\net45\Gedcomx.Model.dll 40 | True 41 | 42 | 43 | ..\packages\Gedcomx.Model.Fs.1.0.6144.20322\lib\net45\Gedcomx.Model.Fs.dll 44 | True 45 | 46 | 47 | ..\packages\Gedcomx.Model.Rs.1.0.6144.20322\lib\net45\Gedcomx.Model.Rs.dll 48 | True 49 | 50 | 51 | 52 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 53 | True 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | True 77 | True 78 | Settings.settings 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | SettingsSingleFileGenerator 87 | Settings.Designer.cs 88 | 89 | 90 | 91 | 92 | {dc9c289b-4ecc-41c5-8845-d29bedacd45e} 93 | Gedcomx.Api.Lite 94 | 95 | 96 | 97 | 98 | 99 | 100 | False 101 | 102 | 103 | False 104 | 105 | 106 | False 107 | 108 | 109 | False 110 | 111 | 112 | 113 | 114 | 115 | 116 | 123 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Tests/PersonTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Gedcomx.Api.Lite.Tests.Properties; 4 | using Newtonsoft.Json; 5 | using System.Threading.Tasks; 6 | using System.Linq; 7 | using System.Net; 8 | 9 | namespace Gedcomx.Api.Lite.Tests 10 | { 11 | [TestClass] 12 | public class PersonTests 13 | { 14 | [TestMethod] 15 | public void PostAPerson() 16 | { 17 | var ft = new FamilySearchSDK(Settings.Default.UserName, Settings.Default.Password, Settings.Default.ApplicationKey, 18 | TestBacking.AppName, TestBacking.AppVersion, Gedcomx.Api.Lite.Environment.Integration); 19 | 20 | // Create a Person 21 | var gedcomx = new Gx.Gedcomx(); 22 | gedcomx.AddPerson(TestBacking.GetCreateMalePerson()); 23 | var postResults = ft.Post("/platform/tree/persons", JsonConvert.SerializeObject(gedcomx), MediaType.X_GEDCOMX_v1_JSON).Result; 24 | 25 | // Now get the new person. 26 | string personId = ((string[])postResults.Headers.Location.ToString().Split('/')).Last(); 27 | var response = ft.Get("/platform/tree/persons/" + personId).Result; 28 | 29 | Assert.IsTrue(postResults.StatusCode == HttpStatusCode.Created, "Posting should flag the reply as created"); 30 | } 31 | 32 | [TestMethod] 33 | public void GetAPerson() 34 | { 35 | var ft = new FamilySearchSDK(Settings.Default.UserName, Settings.Default.Password, Settings.Default.ApplicationKey, 36 | TestBacking.AppName, TestBacking.AppVersion, Gedcomx.Api.Lite.Environment.Integration); 37 | 38 | // Create a Person 39 | var gedcomx = new Gx.Gedcomx(); 40 | gedcomx.AddPerson(TestBacking.GetCreateMalePerson()); 41 | var postResults = ft.Post("/platform/tree/persons", JsonConvert.SerializeObject(gedcomx), MediaType.X_GEDCOMX_v1_JSON).Result; 42 | 43 | // Now get the new person. 44 | string personId = ((string[])postResults.Headers.Location.ToString().Split('/')).Last(); 45 | var response = ft.Get("/platform/tree/persons/" + personId).Result; 46 | 47 | Assert.IsNotNull(response.persons, "resonse should contain a person"); 48 | } 49 | 50 | [TestMethod] 51 | public void DeleteAPerson() 52 | { 53 | var ft = new FamilySearchSDK(Settings.Default.UserName, Settings.Default.Password, Settings.Default.ApplicationKey, 54 | TestBacking.AppName, TestBacking.AppVersion, Gedcomx.Api.Lite.Environment.Integration); 55 | 56 | // Create a Person 57 | var gedcomx = new Gx.Gedcomx(); 58 | gedcomx.AddPerson(TestBacking.GetCreateMalePerson()); 59 | var postResults = ft.Post("/platform/tree/persons", JsonConvert.SerializeObject(gedcomx), MediaType.X_GEDCOMX_v1_JSON).Result; 60 | 61 | // Now get the new person. 62 | string personId = ((string[])postResults.Headers.Location.ToString().Split('/')).Last(); 63 | var response = ft.Delete("/platform/tree/persons/" + personId).Result; 64 | 65 | Assert.IsTrue(postResults.StatusCode == HttpStatusCode.NoContent, "Resonse should indicate deletion successfully"); 66 | } 67 | 68 | [TestMethod] 69 | public void ReadHeadForAPerson() 70 | { 71 | var ft = new FamilySearchSDK(Settings.Default.UserName, Settings.Default.Password, Settings.Default.ApplicationKey, 72 | TestBacking.AppName, TestBacking.AppVersion, Gedcomx.Api.Lite.Environment.Integration); 73 | 74 | // Create a Person 75 | var gedcomx = new Gx.Gedcomx(); 76 | gedcomx.AddPerson(TestBacking.GetCreateMalePerson()); 77 | var postResults = ft.Post("/platform/tree/persons", JsonConvert.SerializeObject(gedcomx), MediaType.X_GEDCOMX_v1_JSON).Result; 78 | 79 | // Now get the new person. 80 | string personId = ((string[])postResults.Headers.Location.ToString().Split('/')).Last(); 81 | var response = ft.Head("/platform/tree/persons/" + personId, MediaType.APPLICATION_JSON).Result; 82 | 83 | Assert.IsTrue(response.StatusCode == HttpStatusCode.OK, "Resonse should indicate header retreived successfully"); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Tests/PortraitTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Gedcomx.Api.Lite.Tests.Properties; 4 | using Newtonsoft.Json; 5 | using System.Net; 6 | using System.Linq; 7 | 8 | namespace Gedcomx.Api.Lite.Tests 9 | { 10 | [TestClass] 11 | public class PortraitTests 12 | { 13 | [TestMethod] 14 | public void GetAPortrait() 15 | { 16 | var ft = new FamilySearchSDK(Settings.Default.UserName, Settings.Default.Password, Settings.Default.ApplicationKey, 17 | TestBacking.AppName, TestBacking.AppVersion, Gedcomx.Api.Lite.Environment.Integration); 18 | 19 | // Create a Person 20 | var gedcomx = new Gx.Gedcomx(); 21 | gedcomx.AddPerson(TestBacking.GetCreateMalePerson()); 22 | var postResults = ft.Post("/platform/tree/persons", JsonConvert.SerializeObject(gedcomx), MediaType.X_GEDCOMX_v1_JSON).Result; 23 | 24 | // Now get the new person. 25 | string personId = ((string[])postResults.Headers.Location.ToString().Split('/')).Last(); 26 | var portraitResponse = ft.Get($"/platform/tree/persons/{personId}/portrait", MediaType.X_FS_v1_JSON); 27 | var portrait = portraitResponse.Result; 28 | 29 | Assert.IsTrue(postResults.StatusCode == HttpStatusCode.Created, "Portrait should flag the reply as created"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Gedcomx.Api.Lite.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Gedcomx.Api.Lite.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8371a813-0389-4a98-b9d7-986bf98c5ad4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Tests/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Gedcomx.Api.Lite.Tests.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.ApplicationScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("username")] 29 | public string UserName { 30 | get { 31 | return ((string)(this["UserName"])); 32 | } 33 | } 34 | 35 | [global::System.Configuration.ApplicationScopedSettingAttribute()] 36 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 37 | [global::System.Configuration.DefaultSettingValueAttribute("password")] 38 | public string Password { 39 | get { 40 | return ((string)(this["Password"])); 41 | } 42 | } 43 | 44 | [global::System.Configuration.ApplicationScopedSettingAttribute()] 45 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 46 | [global::System.Configuration.DefaultSettingValueAttribute("applicationKey")] 47 | public string ApplicationKey { 48 | get { 49 | return ((string)(this["ApplicationKey"])); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Tests/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | username 7 | 8 | 9 | password 10 | 11 | 12 | applicationKey 13 | 14 | 15 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Tests/TestBacking.cs: -------------------------------------------------------------------------------- 1 | using Gx.Common; 2 | using Gx.Conclusion; 3 | using Gx.Source; 4 | using Gx.Types; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | namespace Gedcomx.Api.Lite.Tests 10 | { 11 | public static class TestBacking 12 | { 13 | public const string AppName = "Gedcomx.Api.Lite.Tests"; 14 | public const string AppVersion = "1.0.0"; 15 | 16 | public static Person GetPersonForDeepCompare() 17 | { 18 | return new Person() 19 | { 20 | Living = false, 21 | Gender = new Gender() 22 | { 23 | KnownType = Gx.Types.GenderType.Male, 24 | Fields = new List(), 25 | Sources = new List(), 26 | Notes = new List(), 27 | Links = new List(), 28 | ExtensionElementsXml = new List(), 29 | }, 30 | Names = new List() 31 | { 32 | new Name() 33 | { 34 | KnownType = Gx.Types.NameType.BirthName, 35 | NameForms = new List() 36 | { 37 | new NameForm() 38 | { 39 | FullText = "GedcomX User", 40 | Parts = new List() 41 | { 42 | new NamePart() 43 | { 44 | KnownType = Gx.Types.NamePartType.Given, 45 | Value = "GedcomX", 46 | ExtensionElementsXml = new List(), 47 | Fields = new List(), 48 | Qualifiers = new List(), 49 | }, 50 | new NamePart() 51 | { 52 | KnownType = Gx.Types.NamePartType.Surname, 53 | Value = "User", 54 | ExtensionElementsXml = new List(), 55 | Fields = new List(), 56 | Qualifiers = new List(), 57 | }, 58 | }, 59 | ExtensionElementsXml = new List(), 60 | Fields = new List(), 61 | }, 62 | new NameForm() 63 | { 64 | FullText = "GedcomX2 User", 65 | Parts = new List() 66 | { 67 | new NamePart() 68 | { 69 | KnownType = Gx.Types.NamePartType.Given, 70 | Value = "GedcomX2", 71 | ExtensionElementsXml = new List(), 72 | Fields = new List(), 73 | Qualifiers = new List(), 74 | }, 75 | new NamePart() 76 | { 77 | KnownType = Gx.Types.NamePartType.Surname, 78 | Value = "User", 79 | ExtensionElementsXml = new List(), 80 | Fields = new List(), 81 | Qualifiers = new List(), 82 | }, 83 | }, 84 | ExtensionElementsXml = new List(), 85 | Fields = new List(), 86 | }, 87 | }, 88 | Preferred = true, 89 | Sources = new List(), 90 | Notes = new List(), 91 | Links = new List(), 92 | ExtensionElementsXml = new List(), 93 | }, 94 | }, 95 | Facts = new List() 96 | { 97 | new Fact() 98 | { 99 | KnownType = Gx.Types.FactType.Birth, 100 | Date = new DateInfo() 101 | { 102 | Original = "June 1800", 103 | NormalizedExtensions = new List(), 104 | Fields = new List(), 105 | ExtensionElementsXml = new List(), 106 | }, 107 | Place = new PlaceReference() 108 | { 109 | Original = "Provo, Utah, Utah, United States", 110 | NormalizedExtensions = new List(), 111 | Fields = new List(), 112 | ExtensionElementsXml = new List(), 113 | }, 114 | Qualifiers = new List(), 115 | Fields = new List(), 116 | Sources = new List(), 117 | Notes = new List(), 118 | Links = new List(), 119 | ExtensionElementsXml = new List(), 120 | }, 121 | new Fact() 122 | { 123 | KnownType = Gx.Types.FactType.Christening, 124 | Date = new DateInfo() 125 | { 126 | Original = "1802", 127 | NormalizedExtensions = new List(), 128 | Fields = new List(), 129 | ExtensionElementsXml = new List(), 130 | }, 131 | Place = new PlaceReference() 132 | { 133 | Original = "American Fork, Utah, Utah, United States", 134 | NormalizedExtensions = new List(), 135 | Fields = new List(), 136 | ExtensionElementsXml = new List(), 137 | }, 138 | Qualifiers = new List(), 139 | Fields = new List(), 140 | Sources = new List(), 141 | Notes = new List(), 142 | Links = new List(), 143 | ExtensionElementsXml = new List(), 144 | }, 145 | new Fact() 146 | { 147 | KnownType = Gx.Types.FactType.Residence, 148 | Date = new DateInfo() 149 | { 150 | Original = "4 Jan 1896", 151 | NormalizedExtensions = new List(), 152 | Fields = new List(), 153 | ExtensionElementsXml = new List(), 154 | }, 155 | Place = new PlaceReference() 156 | { 157 | Original = "Provo, Utah, Utah, United States", 158 | NormalizedExtensions = new List(), 159 | Fields = new List(), 160 | ExtensionElementsXml = new List(), 161 | }, 162 | Qualifiers = new List(), 163 | Fields = new List(), 164 | Sources = new List(), 165 | Notes = new List(), 166 | Links = new List(), 167 | ExtensionElementsXml = new List(), 168 | }, 169 | new Fact() 170 | { 171 | KnownType = Gx.Types.FactType.Death, 172 | Date = new DateInfo() 173 | { 174 | Original = "July 14, 1900", 175 | NormalizedExtensions = new List(), 176 | Fields = new List(), 177 | ExtensionElementsXml = new List(), 178 | }, 179 | Place = new PlaceReference() 180 | { 181 | Original = "Provo, Utah, Utah, United States", 182 | NormalizedExtensions = new List(), 183 | Fields = new List(), 184 | ExtensionElementsXml = new List(), 185 | }, 186 | Qualifiers = new List(), 187 | Fields = new List(), 188 | Sources = new List(), 189 | Notes = new List(), 190 | Links = new List(), 191 | ExtensionElementsXml = new List(), 192 | }, 193 | new Fact() 194 | { 195 | KnownType = Gx.Types.FactType.Burial, 196 | Date = new DateInfo() 197 | { 198 | Original = "1900", 199 | NormalizedExtensions = new List(), 200 | Fields = new List(), 201 | ExtensionElementsXml = new List(), 202 | }, 203 | Place = new PlaceReference() 204 | { 205 | Original = "Sandy, Salt Lake, Utah, United States", 206 | NormalizedExtensions = new List(), 207 | Fields = new List(), 208 | ExtensionElementsXml = new List(), 209 | }, 210 | Qualifiers = new List(), 211 | Fields = new List(), 212 | Sources = new List(), 213 | Notes = new List(), 214 | Links = new List(), 215 | ExtensionElementsXml = new List(), 216 | } 217 | }, 218 | ExtensionElementsXml = new List(), 219 | Fields = new List(), 220 | Evidence = new List(), 221 | Media = new List(), 222 | Identifiers = new List(), 223 | Sources = new List(), 224 | Notes = new List(), 225 | Links = new List(), 226 | DiscussionReferences = new List(), 227 | }; 228 | } 229 | 230 | public static Person GetCreateMalePerson() 231 | { 232 | return new Person() 233 | .SetLiving(false) 234 | .SetGender(new Gender().SetType(GenderType.Male)) 235 | .SetName(new Name() 236 | .SetType(NameType.BirthName) 237 | .SetNameForm(new NameForm() 238 | .SetFullText("GedcomX User") 239 | .SetPart(new NamePart(NamePartType.Given, "GedcomX")) 240 | .SetPart(new NamePart(NamePartType.Surname, "User"))) 241 | .SetNameForm(new NameForm() 242 | .SetFullText("GedcomX2 User") 243 | .SetPart(new NamePart(NamePartType.Given, "GedcomX2")) 244 | .SetPart(new NamePart(NamePartType.Surname, "User"))) 245 | .SetPreferred(true)) 246 | .SetFact(new Fact() 247 | .SetType(FactType.Birth) 248 | .SetDate(new DateInfo().SetOriginal("June 1800")) 249 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 250 | .SetFact(new Fact() 251 | .SetType(FactType.Christening) 252 | .SetDate(new DateInfo().SetOriginal("1802")) 253 | .SetPlace(new PlaceReference().SetOriginal("American Fork, Utah, Utah, United States"))) 254 | .SetFact(new Fact() 255 | .SetType(FactType.Residence) 256 | .SetDate(new DateInfo().SetOriginal("4 Jan 1896")) 257 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 258 | .SetFact(new Fact() 259 | .SetType(FactType.Death) 260 | .SetDate(new DateInfo().SetOriginal("July 14, 1900")) 261 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 262 | .SetFact(new Fact() 263 | .SetType(FactType.Burial) 264 | .SetDate(new DateInfo().SetOriginal("1900")) 265 | .SetPlace(new PlaceReference().SetOriginal("Sandy, Salt Lake, Utah, United States"))); 266 | } 267 | 268 | public static Person GetCreateFemalePerson() 269 | { 270 | return new Person() 271 | .SetLiving(false) 272 | .SetGender(new Gender().SetType(GenderType.Female)) 273 | .SetName(new Name() 274 | .SetType(NameType.BirthName) 275 | .SetNameForm(new NameForm() 276 | .SetFullText("GedcomX User") 277 | .SetPart(new NamePart(NamePartType.Given, "GedcomX")) 278 | .SetPart(new NamePart(NamePartType.Surname, "User"))) 279 | .SetNameForm(new NameForm() 280 | .SetFullText("GedcomX2 User") 281 | .SetPart(new NamePart(NamePartType.Given, "GedcomX2")) 282 | .SetPart(new NamePart(NamePartType.Surname, "User"))) 283 | .SetPreferred(true)) 284 | .SetFact(new Fact() 285 | .SetType(FactType.Birth) 286 | .SetDate(new DateInfo().SetOriginal("June 1800")) 287 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 288 | .SetFact(new Fact() 289 | .SetType(FactType.Christening) 290 | .SetDate(new DateInfo().SetOriginal("1802")) 291 | .SetPlace(new PlaceReference().SetOriginal("American Fork, Utah, Utah, United States"))) 292 | .SetFact(new Fact() 293 | .SetType(FactType.Residence) 294 | .SetDate(new DateInfo().SetOriginal("4 Jan 1896")) 295 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 296 | .SetFact(new Fact() 297 | .SetType(FactType.Death) 298 | .SetDate(new DateInfo().SetOriginal("July 14, 1900")) 299 | .SetPlace(new PlaceReference().SetOriginal("Provo, Utah, Utah, United States"))) 300 | .SetFact(new Fact() 301 | .SetType(FactType.Burial) 302 | .SetDate(new DateInfo().SetOriginal("1900")) 303 | .SetPlace(new PlaceReference().SetOriginal("Sandy, Salt Lake, Utah, United States"))); 304 | } 305 | 306 | public static SourceReference GetPersonSourceReference() 307 | { 308 | return new SourceReference() 309 | .SetAttribution(new Attribution() 310 | .SetChangeMessage("Family is at the same address found in other sources associated with this family. Names are a good match. Estimated births are reasonable.")) 311 | .SetDescriptionRef("https://sandbox.familysearch.org/platform/sources/descriptions/MMH1-PNF"); 312 | } 313 | 314 | public static Person GetCreatePersonConclusion(string personId) 315 | { 316 | return new Person() 317 | { 318 | Id = personId, 319 | Facts = new List() 320 | { 321 | new Fact() 322 | { 323 | Attribution = new Attribution() 324 | { 325 | ChangeMessage = "Change message", 326 | }, 327 | KnownType = Gx.Types.FactType.Birth, 328 | Date = new DateInfo() 329 | { 330 | Original = "3 Apr 1836", 331 | Formal = "+1836", 332 | }, 333 | Place = new PlaceReference() 334 | { 335 | Original = "Moscow, Russia", 336 | }, 337 | } 338 | } 339 | }; 340 | } 341 | 342 | public static Person GetCreateDiscussionReference(string personId) 343 | { 344 | return new Person() 345 | { 346 | Id = personId, 347 | Attribution = new Attribution() 348 | { 349 | ChangeMessage = "Change message", 350 | }, 351 | // TODO: discussion-references 352 | }; 353 | } 354 | 355 | public static Note GetCreateNote() 356 | { 357 | return new Note() 358 | .SetSubject("Sample") 359 | .SetText("Sample note text " + DateTime.Now.Ticks) 360 | .SetAttribution(new Attribution() 361 | .SetContributor(new ResourceReference("https://api.familysearch.org/platform/users/agents/MM6M-8QJ").SetResourceId("MM6M-8QJ"))); 362 | } 363 | 364 | public static Fact GetBirthFact() 365 | { 366 | return new Fact() 367 | { 368 | Attribution = new Attribution() 369 | { 370 | ChangeMessage = "Change message", 371 | }, 372 | KnownType = Gx.Types.FactType.Birth, 373 | Date = new DateInfo() 374 | { 375 | Original = "3 Apr 1836", 376 | Formal = "+1836", 377 | }, 378 | Place = new PlaceReference() 379 | { 380 | Original = "Moscow, Russia", 381 | }, 382 | }; 383 | } 384 | 385 | public static Fact GetCustomFact() 386 | { 387 | return new Fact() 388 | { 389 | Attribution = new Attribution() 390 | { 391 | ChangeMessage = "Change message", 392 | }, 393 | Type = "data:,Eagle%20Scout", 394 | Qualifiers = new List() 395 | { 396 | new Qualifier() 397 | { 398 | Name = "http://www.familysearch.org/v1/Event", 399 | Value = bool.FalseString.ToLower(), 400 | }, 401 | }, 402 | }; 403 | } 404 | 405 | public static Gx.Gedcomx GetCreatePersonLifeSketch(string personId) 406 | { 407 | return new Gx.Gedcomx() 408 | { 409 | Persons = new List() 410 | { 411 | new Person() 412 | { 413 | Id = personId, 414 | Facts = new List() 415 | { 416 | new Fact() 417 | { 418 | Attribution = new Attribution() 419 | { 420 | ChangeMessage = "...change message...", 421 | }, 422 | Type = "http://www.familysearch.org/v1/LifeSketch", 423 | Value = "What a long and colorful life this person had!\nDetails are numerous and humorous.", 424 | }, 425 | }, 426 | }, 427 | }, 428 | }; 429 | } 430 | 431 | public static Gx.Gedcomx GetUpdatePersonLifeSketch(string personId, string factId) 432 | { 433 | var result = GetCreatePersonLifeSketch(personId); 434 | 435 | result.Persons[0].Facts[0].Id = factId; 436 | 437 | return result; 438 | } 439 | 440 | public static string GetFactId(Person person, string factType) 441 | { 442 | string result = null; 443 | 444 | if (person != null && person.Facts != null) 445 | { 446 | result = person.Facts.Where(x => x.Type == factType).Select(x => x.Id).FirstOrDefault(); 447 | } 448 | 449 | return result; 450 | } 451 | 452 | public static Fact GetMarriageFact() 453 | { 454 | return new Fact() 455 | { 456 | Attribution = new Attribution() 457 | { 458 | ChangeMessage = "Change message", 459 | }, 460 | KnownType = Gx.Types.FactType.Marriage, 461 | Date = new DateInfo() 462 | { 463 | Original = "3 Apr 1930", 464 | Formal = "+1930", 465 | }, 466 | Place = new PlaceReference() 467 | { 468 | Original = "Moscow, Russia", 469 | }, 470 | }; 471 | } 472 | 473 | public static Relationship GetCreateInvalidRelationship() 474 | { 475 | return (Relationship)new Relationship().SetLink("relationship", new Uri("https://sandbox.familysearch.org/platform/tree/couple-relationships/XXX-XXXX")); 476 | } 477 | 478 | public static Fact GetBiologicalParentFact() 479 | { 480 | return new Fact() 481 | { 482 | Attribution = new Attribution() 483 | { 484 | ChangeMessage = "Change message", 485 | }, 486 | KnownType = Gx.Types.FactType.BiologicalParent, 487 | }; 488 | } 489 | 490 | public static Name GetCreateName(String name, NameType type, bool preferred) 491 | { 492 | var nameParts = GetNameParts(name); 493 | return new Name() 494 | { 495 | KnownType = type, 496 | NameForms = new List() 497 | { 498 | new NameForm() 499 | { 500 | FullText = name, 501 | Parts = nameParts, 502 | }, 503 | }, 504 | Preferred = preferred, 505 | }; 506 | } 507 | 508 | public static List GetNameParts(String name) 509 | { 510 | var result = new List(); 511 | var parts = name.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 512 | 513 | foreach (var part in parts) 514 | { 515 | if (result.Count < parts.Length - 1) 516 | { 517 | result.Add(new NamePart() { KnownType = NamePartType.Given, Value = part }); 518 | } 519 | else 520 | { 521 | result.Add(new NamePart() { KnownType = NamePartType.Surname, Value = part }); 522 | } 523 | } 524 | 525 | return result; 526 | } 527 | 528 | public static SourceDescription GetCreateSourceDescription() 529 | { 530 | return new SourceDescription() 531 | .SetCitation("\"United States Census, 1900.\" database and digital images, FamilySearch (https://www.familysearch.org/: accessed 17 Mar 2012), Ethel Hollivet, 1900; citing United States Census Office, Washington, D.C., 1900 Population Census Schedules, Los Angeles, California, population schedule, Los Angeles Ward 6, Enumeration District 58, p. 20B, dwelling 470, family 501, FHL microfilm 1,240,090; citing NARA microfilm publication T623, roll 90.") 532 | .SetTitle("1900 US Census, Ethel Hollivet") 533 | .SetNote("Ethel Hollivet (line 75) with husband Albert Hollivet (line 74); also in the dwelling: step-father Joseph E Watkins (line 72), mother Lina Watkins (line 73), and grandmother -- Lina's mother -- Mary Sasnett (line 76). Albert's mother and brother also appear on this page -- Emma Hollivet (line 68), and Eddie (line 69).") 534 | .SetAttribution(new Attribution() 535 | .SetContributor(new ResourceReference("https://api.familysearch.org/platform/users/agents/MM6M-8QJ").SetResourceId("MM6M-8QJ")) 536 | .SetModified(DateTime.Now) 537 | .SetChangeMessage("This is the change message")); 538 | } 539 | 540 | public static SourceDescription GetCreateUserSourceDescription(string memoryUri) 541 | { 542 | return new SourceDescription() 543 | { 544 | About = memoryUri, 545 | Titles = new List() 546 | { 547 | new TextValue() 548 | { 549 | Value = "Grandpa's Birth Certificate", 550 | } 551 | }, 552 | Notes = new List() 553 | { 554 | new Note() 555 | { 556 | Text = "This is an image of Grandpa's birth certificate.", 557 | } 558 | } 559 | }; 560 | } 561 | 562 | public static Gx.Gedcomx GetGedcomxObjectForDeepCompare() 563 | { 564 | return new Gx.Gedcomx() 565 | { 566 | Persons = new List() { 567 | TestBacking.GetPersonForDeepCompare() 568 | }, 569 | Relationships = new List(), 570 | SourceDescriptions = new List(), 571 | Agents = new List(), 572 | Events = new List(), 573 | Places = new List(), 574 | Documents = new List(), 575 | Collections = new List(), 576 | Fields = new List(), 577 | RecordDescriptors = new List(), 578 | Links = new List(), 579 | ExtensionElementsXml = new List(), 580 | }; 581 | } 582 | } 583 | } 584 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | username 12 | 13 | 14 | password 15 | 16 | 17 | applicationKey 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gedcomx.Api.Lite", "Gedcomx.Api.Lite\Gedcomx.Api.Lite.csproj", "{DC9C289B-4ECC-41C5-8845-D29BEDACD45E}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example1", "Example1\Example1.csproj", "{9CD0258C-FC2D-493A-8D27-F6BD06C6776D}" 9 | EndProject 10 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Gedcomx.Api.Lite.Core", "Gedcomx.Api.Lite.Core\Gedcomx.Api.Lite.Core.xproj", "{8335F096-EFDD-4380-B576-032C25D0939A}" 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{98881E50-9F28-4575-9CB2-B095AED71915}" 13 | ProjectSection(SolutionItems) = preProject 14 | README.md = README.md 15 | EndProjectSection 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gedcomx.Api.Lite.Tests", "Gedcomx.Api.Lite.Tests\Gedcomx.Api.Lite.Tests.csproj", "{8371A813-0389-4A98-B9D7-986BF98C5AD4}" 18 | EndProject 19 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Example2.Core", "Example2.Core\Example2.Core.xproj", "{577081FC-D9A1-4AFF-B5DF-FEA1E8AA2234}" 20 | EndProject 21 | Global 22 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 23 | Debug|Any CPU = Debug|Any CPU 24 | Release|Any CPU = Release|Any CPU 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {DC9C289B-4ECC-41C5-8845-D29BEDACD45E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {DC9C289B-4ECC-41C5-8845-D29BEDACD45E}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {DC9C289B-4ECC-41C5-8845-D29BEDACD45E}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {DC9C289B-4ECC-41C5-8845-D29BEDACD45E}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {9CD0258C-FC2D-493A-8D27-F6BD06C6776D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {9CD0258C-FC2D-493A-8D27-F6BD06C6776D}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {9CD0258C-FC2D-493A-8D27-F6BD06C6776D}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {9CD0258C-FC2D-493A-8D27-F6BD06C6776D}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {8335F096-EFDD-4380-B576-032C25D0939A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {8335F096-EFDD-4380-B576-032C25D0939A}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {8335F096-EFDD-4380-B576-032C25D0939A}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {8335F096-EFDD-4380-B576-032C25D0939A}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {8371A813-0389-4A98-B9D7-986BF98C5AD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {8371A813-0389-4A98-B9D7-986BF98C5AD4}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {8371A813-0389-4A98-B9D7-986BF98C5AD4}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {8371A813-0389-4A98-B9D7-986BF98C5AD4}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {577081FC-D9A1-4AFF-B5DF-FEA1E8AA2234}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 44 | {577081FC-D9A1-4AFF-B5DF-FEA1E8AA2234}.Debug|Any CPU.Build.0 = Debug|Any CPU 45 | {577081FC-D9A1-4AFF-B5DF-FEA1E8AA2234}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {577081FC-D9A1-4AFF-B5DF-FEA1E8AA2234}.Release|Any CPU.Build.0 = Release|Any CPU 47 | EndGlobalSection 48 | GlobalSection(SolutionProperties) = preSolution 49 | HideSolutionNode = FALSE 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite/Gedcomx.Api.Lite.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DC9C289B-4ECC-41C5-8845-D29BEDACD45E} 8 | Library 9 | Properties 10 | Gedcomx.Api.Lite 11 | Gedcomx.Api.Lite 12 | v4.6 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Environment.cs 49 | 50 | 51 | FamilySearchSDK.cs 52 | 53 | 54 | MediaType.cs 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 71 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite/Gedcomx.Api.Lite.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | 1.0.1 6 | $title$ 7 | FamilySearch 8 | $author$ 9 | https://github.com/wooddani/familysearch-gedcomx-csharp-lite 10 | false 11 | This is the C# Lite version to contact the Family Search GEDCOM X APIs. It will help with authentication and media types through HttpClient. 12 | Update to Proper Repo and copyright 13 | Copyright 2017 14 | 15 | 16 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("gedcomx-csharp-lite")] 9 | [assembly: AssemblyDescription("Family Search C# Lite SDK")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Family Search")] 12 | [assembly: AssemblyProduct("gedcomx-csharp-lite")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("dc9c289b-4ecc-41c5-8845-d29bedacd45e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | 37 | -------------------------------------------------------------------------------- /Gedcomx.Api.Lite/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Welcome 2 | 3 | This C# project is intended to extend the [Family Search APIs](https://www.familysearch.org/developers/) using the [GEDCOM X](http://www.gedcomx.org) specifications. 4 | This project shall also replace the original [C# Family Search SDK](https://github.com/FamilySearch/gedcomx-csharp), however several parts of that SDK can still be utilized. The Nuget Packages are: 5 | 6 | | NuGet Package Id | Purpose | Notes | 7 | |------------------|---------|-------| 8 | | **[Gedcomx.Api.Lite](https://www.nuget.org/packages/Gedcomx.Api.Lite/)** | C# Lite version to contact the Family Search GEDCOM X APIs. It will help with authentication and media types through HttpClient. | Can be used alone or along with the other Model libraries. | 9 | | **[Gedcomx.Api.Lite.Core](https://www.nuget.org/packages/Gedcomx.Api.Lite.Core/)** | C# Core version of the Gedcomx.Api.Lite package. | Can be used on Linux & Mac. See [Microsoft Documentation](https://www.microsoft.com/net/core#linuxredhat) | 10 | | [Gedcomx.Model](http://www.nuget.org/packages/Gedcomx.Model/) | Contains the models for GEDCOM X data. | Use this by itself to just work with the GEDCOM X models and data, and not any web services or files. | 11 | | [Gedcomx.Model.Fs](http://www.nuget.org/packages/Gedcomx.Model.Fs/) | Contains FamilySearch specific GEDCOM X model extensions. | Use this by itself to just work with the GEDCOM X FamilySearch extension models and data, and not any web services or files. | 12 | | [Gedcomx.Model.Rs](http://www.nuget.org/packages/Gedcomx.Model.Rs/) | Contains REST specific GEDCOM X model extensions. | Use this by itself to just work with the GEDCOM X REST extension models and data, and not any web services or files. (This project adds atom feed models.) | 13 | 14 | ## Build 15 | 16 | Most of the code exists in a single file [FamilySearchSDK.cs](https://github.com/FamilySearch/csharp-lite/blob/master/Gedcomx.Api.Lite.Core/FamilySearchSDK.cs) with supporting enumeration files Environment.cs and MediaType.cs 17 | 18 | #### Prerequisites: 19 | * Microsoft .NET Framework 4.6. The web installer can be downloaded here: 20 | * NuGet 2.8. Instructions for installing can be found here: 21 | 22 | #### Project Descriptions: 23 | * Example1 - Contains person creation, relationship creation, search etc.. using the Lite SDK with Models 24 | * Example2.Core - Contains a search example using the new .Net Core approach. 25 | * Gedcomx.Api.Lite - Contains a linked copy of **all** the source needed to run the SDK. 26 | * Gedcomx.Api.Lite.Core - Contains **all** the source needed to run the SDK, but targeting .Net Core Implementations. 27 | * Gedcomx.Api.Lite.Tests - Contains basic test to utilize the api code base and do some code testing. 28 | 29 | ## Example 30 | 31 | Here is how you might use this project. 32 | 33 | #### Step 1 34 | Obtain a *username*, *password* and *applicationKey* refer to the [Family Search Developers Site](https://www.familysearch.org/developers/). 35 | 36 | #### Step 2 37 | Email a request (with your *applicationKey*) to devsupport@familysearch.org to enable password flow, supported for Desktop and Mobile applications. (For more information, see [https://www.familysearch.org/developers/docs/guides/authentication](https://www.familysearch.org/developers/docs/guides/authentication)). 38 | 39 | #### Step 3 40 | Instantiate a ``FamilySearchSDK`` Class supplying the following parameters: 41 | * username from step 1. 42 | * password from step 1. 43 | * application key, sometimes refered to as client key, from step 1. 44 | * application name, preferably from the dev registration site, but could be anything header friendly 45 | * version likely a string such as 1.0.0 46 | * environment Enumeration such as integration (was sandbox), beta and production 47 | ``` 48 | var ft = new FamilySearchSDK("username", "password", "applicationKey", "Example2.Core", "1.0.0", Gedcomx.Api.Lite.Environment.Integration); 49 | var response = ft.Get("/platform/tree/persons/" + personId).Result; 50 | Console.WriteLine(response.persons[0].display.name); 51 | ``` 52 | 53 | #### Step 4 54 | Make an api call such as Get, Post, Put, Delete which returns a Task by default. Adding ``.Result`` will wait for the response. Note that the async and await methodology is encouraged. For more information refer to [Microsoft's documentation on async and await](https://msdn.microsoft.com/en-us/library/hh191443(v=vs.110).aspx). 55 | 56 | ``` 57 | var ft = new FamilySearchSDK("username", "password", "applicationKey", "Example2.Core", "1.0.0", Gedcomx.Api.Lite.Environment.Integration); 58 | var response = ft.Get("/platform/tree/persons/" + personId).Result; 59 | Console.WriteLine(response.persons[0].display.name); 60 | ``` 61 | #### Step 5 62 | Visit the [Family Search Resources](https://www.familysearch.org/developers/docs/api/resources) site for details on how to get, post, put and delete content from Family Search. 63 | 64 | ## Community Samples 65 | 66 | * [*Ancestory Map*](http://ancestormap.azurewebsites.net/) - Using the C# lite SDK, you can see a person's ancestory on a world map by clicking [coming]. It combines ASP.Net 5 Core, Google API's, d3.js and Asure. Source Code can be found at this repository: . 67 | 68 | * Please contact Family Search to add more samples. 69 | 70 | --------------------------------------------------------------------------------