├── .gitignore ├── LICENSE ├── README.md ├── azure-pipelines.yml ├── releasePackages ├── JOS.ContentSerializer.1.0.0.nupkg ├── JOS.ContentSerializer.1.0.1.nupkg ├── JOS.ContentSerializer.2.0.0.nupkg ├── JOS.ContentSerializer.2.0.1.nupkg ├── JOS.ContentSerializer.3.0.0.nupkg ├── JOS.ContentSerializer.4.0.0.nupkg ├── JOS.ContentSerializer.4.1.0.nupkg ├── JOS.ContentSerializer.4.2.0.nupkg └── JOS.ContentSerializer.5.0.0.nupkg └── src ├── JOS.ContentSerializer.Tests ├── ContentAreaPropertyHandlerTests.cs ├── ContentReferenceListPropertyHandlerTests.cs ├── ContentReferencePropertyHandlerTests.cs ├── JOS.ContentSerializer.Tests.csproj ├── LinkItemCollectionPropertyHandlerTests.cs ├── PageTypePropertyHandlerTests.cs ├── Pages │ ├── PropertyNameStrategyPage.cs │ ├── PropertyResolverPage.cs │ ├── StandardPage.cs │ ├── StringArrayPropertyHandlerPage.cs │ ├── StringPropertyHandlerPage.cs │ ├── ValueTypePropertyHandlerPage.cs │ └── VideoBlock.cs ├── Properties │ └── AssemblyInfo.cs ├── PropertyHandlerServiceTests.cs ├── PropertyManagerTests.cs ├── PropertyNameStrategyTests.cs ├── PropertyResolverTests.cs ├── SelectStrategies │ ├── CustomSelectManyStrategy.cs │ └── CustomSelectOneStrategy.cs ├── SelectionFactory.cs ├── StandardPageBuilder.cs ├── StringPropertyHandlerWithCustomSelectStrategiesTests.cs ├── UrlHelperAdapterTests.cs ├── UrlPropertyHandlerTests.cs ├── ValueTypeListPropertyHandlers │ ├── DateTimeListPropertyHandlerTests.cs │ ├── DoubleListPropertyHandlerTests.cs │ ├── IntListPropertyHandlerTests.cs │ └── StringListPropertyHandlerTests.cs ├── ValueTypePropertyHandlers │ ├── BoolPropertyHandlerTests.cs │ ├── DateTimePropertyHandlerTests.cs │ ├── DoublePropertyHandlerTests.cs │ ├── IntPropertyHandlerTests.cs │ └── StringPropertyHandlerTests.cs ├── XhtmlStringPropertyHandlerTests.cs ├── app.config └── packages.config ├── JOS.ContentSerializer.sln ├── JOS.ContentSerializer ├── Attributes │ ├── ContentSerializerIgnoreAttribute.cs │ ├── ContentSerializerIncludeAttribute.cs │ ├── ContentSerializerNameAttribute.cs │ ├── ContentSerializerPropertyHandlerAttribute.cs │ └── ContentSerializerWrapItemsAttribute.cs ├── ContentSerializer.cs ├── ContentSerializerSettings.cs ├── IContentDataExtensions.cs ├── IContentJsonSerializer.cs ├── IContentSerializer.cs ├── IContentSerializerSettings.cs ├── IPropertyHandler.cs ├── IPropertyHandlerService.cs ├── IPropertyManager.cs ├── IPropertyNameStrategy.cs ├── IPropertyResolver.cs ├── ISelectManyStrategy.cs ├── ISelectOneStrategy.cs ├── IUrlHelper.cs ├── IUrlSettings.cs ├── Internal │ ├── ContentSerializerInitalizationModule.cs │ ├── Default │ │ ├── BlockDataPropertyHandler.cs │ │ ├── BoolPropertyHandler.cs │ │ ├── ContentAreaPropertyHandler.cs │ │ ├── ContentReferenceListPropertyHandler.cs │ │ ├── ContentReferencePropertyHandler.cs │ │ ├── DefaultSelectStrategy.cs │ │ ├── LinkItemCollectionPropertyHandler.cs │ │ ├── NullableTimeSpanPropertyHandler.cs │ │ ├── PageReferencePropertyHandler.cs │ │ ├── PageTypeModel.cs │ │ ├── PageTypePropertyHandler.cs │ │ ├── StringPropertyHandler.cs │ │ ├── UrlPropertyHandler.cs │ │ ├── ValueListPropertyHandlers │ │ │ ├── DateTimeListPropertyHandler.cs │ │ │ ├── DoubleListPropertyHandler.cs │ │ │ ├── IntListPropertyHandler.cs │ │ │ └── StringListPropertyHandler.cs │ │ ├── ValueTypePropertyHandlers │ │ │ ├── DateTimePropertyHandler.cs │ │ │ ├── DoublePropertyHandler.cs │ │ │ ├── IntPropertyHandler.cs │ │ │ └── StringPropertyHandler.cs │ │ └── XhtmlStringPropertyHandler.cs │ ├── ISelectStrategy.cs │ ├── JsonContentSerializer.cs │ ├── LinkItem.cs │ ├── PropertyHandlerService.cs │ ├── PropertyManager.cs │ ├── PropertyNameStrategy.cs │ ├── PropertyResolver.cs │ ├── SelectOption.cs │ └── UrlHelperAdapter.cs ├── JOS.ContentSerializer.csproj ├── JOS.ContentSerializer.nuspec ├── Properties │ └── AssemblyInfo.cs ├── UrlSettings.cs └── packages.config └── nuget.config /.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 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studo 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | *_i.c 42 | *_p.c 43 | *_i.h 44 | *.ilk 45 | *.meta 46 | *.obj 47 | *.pch 48 | *.pdb 49 | *.pgc 50 | *.pgd 51 | *.rsp 52 | *.sbr 53 | *.tlb 54 | *.tli 55 | *.tlh 56 | *.tmp 57 | *.tmp_proj 58 | *.log 59 | *.vspscc 60 | *.vssscc 61 | .builds 62 | *.pidb 63 | *.svclog 64 | *.scc 65 | 66 | # Chutzpah Test files 67 | _Chutzpah* 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | *.cachefile 76 | 77 | # Visual Studio profiler 78 | *.psess 79 | *.vsp 80 | *.vspx 81 | 82 | # TFS 2012 Local Workspace 83 | $tf/ 84 | 85 | # Guidance Automation Toolkit 86 | *.gpState 87 | 88 | # ReSharper is a .NET coding add-in 89 | _ReSharper*/ 90 | *.[Rr]e[Ss]harper 91 | *.DotSettings.user 92 | 93 | # JustCode is a .NET coding addin-in 94 | .JustCode 95 | 96 | # TeamCity is a build add-in 97 | _TeamCity* 98 | 99 | # DotCover is a Code Coverage Tool 100 | *.dotCover 101 | 102 | # NCrunch 103 | _NCrunch_* 104 | .*crunch*.local.xml 105 | 106 | # MightyMoose 107 | *.mm.* 108 | AutoTest.Net/ 109 | 110 | # Web workbench (sass) 111 | .sass-cache/ 112 | 113 | # Installshield output folder 114 | [Ee]xpress/ 115 | 116 | # DocProject is a documentation generator add-in 117 | DocProject/buildhelp/ 118 | DocProject/Help/*.HxT 119 | DocProject/Help/*.HxC 120 | DocProject/Help/*.hhc 121 | DocProject/Help/*.hhk 122 | DocProject/Help/*.hhp 123 | DocProject/Help/Html2 124 | DocProject/Help/html 125 | 126 | # Click-Once directory 127 | publish/ 128 | 129 | # Publish Web Output 130 | *.[Pp]ublish.xml 131 | *.azurePubxml 132 | # TODO: Comment the next line if you want to checkin your web deploy settings 133 | # but database connection strings (with potential passwords) will be unencrypted 134 | *.pubxml 135 | *.publishproj 136 | 137 | # The packages folder can be ignored because of Package Restore 138 | **/packages/* 139 | # except build/, which is used as an MSBuild target. 140 | !**/packages/build/ 141 | # Uncomment if necessary however generally it will be regenerated when needed 142 | #!**/packages/repositories.config 143 | 144 | # Windows Azure Build Output 145 | csx/ 146 | *.build.csdef 147 | 148 | # Windows Store app package directory 149 | AppPackages/ 150 | 151 | # Others 152 | *.[Cc]ache 153 | ClientBin/ 154 | [Ss]tyle[Cc]op.* 155 | ~$* 156 | *~ 157 | *.dbmdl 158 | *.dbproj.schemaview 159 | *.pfx 160 | *.publishsettings 161 | node_modules/ 162 | bower_components/ 163 | 164 | # RIA/Silverlight projects 165 | Generated_Code/ 166 | 167 | # Backup & report files from converting an old project file 168 | # to a newer Visual Studio version. Backup files are not needed, 169 | # because we have git ;-) 170 | _UpgradeReport_Files/ 171 | Backup*/ 172 | UpgradeLog*.XML 173 | UpgradeLog*.htm 174 | 175 | # SQL Server files 176 | *.mdf 177 | *.ldf 178 | 179 | # Business Intelligence projects 180 | *.rdl.data 181 | *.bim.layout 182 | *.bim_*.settings 183 | 184 | # Microsoft Fakes 185 | FakesAssemblies/ 186 | 187 | # Node.js Tools for Visual Studio 188 | .ntvs_analysis.dat 189 | 190 | # Visual Studio 6 build log 191 | *.plg 192 | 193 | # Visual Studio 6 workspace options file 194 | *.opt 195 | 196 | License.config 197 | App_Data/ 198 | JosTest/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Josef Ottosson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JOS.ContentSerializer - Converts any Episerver ContentData object to JSON 2 | 3 | ## Serialize any ContentData object to JSON(or xml, or something else) 4 | 5 | ### Installation 6 | Nuget: **Install-Package Jos.ContentSerializer** 7 | #### *OR* 8 | Just check out the desired branch and add the Jos.ContentSerializer project to your solution. 9 | 10 | ### Features 11 | 12 | Support for the most common built in properties: 13 | * ```BlockData``` 14 | * ```bool``` 15 | * ```double``` 16 | * ```ContentArea``` 17 | * ```ContentReference``` 18 | * ```DateTime``` 19 | * ```IEnumerable``` 20 | * ```IEnumerable``` *ICollection/IList works as well* 21 | * ```IEnumerable``` *ICollection/IList works as well* 22 | * ```IEnumerable``` *ICollection/IList works as well* 23 | * ```IEnumerable``` *ICollection/IList works as well* 24 | * ```int``` 25 | * ```LinkItemCollection``` 26 | * ```PageReference``` 27 | * ```PageType``` 28 | * ```string[]``` 29 | * ```string``` *SelectOne/SelectMany* support as well.* 30 | * ```Url``` 31 | * ```XhtmlString``` 32 | 33 | Nested ContentAreas are supported as well. When the code finds a ContentArea, it will load all items recursively so you can have multiple levels of "nesting". 34 | 35 | ### Extensible, really easy to add support for custom properties 36 | Example: 37 | You're using the property [Jos.PropertyKeyValueList](https://github.com/joseftw/JOS.PropertyKeyValueList) on your StartPage like this. 38 | 39 | ```csharp 40 | public class StartPage : PageData 41 | { 42 | ... 43 | public virtual string Heading { get; set; } 44 | public virtual IEnumerable KeyValueItems{ get; set; } 45 | ... 46 | } 47 | ``` 48 | Now, if you call .ToJson on a StartPage instance you would only get the Heading property in the json output since ```IEnumerable``` isn't handled out of the box. 49 | ```javascript 50 | { 51 | "heading" : "Where is my KeyValueItems??" 52 | } 53 | ``` 54 | 55 | To add support for it, first create a new class that implements the ```IPropertyHandler<>``` interface 56 | 57 | ```csharp 58 | public class KeyValueItemListPropertyHandler : IPropertyHandler> 59 | { 60 | public object Handle(IEnumerable value, PropertyInfo property, IContentData contentData) 61 | { 62 | // Do whatever you want with the property here. 63 | return value; 64 | } 65 | } 66 | ``` 67 | Then register your class in your DI container. 68 | **Example** 69 | ```csharp 70 | [InitializableModule] 71 | [ModuleDependency(typeof(EPiServer.Web.InitializationModule))] 72 | public class MyConfigurationModule : IConfigurableModule 73 | { 74 | public void ConfigureContainer(ServiceConfigurationContext context) 75 | { 76 | context.Services.AddSingleton>, KeyValueItemListPropertyHandler>(); 77 | } 78 | } 79 | ``` 80 | Now, if you would call .ToJson again on your StartPage instance, you would see the following output. 81 | 82 | ```javascript 83 | { 84 | "heading": "Where is my KeyValueItems??", 85 | "keyValueItems": [ 86 | { 87 | "key": "Some key", 88 | "value": "Hello there" 89 | }, 90 | { 91 | "key": "Another key", 92 | "value": "Another value!" 93 | } 94 | ] 95 | } 96 | ``` 97 | 98 | ### Extend/Replace built in PropertyHandlers 99 | Say that you, for some reason, want all strings to return "JOSEF OTTOSSON!!" instead of their actual value. 100 | 101 | Just create a new propertyhandler for strings like this. 102 | ```csharp 103 | public class JosefStringPropertyHandler : IPropertyHandler 104 | { 105 | public object Handle(string value, PropertyInfo property, IContentData contentData) 106 | { 107 | return "JOSEF OTTOSSON!!"; 108 | } 109 | } 110 | ``` 111 | 112 | Then swap out the default ```StringPropertyHandler``` in the DI container like this: 113 | ```csharp 114 | context.Services.AddSingleton, JosefStringPropertyHandler>(); 115 | ``` 116 | **Don't forget to unregister the default ``IPropertyHandler`` as well** 117 | 118 | ### Breaking changes 119 | 120 | #### Version 5.0 121 | To fix the issue with IContentSerializerSettings not getting passed on to ```IPropertyHandlers``` I needed to do a breaking change. 122 | I've added the following method to the ```IPropertyHandler``` interface: 123 | ```csharp 124 | object Handle(T value, PropertyInfo property, IContentData contentData, IContentSerializerSettings settings); 125 | ``` 126 | **This method will now be called by the default implementation of ```IPropertyManager```**. 127 | 128 | If you've built any custom ```IPropertyHandlers``` you will need to implement this new method as well. 129 | Example: 130 | 131 | Old **UrlPropertyHandler** 132 | ```csharp 133 | public class UrlPropertyHandler : IPropertyHandler 134 | { 135 | private readonly IUrlHelper _urlHelper; 136 | private readonly IContentSerializerSettings _contentSerializerSettings; 137 | private const string MailTo = "mailto"; 138 | 139 | public UrlPropertyHandler(IUrlHelper urlHelper, IContentSerializerSettings contentSerializerSettings) 140 | { 141 | _urlHelper = urlHelper ?? throw new ArgumentNullException(nameof(urlHelper)); 142 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 143 | } 144 | 145 | public object Handle(Url url, PropertyInfo propertyInfo, IContentData contentData) 146 | { 147 | if (url == null) 148 | { 149 | return null; 150 | } 151 | 152 | if (url.Scheme == MailTo) return url.OriginalString; 153 | 154 | if (url.IsAbsoluteUri) 155 | { 156 | if (this._contentSerializerSettings.UrlSettings.UseAbsoluteUrls) 157 | { 158 | return url.OriginalString; 159 | } 160 | 161 | return url.PathAndQuery; 162 | } 163 | 164 | return this._urlHelper.ContentUrl(url, this._contentSerializerSettings.UrlSettings); 165 | } 166 | } 167 | ``` 168 | 169 | Updated **UrlPropertyHandler** 170 | ```csharp 171 | public class UrlPropertyHandler : IPropertyHandler 172 | { 173 | private readonly IUrlHelper _urlHelper; 174 | private readonly IContentSerializerSettings _contentSerializerSettings; 175 | private const string MailTo = "mailto"; 176 | 177 | public UrlPropertyHandler(IUrlHelper urlHelper, IContentSerializerSettings contentSerializerSettings) 178 | { 179 | _urlHelper = urlHelper ?? throw new ArgumentNullException(nameof(urlHelper)); 180 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 181 | } 182 | 183 | public object Handle( 184 | Url url, 185 | PropertyInfo propertyInfo, 186 | IContentData contentData) 187 | { 188 | return Handle(url, propertyInfo, contentData, _contentSerializerSettings); 189 | } 190 | 191 | public object Handle( 192 | Url url, 193 | PropertyInfo property, 194 | IContentData contentData, 195 | IContentSerializerSettings settings) 196 | { 197 | if (url == null) 198 | { 199 | return null; 200 | } 201 | 202 | if (url.Scheme == MailTo) return url.OriginalString; 203 | 204 | if (url.IsAbsoluteUri) 205 | { 206 | if (settings.UrlSettings.UseAbsoluteUrls) 207 | { 208 | return url.OriginalString; 209 | } 210 | 211 | return url.PathAndQuery; 212 | } 213 | 214 | return this._urlHelper.ContentUrl(url, settings.UrlSettings); 215 | } 216 | } 217 | ``` 218 | 219 | #### Other interfaces 220 | 221 | - IContentJsonSerializer - The default Json serializer. Implent it and register your own if you want to replace it. 222 | - IContentSerializer - The default serializer. The default one is the same as IContentJsonSerializer. 223 | - IPropertyManager - Handles the mapping from a property to a PropertyHandler. 224 | - IPropertyNameStrategy - Handles how the serialized properties should be named. 225 | - IPropertyResolver - Handles which properties that should be serialized. 226 | - IUrlHelper - Handles how ContentReferences/Url-properties should be serialized. 227 | 228 | #### IPropertyNameStrategy 229 | The default implementation checks for the ```ContentSerializerNameAttribute``` attribute, if found, the name from the attribute will be used. If not found, the name of the property will be used. 230 | 231 | #### IPropertyResolver 232 | The default implementation works like this on a ContentData object. 233 | 1. It looks for the ```ContentSerializerIgnoreAttribute```, if found, the property will be skipped. 234 | 2. If no ```ContentSerializerIgnoreAttribute``` was found, it looks for the ```DisplayAttribute```, if found, the property will be included. 235 | 3. If no ```DisplayAttribute``` was found, it looks for the ```ContentSerializerIncludeAttribute```, if found, the property will be included. 236 | 237 | ### Customizable 238 | The .Serialize and .ToJson methods both have an overload where you can pass in ```ContentSerializerSettings```. 239 | You can change the following settings: 240 | 241 | * GlobalWrapContentAreaItems - Default = **true**. 242 | Decides if items in a contentarea should be grouped by their ContentType or not. 243 | * UrlSettings 244 | * UseAbsoluteUrls - Default = **true**. 245 | Decides if the urls returned should be absolute or relative. 246 | * FallbackToWildcard - Default = **true**. 247 | If set to true, the site matched with wildcard (if any) is returned if no mapping could be found for the current hostname when using the GetByHostname method. 248 | 249 | ### Attributes 250 | The following attributes exists 251 | 252 | - ContentSerializerIgnoreAttribute - If added to a property, the property will not be included in the result. 253 | - ContentSerializerIncludeAttribute - If added to a property that doesn't have the DisplayAttribute, the property will be included in the result 254 | - ContentSerializerNameAttribute - Makes it possible to set a custom name of the property when serialized. 255 | - ContentSerializerWrapItemsAttribute - When used on a ContentArea, it's possible to override the global ```GlobalWrapContentAreaItems``` setting for that specific ContentArea. 256 | - ContentSerializerPropertyHandlerAttribute - Makes it possible to specify a custom PropertyHandler for a specific property. 257 | 258 | ### Examples 259 | 260 | Use it like this: 261 | ```c# 262 | public class DemoPageController : PageController 263 | { 264 | public string Index(DemoPage currentPage) 265 | { 266 | return currentPage.ToJson(); 267 | } 268 | } 269 | ``` 270 | 271 |
272 | DemoPage 273 | 274 | ```c# 275 | [ContentType(DisplayName = "DemoPage", GUID = "a6762bfb-973b-41c1-acf8-7d26567cd71d")] 276 | public class DemoPage : PageData 277 | { 278 | [CultureSpecific] 279 | [Display( 280 | Name = "String", 281 | GroupName = SystemTabNames.Content, 282 | Order = 100)] 283 | public virtual string String { get; set; } 284 | 285 | [CultureSpecific] 286 | [Display( 287 | Name = "ContentArea", 288 | GroupName = SystemTabNames.Content, 289 | Order = 200)] 290 | public virtual ContentArea MainContentArea { get; set; } 291 | 292 | [CultureSpecific] 293 | [Display( 294 | Name = "Degrees", 295 | GroupName = SystemTabNames.Content, 296 | Order = 300)] 297 | public virtual double Degrees { get; set; } 298 | 299 | [CultureSpecific] 300 | [Display( 301 | Name = "Int", 302 | GroupName = SystemTabNames.Content, 303 | Order = 400)] 304 | public virtual int Int { get; set; } 305 | 306 | [CultureSpecific] 307 | [Display( 308 | Name = "Date", 309 | GroupName = SystemTabNames.Content, 310 | Order = 500)] 311 | public virtual DateTime DateTime { get; set; } 312 | 313 | [CultureSpecific] 314 | [Display( 315 | Name = "Bool", 316 | GroupName = SystemTabNames.Content, 317 | Order = 600)] 318 | public virtual bool Bool { get; set; } 319 | 320 | [CultureSpecific] 321 | [Display( 322 | Name = "PageType", 323 | GroupName = SystemTabNames.Content, 324 | Order = 700)] 325 | public virtual PageType PageType { get; set; } 326 | 327 | [CultureSpecific] 328 | [Display( 329 | Name = "ContentReference", 330 | GroupName = SystemTabNames.Content, 331 | Order = 800)] 332 | public virtual ContentReference ContentReference { get; set; } 333 | 334 | [CultureSpecific] 335 | [Display( 336 | Name = "PageReference", 337 | GroupName = SystemTabNames.Content, 338 | Order = 900)] 339 | public virtual PageReference PageReference { get; set; } 340 | 341 | [CultureSpecific] 342 | [Display( 343 | Name = "Url", 344 | GroupName = SystemTabNames.Content, 345 | Order = 1000)] 346 | public virtual Url Url { get; set; } 347 | 348 | [Display( 349 | Name = "InternalBlock", 350 | GroupName = SystemTabNames.Content, 351 | Order = 1100)] 352 | public virtual VimeoVideoBlock InternalBlock { get; set; } 353 | 354 | [Display( 355 | Name = "ContentReferenceList", 356 | GroupName = SystemTabNames.Content, 357 | Order = 1200)] 358 | public virtual IList ContentReferenceList { get; set; } 359 | 360 | [Display( 361 | Name = "XhtmlString", 362 | GroupName = SystemTabNames.Content, 363 | Order = 1300)] 364 | public virtual XhtmlString XhtmlString { get; set; } 365 | 366 | [Display( 367 | Name = "LinkItemCollection", 368 | GroupName = SystemTabNames.Content, 369 | Order = 1400)] 370 | public virtual LinkItemCollection LinkItemCollection { get; set; } 371 | 372 | [Display( 373 | Name = "SelectOne", 374 | GroupName = SystemTabNames.Content, 375 | Order = 1500)] 376 | [SelectOne(SelectionFactoryType = typeof(ContactPageSelectionFactory))] 377 | public virtual string SelectOne { get; set; } 378 | 379 | [Display( 380 | Name = "SelectMany", 381 | GroupName = SystemTabNames.Content, 382 | Order = 1600)] 383 | [SelectMany(SelectionFactoryType = typeof(ContactPageSelectionFactory))] 384 | public virtual string SelectMany { get; set; } 385 | } 386 | ``` 387 |
388 |
389 | This will return a JSON representation of the `DemoPage` type like this: 390 | 391 | ```javascript 392 | { 393 | "string": "This is a string", 394 | "mainContentArea": { 395 | "vimeoVideoBlock": [{ 396 | "name": "Josef" 397 | }] 398 | }, 399 | "degrees": 133.7, 400 | "int": 1337, 401 | "dateTime": "2017-05-18T00:00:00+02:00", 402 | "bool": true, 403 | "pageType": "DemoPage", 404 | "contentReference": "http://localhost:52467/about-us/management/", 405 | "pageReference": "http://localhost:52467/alloy-plan/download-alloy-plan/", 406 | "url": "http://localhost:52467/globalassets/alloy-meet/alloymeet.png", 407 | "internalBlock": { 408 | "name": "Josef is my name", 409 | "mainContentArea": { 410 | "youtubeVideoBlock": [{ 411 | "name": "I am a youtube block" 412 | }] 413 | } 414 | }, 415 | "contentReferenceList": ["http://localhost:52467/search/", "http://localhost:52467/alloy-meet/"], 416 | "xhtmlString": "

I am a xhtmlstring, do you like it?

\n

Im bold not bald

", 417 | "linkItemCollection": [{ 418 | "href": "http://localhost:52467/alloy-plan/?query=any", 419 | "title": "Josef Ottossons sida", 420 | "target": "_blank", 421 | "text": "Josef Ottosson" 422 | }, { 423 | "href": "https://josef.guru", 424 | "title": "External link", 425 | "target": "_blank", 426 | "text": "External" 427 | }, { 428 | "href": "mailto:mail@example.com", 429 | "title": "Email link", 430 | "target": null, 431 | "text": "Email" 432 | }], 433 | "selectOne": [{ 434 | "selected": false, 435 | "text": "Amar Gupta", 436 | "value": "34" 437 | }, { 438 | "selected": false, 439 | "text": "Fiona Miller", 440 | "value": "33" 441 | }, { 442 | "selected": true, 443 | "text": "Michelle Hernandez", 444 | "value": "30" 445 | }, { 446 | "selected": false, 447 | "text": "Robert Carlsson", 448 | "value": "32" 449 | }, { 450 | "selected": false, 451 | "text": "Todd Slayton", 452 | "value": "31" 453 | }], 454 | "selectMany": [{ 455 | "selected": false, 456 | "text": "Amar Gupta", 457 | "value": "34" 458 | }, { 459 | "selected": true, 460 | "text": "Fiona Miller", 461 | "value": "33" 462 | }, { 463 | "selected": false, 464 | "text": "Michelle Hernandez", 465 | "value": "30" 466 | }, { 467 | "selected": false, 468 | "text": "Robert Carlsson", 469 | "value": "32" 470 | }, { 471 | "selected": false, 472 | "text": "Todd Slayton", 473 | "value": "31" 474 | }] 475 | } 476 | ``` 477 |
478 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # ASP.NET 2 | # Build and test ASP.NET projects. 3 | # Add steps that publish symbols, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4 5 | 6 | trigger: 7 | - develop 8 | 9 | pool: 10 | vmImage: 'windows-latest' 11 | 12 | variables: 13 | solution: '**/*.sln' 14 | buildPlatform: 'Any CPU' 15 | buildConfiguration: 'Release' 16 | 17 | steps: 18 | - task: NuGetToolInstaller@0 19 | 20 | - task: NuGetCommand@2 21 | inputs: 22 | command: 'restore' 23 | restoreSolution: '**/*.sln' 24 | feedsToUse: 'config' 25 | nugetConfigPath: 'src/nuget.config' 26 | versioningScheme: 'off' 27 | 28 | - task: VSBuild@1 29 | inputs: 30 | solution: '$(solution)' 31 | msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"' 32 | platform: '$(buildPlatform)' 33 | configuration: '$(buildConfiguration)' 34 | 35 | - task: VSTest@2 36 | inputs: 37 | testSelector: 'testAssemblies' 38 | testAssemblyVer2: '**\bin\Release\*Test*.dll' 39 | searchFolder: '$(System.DefaultWorkingDirectory)' 40 | configuration: 'Release' -------------------------------------------------------------------------------- /releasePackages/JOS.ContentSerializer.1.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseftw/JOS.ContentSerializer/f46588dcf7695dbd39b2e5bf1e83274f8e3599a9/releasePackages/JOS.ContentSerializer.1.0.0.nupkg -------------------------------------------------------------------------------- /releasePackages/JOS.ContentSerializer.1.0.1.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseftw/JOS.ContentSerializer/f46588dcf7695dbd39b2e5bf1e83274f8e3599a9/releasePackages/JOS.ContentSerializer.1.0.1.nupkg -------------------------------------------------------------------------------- /releasePackages/JOS.ContentSerializer.2.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseftw/JOS.ContentSerializer/f46588dcf7695dbd39b2e5bf1e83274f8e3599a9/releasePackages/JOS.ContentSerializer.2.0.0.nupkg -------------------------------------------------------------------------------- /releasePackages/JOS.ContentSerializer.2.0.1.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseftw/JOS.ContentSerializer/f46588dcf7695dbd39b2e5bf1e83274f8e3599a9/releasePackages/JOS.ContentSerializer.2.0.1.nupkg -------------------------------------------------------------------------------- /releasePackages/JOS.ContentSerializer.3.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseftw/JOS.ContentSerializer/f46588dcf7695dbd39b2e5bf1e83274f8e3599a9/releasePackages/JOS.ContentSerializer.3.0.0.nupkg -------------------------------------------------------------------------------- /releasePackages/JOS.ContentSerializer.4.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseftw/JOS.ContentSerializer/f46588dcf7695dbd39b2e5bf1e83274f8e3599a9/releasePackages/JOS.ContentSerializer.4.0.0.nupkg -------------------------------------------------------------------------------- /releasePackages/JOS.ContentSerializer.4.1.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseftw/JOS.ContentSerializer/f46588dcf7695dbd39b2e5bf1e83274f8e3599a9/releasePackages/JOS.ContentSerializer.4.1.0.nupkg -------------------------------------------------------------------------------- /releasePackages/JOS.ContentSerializer.4.2.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseftw/JOS.ContentSerializer/f46588dcf7695dbd39b2e5bf1e83274f8e3599a9/releasePackages/JOS.ContentSerializer.4.2.0.nupkg -------------------------------------------------------------------------------- /releasePackages/JOS.ContentSerializer.5.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseftw/JOS.ContentSerializer/f46588dcf7695dbd39b2e5bf1e83274f8e3599a9/releasePackages/JOS.ContentSerializer.5.0.0.nupkg -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ContentAreaPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using EPiServer; 4 | using EPiServer.Core; 5 | using JOS.ContentSerializer.Internal.Default; 6 | using JOS.ContentSerializer.Tests.Pages; 7 | using NSubstitute; 8 | using Shouldly; 9 | using Xunit; 10 | 11 | namespace JOS.ContentSerializer.Tests 12 | { 13 | public class ContentAreaPropertyHandlerTests 14 | { 15 | private readonly ContentAreaPropertyHandler _sut; 16 | 17 | public ContentAreaPropertyHandlerTests() 18 | { 19 | var contentLoader = Substitute.For(); 20 | SetupContentLoader(contentLoader); 21 | var propertyManager = Substitute.For(); 22 | this._sut = new ContentAreaPropertyHandler(contentLoader, propertyManager, new ContentSerializerSettings()); 23 | } 24 | 25 | [Fact] 26 | public void GivenNullContentArea_WhenHandle_ThenReturnsNull() 27 | { 28 | var result = this._sut.Handle(null, null, null); 29 | 30 | result.ShouldBeNull(); 31 | } 32 | 33 | // TODO TESTS 34 | 35 | private static void SetupContentLoader(IContentLoader contentLoader) 36 | { 37 | contentLoader.Get(new ContentReference(1000)) 38 | .Returns(new VideoBlock 39 | { 40 | Name = "My name", 41 | Url = new Url("https://josef.guru") 42 | }); 43 | } 44 | 45 | private static ContentArea CreateContentArea(IEnumerable content) 46 | { 47 | var contentArea = Substitute.For(); 48 | var items = content.Select(x => new ContentAreaItem 49 | { 50 | ContentLink = x 51 | }).ToList(); 52 | 53 | contentArea.Items.Returns(items); 54 | contentArea.Count.Returns(items.Count); 55 | contentArea.Items.Returns(items); 56 | 57 | return contentArea; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ContentReferenceListPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using EPiServer.Core; 4 | using JOS.ContentSerializer.Internal.Default; 5 | using NSubstitute; 6 | using Shouldly; 7 | using Xunit; 8 | 9 | namespace JOS.ContentSerializer.Tests 10 | { 11 | public class ContentReferenceListPropertyHandlerTests 12 | { 13 | private readonly ContentReferenceListPropertyHandler _sut; 14 | private readonly IUrlHelper _urlHelper; 15 | private readonly IContentSerializerSettings _contentSerializerSettings; 16 | 17 | public ContentReferenceListPropertyHandlerTests() 18 | { 19 | this._urlHelper = Substitute.For(); 20 | this._contentSerializerSettings = Substitute.For(); 21 | this._contentSerializerSettings.UrlSettings = new UrlSettings(); 22 | this._sut = new ContentReferenceListPropertyHandler( 23 | new ContentReferencePropertyHandler( 24 | this._urlHelper, 25 | this._contentSerializerSettings), 26 | this._contentSerializerSettings); 27 | } 28 | 29 | [Fact] 30 | public void GivenNullList_WhenHandle_ThenReturnsNull() 31 | { 32 | var result = this._sut.Handle(null, null, null); 33 | 34 | result.ShouldBeNull(); 35 | } 36 | 37 | [Fact] 38 | public void GivenEmptyList_WhenHandle_ThenReturnsEmptyList() 39 | { 40 | var contentReferences = Enumerable.Empty(); 41 | 42 | var result = this._sut.Handle(contentReferences, null, null); 43 | 44 | ((IEnumerable)result).ShouldBeEmpty(); 45 | } 46 | 47 | [Fact] 48 | public void GivenContentReferences_WhenHandle_ThenReturnsEmptyList() 49 | { 50 | var host = "example.com"; 51 | var scheme = "https://"; 52 | var baseUrl = $"{scheme}{host}"; 53 | var prettyPath = "/any-path/to/page/?anyQueryParam=value&anotherQuery"; 54 | var contentReference = new ContentReference(1000); 55 | var contentReferences = new List{contentReference}; 56 | 57 | this._urlHelper.ContentUrl(contentReference, this._contentSerializerSettings.UrlSettings) 58 | .Returns($"{baseUrl}{prettyPath}"); 59 | 60 | var result = this._sut.Handle(contentReferences, null, null); 61 | var items = ((IEnumerable)result).Cast().ToList(); 62 | 63 | items.Count.ShouldBe(1); 64 | items.First().ShouldBe($"{baseUrl}{prettyPath}"); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ContentReferencePropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Core; 2 | using JOS.ContentSerializer.Internal.Default; 3 | using NSubstitute; 4 | using Shouldly; 5 | using Xunit; 6 | 7 | namespace JOS.ContentSerializer.Tests 8 | { 9 | public class ContentReferencePropertyHandlerTests 10 | { 11 | private readonly ContentReferencePropertyHandler _sut; 12 | private readonly IUrlHelper _urlHelper; 13 | private IContentSerializerSettings _contentSerializerSettings; 14 | 15 | public ContentReferencePropertyHandlerTests() 16 | { 17 | this._contentSerializerSettings = Substitute.For(); 18 | this._contentSerializerSettings.UrlSettings = new UrlSettings(); 19 | this._urlHelper = Substitute.For(); 20 | this._sut = new ContentReferencePropertyHandler(this._urlHelper, this._contentSerializerSettings); 21 | } 22 | 23 | [Fact] 24 | public void GivenNullContentReference_WhenHandle_ThenReturnsNull() 25 | { 26 | var result = this._sut.Handle(null, null, null); 27 | 28 | result.ShouldBeNull(); 29 | } 30 | 31 | [Fact] 32 | public void GivenEmptyContentReference_WhenHandle_ThenReturnsNull() 33 | { 34 | var result = this._sut.Handle(ContentReference.EmptyReference, null, null); 35 | 36 | result.ShouldBeNull(); 37 | } 38 | 39 | [Fact] 40 | public void GivenContentReference_WhenHandle_ThenReturnsAbsoluteUrlString() 41 | { 42 | var host = "example.com"; 43 | var scheme = "https://"; 44 | var baseUrl = $"{scheme}{host}"; 45 | var prettyPath = "/any-path/to/page/?anyQueryParam=value&anotherQuery"; 46 | var contentReference = new ContentReference(1000); 47 | this._urlHelper.ContentUrl(contentReference, this._contentSerializerSettings.UrlSettings) 48 | .Returns($"{baseUrl}{prettyPath}"); 49 | 50 | var result = this._sut.Handle(contentReference, null, null); 51 | 52 | result.ShouldBe($"{baseUrl}{prettyPath}"); 53 | } 54 | 55 | [Fact] 56 | public void GivenContentReference_WhenHandleWithUseAbsoluteUrlsSetToFalse_ThenReturnsRelativeUrlString() 57 | { 58 | var host = "example.com"; 59 | var scheme = "https://"; 60 | var baseUrl = $"{scheme}{host}"; 61 | var prettyPath = "/any-path/to/page/?anyQueryParam=value&anotherQuery"; 62 | var contentReference = new ContentReference(1000); 63 | this._contentSerializerSettings.UrlSettings.Returns(new UrlSettings { UseAbsoluteUrls = false }); 64 | this._urlHelper.ContentUrl(Arg.Any(), this._contentSerializerSettings.UrlSettings) 65 | .Returns($"{baseUrl}{prettyPath}"); 66 | 67 | var result = this._sut.Handle(contentReference, null, null); 68 | 69 | result.ShouldBe(prettyPath); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/JOS.ContentSerializer.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4A97CB84-60AB-4517-BE5D-73976D33EA91} 8 | Library 9 | Properties 10 | JOS.ContentSerializer.Tests 11 | JOS.ContentSerializer.Tests 12 | v4.6.1 13 | 512 14 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 15.0 16 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 17 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 18 | False 19 | UnitTest 20 | 21 | 22 | 23 | 24 | 25 | true 26 | full 27 | false 28 | bin\Debug\ 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll 84 | 85 | 86 | ..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll 87 | 88 | 89 | ..\packages\EPiServer.CMS.Core.11.1.0\lib\net461\EPiServer.dll 90 | 91 | 92 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.ApplicationModules.dll 93 | 94 | 95 | ..\packages\EPiServer.CMS.AspNet.11.1.0\lib\net461\EPiServer.Cms.AspNet.dll 96 | 97 | 98 | ..\packages\EPiServer.CMS.UI.Core.11.1.0\lib\net461\EPiServer.Cms.Shell.UI.dll 99 | 100 | 101 | ..\packages\EPiServer.CMS.AspNet.11.1.0\lib\net461\EPiServer.Configuration.dll 102 | 103 | 104 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.Data.dll 105 | 106 | 107 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.Data.Cache.dll 108 | 109 | 110 | ..\packages\EPiServer.CMS.Core.11.1.0\lib\net461\EPiServer.Enterprise.dll 111 | 112 | 113 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.Events.dll 114 | 115 | 116 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.Framework.dll 117 | 118 | 119 | ..\packages\EPiServer.Framework.AspNet.11.1.0\lib\net461\EPiServer.Framework.AspNet.dll 120 | 121 | 122 | ..\packages\EPiServer.CMS.AspNet.11.1.0\lib\net461\EPiServer.ImageLibrary.dll 123 | 124 | 125 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.Licensing.dll 126 | 127 | 128 | ..\packages\EPiServer.CMS.Core.11.1.0\lib\net461\EPiServer.LinkAnalyzer.dll 129 | 130 | 131 | ..\packages\EPiServer.CMS.UI.Core.11.1.0\lib\net461\EPiServer.Shell.dll 132 | 133 | 134 | ..\packages\EPiServer.CMS.UI.Core.11.1.0\lib\net461\EPiServer.Shell.UI.dll 135 | 136 | 137 | ..\packages\EPiServer.CMS.UI.Core.11.1.0\lib\net461\EPiServer.UI.dll 138 | 139 | 140 | ..\packages\EPiServer.CMS.AspNet.11.1.0\lib\net461\EPiServer.Web.WebControls.dll 141 | 142 | 143 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 144 | 145 | 146 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 147 | 148 | 149 | ..\packages\NSubstitute.2.0.3\lib\net45\NSubstitute.dll 150 | 151 | 152 | ..\packages\AutoFixture.3.50.2\lib\net40\Ploeh.AutoFixture.dll 153 | 154 | 155 | ..\packages\Shouldly.2.8.2\lib\net451\Shouldly.dll 156 | 157 | 158 | ..\packages\structuremap-signed.3.1.6.186\lib\net40\StructureMap.dll 159 | 160 | 161 | ..\packages\structuremap-signed.3.1.6.186\lib\net40\StructureMap.Net4.dll 162 | 163 | 164 | ..\packages\structuremap.web-signed.3.1.6.186\lib\net40\StructureMap.Web.dll 165 | 166 | 167 | 168 | ..\packages\System.ComponentModel.Annotations.4.4.0\lib\net461\System.ComponentModel.Annotations.dll 169 | 170 | 171 | 172 | 173 | 174 | 175 | ..\packages\System.Data.SqlClient.4.4.0\lib\net461\System.Data.SqlClient.dll 176 | 177 | 178 | 179 | 180 | 181 | 182 | ..\packages\System.Security.AccessControl.4.4.0\lib\net461\System.Security.AccessControl.dll 183 | 184 | 185 | ..\packages\System.Security.Cryptography.Xml.4.4.0\lib\net461\System.Security.Cryptography.Xml.dll 186 | 187 | 188 | ..\packages\System.Security.Permissions.4.4.0\lib\net461\System.Security.Permissions.dll 189 | 190 | 191 | ..\packages\System.Security.Principal.Windows.4.4.0\lib\net461\System.Security.Principal.Windows.dll 192 | 193 | 194 | ..\packages\System.Threading.AccessControl.4.4.0\lib\net461\System.Threading.AccessControl.dll 195 | 196 | 197 | ..\packages\Microsoft.Tpl.Dataflow.4.5.24\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll 198 | True 199 | 200 | 201 | 202 | 203 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll 204 | 205 | 206 | ..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll 207 | 208 | 209 | ..\packages\Microsoft.AspNet.Razor.2.0.20710.0\lib\net40\System.Web.Razor.dll 210 | 211 | 212 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll 213 | 214 | 215 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll 216 | 217 | 218 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll 219 | 220 | 221 | 222 | ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll 223 | 224 | 225 | ..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll 226 | 227 | 228 | ..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll 229 | 230 | 231 | ..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll 232 | 233 | 234 | 235 | 236 | {8A190000-F8C2-429E-931A-692C8DED1168} 237 | JOS.ContentSerializer 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 246 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/LinkItemCollectionPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using EPiServer; 5 | using EPiServer.SpecializedProperties; 6 | using JOS.ContentSerializer.Internal.Default; 7 | using NSubstitute; 8 | using Shouldly; 9 | using Xunit; 10 | using LinkItem = JOS.ContentSerializer.Internal.LinkItem; 11 | 12 | namespace JOS.ContentSerializer.Tests 13 | { 14 | public class LinkItemCollectionPropertyHandlerTests 15 | { 16 | private readonly LinkItemCollectionPropertyHandler _sut; 17 | private readonly IUrlHelper _urlHelper; 18 | private IContentSerializerSettings _contentSerializerSettings; 19 | 20 | public LinkItemCollectionPropertyHandlerTests() 21 | { 22 | this._contentSerializerSettings = Substitute.For(); 23 | this._contentSerializerSettings.UrlSettings = new UrlSettings(); 24 | this._urlHelper = Substitute.For(); 25 | this._sut = new LinkItemCollectionPropertyHandler(this._urlHelper, this._contentSerializerSettings); 26 | } 27 | 28 | [Fact] 29 | public void GivenNullLinkItemCollection_WhenHandle_ThenReturnsNull() 30 | { 31 | var result = this._sut.Handle(null, null, null); 32 | 33 | result.ShouldBeNull(); 34 | } 35 | 36 | [Fact] 37 | public void GivenMailToLink_WhenHandle_ThenReturnsCorrectMailToLink() 38 | { 39 | var value = "mailto:mail@example.com"; 40 | var linkItemCollection = new LinkItemCollection(); 41 | linkItemCollection.Add(new EPiServer.SpecializedProperties.LinkItem 42 | { 43 | Href = value, 44 | Text = "any text", 45 | Title = "any title" 46 | }); 47 | 48 | var result = ((IEnumerable)this._sut.Handle(linkItemCollection, null, null)).ToList(); 49 | 50 | result.Count.ShouldBe(1); 51 | result.ShouldContain(x => x.Href == value); 52 | result.ShouldContain(x => x.Text == "any text"); 53 | result.ShouldContain(x => x.Title == "any title"); 54 | } 55 | 56 | [Fact] 57 | public void GivenExternalLink_WhenHandle_ThenReturnsCorrectLink() 58 | { 59 | var value = "https://example.com/anypage?query=value"; 60 | var linkItemCollection = new LinkItemCollection(); 61 | linkItemCollection.Add(new EPiServer.SpecializedProperties.LinkItem 62 | { 63 | Href = value, 64 | Text = "any text", 65 | Title = "any title", 66 | Target = "_blank" 67 | }); 68 | 69 | var result = ((IEnumerable)this._sut.Handle(linkItemCollection, null, null)).ToList(); 70 | 71 | result.Count.ShouldBe(1); 72 | result.ShouldContain(x => x.Href == value); 73 | result.ShouldContain(x => x.Text == "any text"); 74 | result.ShouldContain(x => x.Title == "any title"); 75 | result.ShouldContain(x => x.Target == "_blank"); 76 | } 77 | 78 | [Fact] 79 | public void GivenInternalLink_WhenHandle_ThenReturnsCorrectAbsoluteLink() 80 | { 81 | var value = "random-internallink"; 82 | var linkItemCollection = new LinkItemCollection(); 83 | var expected = "https://example.com/my-pretty-url/?anyQuery=hej"; 84 | this._urlHelper.ContentUrl(Arg.Any(), Arg.Any()) 85 | .Returns(expected); 86 | var linkItem = Substitute.For(); 87 | linkItem.Href.Returns(value); 88 | linkItem.Text.Returns("any text"); 89 | linkItem.Title.Returns("any title"); 90 | linkItem.Target.Returns("_blank"); 91 | linkItem.ReferencedPermanentLinkIds.Returns(new List 92 | { 93 | Guid.NewGuid() 94 | }); 95 | linkItemCollection.Add(linkItem); 96 | 97 | var result = ((IEnumerable)this._sut.Handle(linkItemCollection, null, null)).ToList(); 98 | 99 | result.Count.ShouldBe(1); 100 | result.ShouldContain(x => x.Href == expected); 101 | result.ShouldContain(x => x.Text == "any text"); 102 | result.ShouldContain(x => x.Title == "any title"); 103 | result.ShouldContain(x => x.Target == "_blank"); 104 | } 105 | 106 | [Fact] 107 | public void GivenInternalLink_WhenHandleWithUseAbsoluteUrlsSetToFalse_ThenReturnsCorrectRelativeLink() 108 | { 109 | var value = "random-internallink"; 110 | var linkItemCollection = new LinkItemCollection(); 111 | var expected = "/my-pretty-url/?anyQuery=hej"; 112 | this._contentSerializerSettings.UrlSettings.Returns(new UrlSettings { UseAbsoluteUrls = false }); 113 | this._urlHelper.ContentUrl(Arg.Any(), this._contentSerializerSettings.UrlSettings).Returns(expected); 114 | var linkItem = Substitute.For(); 115 | linkItem.Href.Returns(value); 116 | linkItem.Text.Returns("any text"); 117 | linkItem.Title.Returns("any title"); 118 | linkItem.Target.Returns("_blank"); 119 | linkItem.ReferencedPermanentLinkIds.Returns(new List 120 | { 121 | Guid.NewGuid() 122 | }); 123 | linkItemCollection.Add(linkItem); 124 | 125 | var result = ((IEnumerable)this._sut.Handle(linkItemCollection, null, null)).ToList(); 126 | 127 | result.Count.ShouldBe(1); 128 | result.ShouldContain(x => x.Href == expected); 129 | result.ShouldContain(x => x.Text == "any text"); 130 | result.ShouldContain(x => x.Title == "any title"); 131 | result.ShouldContain(x => x.Target == "_blank"); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/PageTypePropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.DataAbstraction; 2 | using JOS.ContentSerializer.Internal.Default; 3 | using Shouldly; 4 | using Xunit; 5 | 6 | namespace JOS.ContentSerializer.Tests 7 | { 8 | public class PageTypePropertyHandlerTests 9 | { 10 | private readonly PageTypePropertyHandler _sut; 11 | 12 | public PageTypePropertyHandlerTests() 13 | { 14 | this._sut = new PageTypePropertyHandler(new ContentSerializerSettings()); 15 | } 16 | 17 | [Fact] 18 | public void GivenNullPageType_WhenHandle_ThenReturnsNull() 19 | { 20 | var result = this._sut.Handle(null, null, null); 21 | 22 | result.ShouldBeNull(); 23 | } 24 | 25 | [Fact] 26 | public void GivenPageType_WhenHandle_ThenReturnsCorrectValue() 27 | { 28 | var pageType = new PageType {Name = "anytype"}; 29 | 30 | var result = this._sut.Handle(pageType, null, null); 31 | 32 | ((PageTypeModel)result).Name.ShouldBe(pageType.Name); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/Pages/PropertyNameStrategyPage.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Core; 2 | using JOS.ContentSerializer.Attributes; 3 | 4 | namespace JOS.ContentSerializer.Tests.Pages 5 | { 6 | public class PropertyNameStrategyPage : PageData 7 | { 8 | public virtual string Heading { get; set; } 9 | 10 | [ContentSerializerName("customAuthor")] 11 | public virtual string Author { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/Pages/PropertyResolverPage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | using EPiServer.Core; 4 | using EPiServer.DataAnnotations; 5 | using JOS.ContentSerializer.Attributes; 6 | 7 | namespace JOS.ContentSerializer.Tests.Pages 8 | { 9 | public class PropertyResolverPage : PageData 10 | { 11 | [CultureSpecific] 12 | [Display( 13 | Name = "Heading")] 14 | public virtual string Heading { get; set; } 15 | 16 | [CultureSpecific] 17 | [Display(Name = "Description")] 18 | public virtual string Description { get; set; } 19 | 20 | [CultureSpecific] 21 | [Display(Name = "Age")] 22 | public virtual int Age { get; set; } 23 | 24 | [CultureSpecific] 25 | [Display(Name = "Starting")] 26 | public virtual DateTime Starting { get; set; } 27 | 28 | [CultureSpecific] 29 | [Display(Name = "Private")] 30 | public virtual bool Private { get; set; } 31 | 32 | [CultureSpecific] 33 | [Display(Name = "Degrees")] 34 | public virtual double Degrees { get; set; } 35 | 36 | [CultureSpecific] 37 | [Display(Name = "Main body")] 38 | public virtual XhtmlString MainBody { get; set; } 39 | 40 | [CultureSpecific] 41 | [Display(Name = "Main Content Area")] 42 | public virtual ContentArea MainContentArea { get; set; } 43 | 44 | [Display(Name = "Main Video")] 45 | public virtual VideoBlock MainVideo { get; set; } 46 | 47 | [Display(Name = "Author")] 48 | [ContentSerializerIgnore] 49 | public virtual string Author { get; set; } 50 | 51 | public virtual string Phone 52 | { 53 | get; set; 54 | } 55 | 56 | [ContentSerializerInclude] 57 | public virtual string Include { get; set; } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/Pages/StandardPage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using EPiServer.Core; 5 | using EPiServer.DataAnnotations; 6 | using Newtonsoft.Json; 7 | 8 | namespace JOS.ContentSerializer.Tests.Pages 9 | { 10 | [ContentType(DisplayName = "StandardPage", GUID = "e48d76d2-016c-4588-9768-f68caf3a9b43", Description = "")] 11 | public class StandardPage : PageData 12 | { 13 | [CultureSpecific] 14 | [Display( 15 | Name = "Heading")] 16 | public virtual string Heading { get; set; } 17 | 18 | [CultureSpecific] 19 | [Display(Name = "Description")] 20 | public virtual string Description { get; set; } 21 | 22 | [CultureSpecific] 23 | [Display(Name = "Age")] 24 | public virtual int Age { get; set; } 25 | 26 | [CultureSpecific] 27 | [Display(Name = "Starting")] 28 | public virtual DateTime Starting { get; set; } 29 | 30 | [CultureSpecific] 31 | [Display(Name = "Private")] 32 | public virtual bool Private { get; set; } 33 | 34 | [CultureSpecific] 35 | [Display(Name = "Degrees")] 36 | public virtual double Degrees { get; set; } 37 | 38 | [CultureSpecific] 39 | [Display(Name = "Main body")] 40 | public virtual XhtmlString MainBody { get; set; } 41 | 42 | [CultureSpecific] 43 | [Display(Name = "Main Content Area")] 44 | public virtual ContentArea MainContentArea { get; set; } 45 | 46 | [Display(Name = "Main Video")] 47 | public virtual VideoBlock MainVideo { get; set; } 48 | 49 | [Display(Name = "ContentReference")] 50 | public virtual ContentReference ContentReference { get; set; } 51 | 52 | [Display(Name = "PageReference")] 53 | public virtual PageReference PageReference { get; set; } 54 | 55 | [Display(Name = "strings")] 56 | public virtual IEnumerable Strings { get; set; } 57 | 58 | [Display(Name = "ints")] 59 | public virtual IEnumerable Ints { get; set; } 60 | 61 | [Display(Name = "doubles")] 62 | public virtual IEnumerable Doubles { get; set; } 63 | 64 | [Display(Name = "dateTimes")] 65 | public virtual IEnumerable DateTimes { get; set; } 66 | 67 | [JsonIgnore] 68 | public virtual string Author { get; set; } 69 | 70 | public virtual string Phone { get; set; } 71 | } 72 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/Pages/StringArrayPropertyHandlerPage.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.Core; 3 | using EPiServer.DataAbstraction; 4 | using EPiServer.DataAnnotations; 5 | 6 | namespace JOS.ContentSerializer.Tests.Pages 7 | { 8 | [ContentType(DisplayName = "StringArrayPropertyHandlerPage", GUID = "414a734c-0fdf-49a5-9fc4-04d10538baa5", Description = "")] 9 | public class StringArrayPropertyHandlerPage : PageData 10 | { 11 | 12 | [CultureSpecific] 13 | [Display( 14 | Name = "Strings", 15 | GroupName = SystemTabNames.Content, 16 | Order = 1)] 17 | public virtual string[] Strings { get; set; } 18 | 19 | } 20 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/Pages/StringPropertyHandlerPage.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer.Core; 3 | using EPiServer.DataAbstraction; 4 | using EPiServer.DataAnnotations; 5 | using EPiServer.Shell.ObjectEditing; 6 | 7 | namespace JOS.ContentSerializer.Tests.Pages 8 | { 9 | [ContentType(DisplayName = "StringPropertyHandlerPage", GUID = "e3a74971-d641-4081-95e0-b0200284d8cd", Description = "")] 10 | public class StringPropertyHandlerPage : PageData 11 | { 12 | 13 | [CultureSpecific] 14 | [Display( 15 | Name = "Main body", 16 | GroupName = SystemTabNames.Content, 17 | Order = 1)] 18 | public virtual string Heading { get; set; } 19 | 20 | [SelectOne(SelectionFactoryType = typeof(SelectionFactory))] 21 | public virtual string SelectOne { get; set; } 22 | 23 | [SelectMany(SelectionFactoryType = typeof(SelectionFactory))] 24 | public virtual string SelectMany { get; set; } 25 | 26 | [SelectOne(SelectionFactoryType = typeof(SelectionFactory))] 27 | public virtual string SelectedOnlyOne { get; set; } 28 | 29 | [SelectMany(SelectionFactoryType = typeof(SelectionFactory))] 30 | public virtual string SelectedOnlyMany { get; set; } 31 | 32 | [SelectOne(SelectionFactoryType = typeof(SelectionFactory))] 33 | public virtual string SelectedOnlyValueOnlyOne { get; set; } 34 | 35 | [SelectMany(SelectionFactoryType = typeof(SelectionFactory))] 36 | public virtual string SelectedOnlyValueOnlyMany { get; set; } 37 | } 38 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/Pages/ValueTypePropertyHandlerPage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | using EPiServer.Core; 4 | using EPiServer.DataAbstraction; 5 | using EPiServer.DataAnnotations; 6 | 7 | namespace JOS.ContentSerializer.Tests.Pages 8 | { 9 | [ContentType(DisplayName = "ValueTypePropertyHandlerPage", GUID = "91b9fea0-c87e-482d-937b-0cbd5455f296", Description = "")] 10 | public class ValueTypePropertyHandlerPage : PageData 11 | { 12 | [CultureSpecific] 13 | [Display( 14 | GroupName = SystemTabNames.Content, 15 | Order = 100)] 16 | public virtual int Integer { get; set; } 17 | 18 | [CultureSpecific] 19 | [Display( 20 | GroupName = SystemTabNames.Content, 21 | Order = 200)] 22 | public virtual DateTime DateTime { get; set; } 23 | 24 | [CultureSpecific] 25 | [Display( 26 | GroupName = SystemTabNames.Content, 27 | Order = 300)] 28 | public virtual double Double { get; set; } 29 | 30 | [CultureSpecific] 31 | [Display( 32 | GroupName = SystemTabNames.Content, 33 | Order = 400)] 34 | public virtual bool Bool { get; set; } 35 | } 36 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/Pages/VideoBlock.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using EPiServer; 3 | using EPiServer.Core; 4 | using EPiServer.DataAbstraction; 5 | using EPiServer.DataAnnotations; 6 | 7 | namespace JOS.ContentSerializer.Tests.Pages 8 | { 9 | [ContentType(DisplayName = "VideoBlock", GUID = "f4a40b95-798e-4400-ac79-7f3a4189d5c7", Description = "")] 10 | public class VideoBlock : BlockData 11 | { 12 | 13 | [CultureSpecific] 14 | [Display( 15 | Name = "Name", 16 | Description = "Name field's description", 17 | GroupName = SystemTabNames.Content, 18 | Order = 1)] 19 | public virtual string Name { get; set; } 20 | 21 | [Display(Name = "Url")] 22 | public virtual Url Url { get; set; } 23 | } 24 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("JOS.DefaultContentSerializer.Tests")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("")] 8 | [assembly: AssemblyProduct("JOS.DefaultContentSerializer.Tests")] 9 | [assembly: AssemblyCopyright("Copyright © 2017")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | 15 | [assembly: Guid("4a97cb84-60ab-4517-be5d-73976d33ea91")] 16 | 17 | // [assembly: AssemblyVersion("1.0.*")] 18 | [assembly: AssemblyVersion("1.0.0.0")] 19 | [assembly: AssemblyFileVersion("1.0.0.0")] 20 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/PropertyHandlerServiceTests.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using JOS.ContentSerializer.Internal; 4 | using NSubstitute; 5 | using Shouldly; 6 | using Xunit; 7 | 8 | namespace JOS.ContentSerializer.Tests 9 | { 10 | public class PropertyHandlerServiceTests 11 | { 12 | private readonly PropertyHandlerService _sut; 13 | 14 | public PropertyHandlerServiceTests() 15 | { 16 | this._sut = new PropertyHandlerService(); 17 | } 18 | 19 | [Fact] 20 | public void GivenNullPropertyInfo_WhenGetPropertyHandler_ThenReturnsNull() 21 | { 22 | var result = this._sut.GetPropertyHandler(null); 23 | 24 | result.ShouldBeNull(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/PropertyManagerTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using EPiServer; 4 | using EPiServer.Core; 5 | using EPiServer.ServiceLocation; 6 | using JOS.ContentSerializer.Internal; 7 | using JOS.ContentSerializer.Internal.Default; 8 | using JOS.ContentSerializer.Internal.Default.ValueListPropertyHandlers; 9 | using JOS.ContentSerializer.Internal.Default.ValueTypePropertyHandlers; 10 | using JOS.ContentSerializer.Tests.Pages; 11 | using NSubstitute; 12 | using Shouldly; 13 | using Xunit; 14 | 15 | namespace JOS.ContentSerializer.Tests 16 | { 17 | public class PropertyManagerTests 18 | { 19 | private readonly PropertyManager _sut; 20 | private readonly StandardPage _page; 21 | private readonly IContentSerializerSettings _contentSerializerSettings; 22 | private readonly IContentLoader _contentLoader; 23 | public PropertyManagerTests() 24 | { 25 | this._contentSerializerSettings = Substitute.For(); 26 | this._contentSerializerSettings.UrlSettings = new UrlSettings(); 27 | this._contentLoader = Substitute.For(); 28 | SetupContentLoader(this._contentLoader); 29 | this._sut = new PropertyManager( 30 | new PropertyNameStrategy(), 31 | new PropertyResolver(), 32 | new PropertyHandlerService() 33 | ); 34 | this._page = new StandardPageBuilder().Build(); 35 | } 36 | 37 | [Fact] 38 | public void GivenStringProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 39 | { 40 | var serviceLocator = Substitute.For(); 41 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler), out var _).Returns(x => 42 | { 43 | var selectStrategy = new DefaultSelectStrategy(); 44 | x[1] = new StringPropertyHandler(selectStrategy, selectStrategy, _contentSerializerSettings); 45 | return true; 46 | }); 47 | ServiceLocator.SetLocator(serviceLocator); 48 | 49 | var result = this._sut.GetStructuredData(_page, this._contentSerializerSettings); 50 | 51 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.Heading)) && x.Value.Equals(_page.Heading)); 52 | } 53 | 54 | [Fact] 55 | public void GivenIntProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 56 | { 57 | var serviceLocator = Substitute.For(); 58 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler), out var _).Returns(x => 59 | { 60 | x[1] = new IntPropertyHandler(_contentSerializerSettings); 61 | return true; 62 | }); 63 | ServiceLocator.SetLocator(serviceLocator); 64 | 65 | var result = this._sut.GetStructuredData(_page, this._contentSerializerSettings); 66 | 67 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.Age)) && x.Value.Equals(_page.Age)); 68 | } 69 | 70 | [Fact] 71 | public void GivenDoubleProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 72 | { 73 | var serviceLocator = Substitute.For(); 74 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler), out var _).Returns(x => 75 | { 76 | x[1] = new DoublePropertyHandler(_contentSerializerSettings); 77 | return true; 78 | }); 79 | ServiceLocator.SetLocator(serviceLocator); 80 | 81 | var result = this._sut.GetStructuredData(_page, this._contentSerializerSettings); 82 | 83 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.Degrees)) && x.Value.Equals(_page.Degrees)); 84 | } 85 | 86 | [Fact] 87 | public void GivenBoolProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 88 | { 89 | var serviceLocator = Substitute.For(); 90 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler), out var _).Returns(x => 91 | { 92 | x[1] = new BoolPropertyHandler(_contentSerializerSettings); 93 | return true; 94 | }); 95 | ServiceLocator.SetLocator(serviceLocator); 96 | var page = new StandardPageBuilder().WithPrivate(true).Build(); 97 | 98 | var result = this._sut.GetStructuredData(page, this._contentSerializerSettings); 99 | 100 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.Private)) && x.Value.Equals(page.Private)); 101 | } 102 | 103 | [Fact] 104 | public void GivenDateTimeProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 105 | { 106 | var serviceLocator = Substitute.For(); 107 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler), out var _).Returns(x => 108 | { 109 | x[1] = new DateTimePropertyHandler(_contentSerializerSettings); 110 | return true; 111 | }); 112 | ServiceLocator.SetLocator(serviceLocator); 113 | var expectedStartingDate = new DateTime(3000, 1,1); 114 | var page = new StandardPageBuilder().WithStarting(expectedStartingDate).Build(); 115 | 116 | var result = this._sut.GetStructuredData(page, this._contentSerializerSettings); 117 | 118 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.Starting)) && x.Value.Equals(page.Starting)); 119 | } 120 | 121 | [Fact] 122 | public void GivenContentReferenceProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 123 | { 124 | var contentReference = new ContentReference(2000); 125 | var page = new StandardPageBuilder().WithContentReference(contentReference).Build(); 126 | var serviceLocator = Substitute.For(); 127 | var urlHelper = Substitute.For(); 128 | var contentReferencePageUrl = "https://josefottosson.se/"; 129 | urlHelper.ContentUrl(contentReference, Arg.Any()).Returns(contentReferencePageUrl); 130 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler), out var _).Returns(x => 131 | { 132 | x[1] = new ContentReferencePropertyHandler(urlHelper, this._contentSerializerSettings); 133 | return true; 134 | }); 135 | ServiceLocator.SetLocator(serviceLocator); 136 | 137 | var result = this._sut.GetStructuredData(page, this._contentSerializerSettings); 138 | 139 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.ContentReference)) && x.Value.Equals(contentReferencePageUrl)); 140 | } 141 | 142 | [Fact] 143 | public void GivenPageReferenceProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 144 | { 145 | var pageReference = new PageReference(3000); 146 | var page = new StandardPageBuilder().WithPageReference(pageReference).Build(); 147 | var serviceLocator = Substitute.For(); 148 | var urlHelper = Substitute.For(); 149 | var pageReferenceUrl = "https://josefottosson.se/"; 150 | var contentReferencePropertyHandler = new ContentReferencePropertyHandler(urlHelper, this._contentSerializerSettings); 151 | urlHelper.ContentUrl(pageReference, Arg.Any()).Returns(pageReferenceUrl); 152 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler), out var _).Returns(x => 153 | { 154 | x[1] = new PageReferencePropertyHandler(contentReferencePropertyHandler, _contentSerializerSettings); 155 | return true; 156 | }); 157 | ServiceLocator.SetLocator(serviceLocator); 158 | 159 | var result = this._sut.GetStructuredData(page, this._contentSerializerSettings); 160 | 161 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.PageReference)) && x.Value.Equals(pageReferenceUrl)); 162 | } 163 | 164 | [Fact] 165 | public void GivenContentAreaProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 166 | { 167 | var contentArea = CreateContentArea(); 168 | var page = new StandardPageBuilder().WithMainContentArea(contentArea).Build(); 169 | var serviceLocator = Substitute.For(); 170 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler), out var _).Returns(x => 171 | { 172 | x[1] = new ContentAreaPropertyHandler(this._contentLoader, this._sut, this._contentSerializerSettings); 173 | return true; 174 | }); 175 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler), out var _).Returns(x => 176 | { 177 | var selectStrategy = new DefaultSelectStrategy(); 178 | x[1] = new StringPropertyHandler(selectStrategy, selectStrategy, _contentSerializerSettings); 179 | return true; 180 | }); 181 | ServiceLocator.SetLocator(serviceLocator); 182 | 183 | var result = this._sut.GetStructuredData(page, this._contentSerializerSettings); 184 | 185 | result.ShouldContainKey(nameof(StandardPage.MainContentArea)); 186 | } 187 | 188 | [Fact] 189 | public void GivenStringArrayProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 190 | { 191 | var strings = new[] {"any", "value"}; 192 | var page = new StandardPageBuilder().WithStrings(strings).Build(); 193 | var serviceLocator = Substitute.For(); 194 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler>), out var _).Returns(x => 195 | { 196 | x[1] = new StringListPropertyHandler(_contentSerializerSettings); 197 | return true; 198 | }); 199 | ServiceLocator.SetLocator(serviceLocator); 200 | 201 | var result = this._sut.GetStructuredData(page, this._contentSerializerSettings); 202 | 203 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.Strings)) && x.Value.Equals(strings)); 204 | } 205 | 206 | [Fact] 207 | public void GivenStringListProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 208 | { 209 | var strings = new List { "any", "value" }; 210 | var page = new StandardPageBuilder().WithStrings(strings).Build(); 211 | var serviceLocator = Substitute.For(); 212 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler>), out var _).Returns(x => 213 | { 214 | x[1] = new StringListPropertyHandler(_contentSerializerSettings); 215 | return true; 216 | }); 217 | ServiceLocator.SetLocator(serviceLocator); 218 | 219 | var result = this._sut.GetStructuredData(page, this._contentSerializerSettings); 220 | 221 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.Strings)) && x.Value.Equals(strings)); 222 | } 223 | 224 | [Fact] 225 | public void GivenIntListProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 226 | { 227 | var ints = new List { 1000, 2000 }; 228 | var page = new StandardPageBuilder().WithInts(ints).Build(); 229 | var serviceLocator = Substitute.For(); 230 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler>), out var _).Returns(x => 231 | { 232 | x[1] = new IntListPropertyHandler(_contentSerializerSettings); 233 | return true; 234 | }); 235 | ServiceLocator.SetLocator(serviceLocator); 236 | 237 | var result = this._sut.GetStructuredData(page, this._contentSerializerSettings); 238 | 239 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.Ints)) && x.Value.Equals(ints)); 240 | } 241 | 242 | [Fact] 243 | public void GivenDoubleListProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 244 | { 245 | var doubles = new List { 1000, 2000.50 }; 246 | var page = new StandardPageBuilder().WithDoubles(doubles).Build(); 247 | var serviceLocator = Substitute.For(); 248 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler>), out var _).Returns(x => 249 | { 250 | x[1] = new DoubleListPropertyHandler(_contentSerializerSettings); 251 | return true; 252 | }); 253 | ServiceLocator.SetLocator(serviceLocator); 254 | 255 | var result = this._sut.GetStructuredData(page, this._contentSerializerSettings); 256 | 257 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.Doubles)) && x.Value.Equals(doubles)); 258 | } 259 | 260 | [Fact] 261 | public void GivenDateTimeListProperty_WhenGetStructuredData_ThenReturnsCorrectValue() 262 | { 263 | var dateTimes = new List { new DateTime(2000, 1, 12), new DateTime(3000, 1 ,20) }; 264 | var page = new StandardPageBuilder().WithDateTimes(dateTimes).Build(); 265 | var serviceLocator = Substitute.For(); 266 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler>), out var _).Returns(x => 267 | { 268 | x[1] = new DateTimeListPropertyHandler(_contentSerializerSettings); 269 | return true; 270 | }); 271 | ServiceLocator.SetLocator(serviceLocator); 272 | 273 | var result = this._sut.GetStructuredData(page, this._contentSerializerSettings); 274 | 275 | result.ShouldContain(x => x.Key.Equals(nameof(StandardPage.DateTimes)) && x.Value.Equals(dateTimes)); 276 | } 277 | 278 | [Fact] 279 | public void ShouldUsePassedInContentSerializerSettings() 280 | { 281 | var pageReference = new PageReference(3000); 282 | var page = new StandardPageBuilder().WithPageReference(pageReference).Build(); 283 | var serviceLocator = Substitute.For(); 284 | var urlHelper = Substitute.For(); 285 | var pageReferenceUrl = "https://josefottosson.se/some-path"; 286 | var contentReferencePropertyHandler = new ContentReferencePropertyHandler(urlHelper, this._contentSerializerSettings); 287 | urlHelper.ContentUrl(pageReference, Arg.Any()).Returns(pageReferenceUrl); 288 | serviceLocator.TryGetExistingInstance(typeof(IPropertyHandler), out var _).Returns(x => 289 | { 290 | x[1] = new PageReferencePropertyHandler(contentReferencePropertyHandler, _contentSerializerSettings); 291 | return true; 292 | }); 293 | ServiceLocator.SetLocator(serviceLocator); 294 | var customContentSerializerSettings = new ContentSerializerSettings 295 | { 296 | UrlSettings = new UrlSettings 297 | { 298 | UseAbsoluteUrls = false 299 | } 300 | }; 301 | 302 | var result = this._sut.GetStructuredData(page, customContentSerializerSettings); 303 | 304 | result.ShouldContainKey("PageReference"); 305 | result["PageReference"].ShouldBe("/some-path"); 306 | } 307 | 308 | private static void SetupContentLoader(IContentLoader contentLoader) 309 | { 310 | contentLoader.Get(new ContentReference(1000)) 311 | .Returns(new VideoBlock 312 | { 313 | Name = "My name", 314 | Url = new Url("https://josef.guru") 315 | }); 316 | } 317 | 318 | private static ContentArea CreateContentArea() 319 | { 320 | var contentArea = Substitute.For(); 321 | var items = new List 322 | { 323 | new ContentAreaItem 324 | { 325 | ContentLink = new ContentReference(1000) 326 | } 327 | }; 328 | contentArea.Count.Returns(items.Count); 329 | contentArea.FilteredItems.Returns(items); 330 | 331 | return contentArea; 332 | } 333 | } 334 | } 335 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/PropertyNameStrategyTests.cs: -------------------------------------------------------------------------------- 1 | using JOS.ContentSerializer.Internal; 2 | using JOS.ContentSerializer.Tests.Pages; 3 | using Shouldly; 4 | using Xunit; 5 | 6 | namespace JOS.ContentSerializer.Tests 7 | { 8 | public class PropertyNameStrategyTests 9 | { 10 | private readonly PropertyNameStrategy _sut; 11 | 12 | public PropertyNameStrategyTests() 13 | { 14 | this._sut = new PropertyNameStrategy(); 15 | } 16 | 17 | [Fact] 18 | public void GivenNoContentSerializerNameAttribute_WhenGetPropertyName_ThenReturnsDeclaredName() 19 | { 20 | var page = new PropertyNameStrategyPage(); 21 | 22 | var result = this._sut.GetPropertyName(page.GetType().GetProperty(nameof(PropertyNameStrategyPage.Heading))); 23 | 24 | result.ShouldBe("Heading"); 25 | } 26 | 27 | [Fact] 28 | public void GivenContentSerializerNameAttribute_WhenGetPropertyName_ThenReturnsOverridenName() 29 | { 30 | var page = new PropertyNameStrategyPage(); 31 | 32 | var result = this._sut.GetPropertyName(page.GetType().GetProperty(nameof(PropertyNameStrategyPage.Author))); 33 | 34 | result.ShouldBe("customAuthor"); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/PropertyResolverTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using JOS.ContentSerializer.Internal; 4 | using JOS.ContentSerializer.Tests.Pages; 5 | using Shouldly; 6 | using Xunit; 7 | 8 | namespace JOS.ContentSerializer.Tests 9 | { 10 | public class PropertyResolverTests 11 | { 12 | private readonly PropertyResolver _sut; 13 | 14 | public PropertyResolverTests() 15 | { 16 | this._sut = new PropertyResolver(); 17 | } 18 | 19 | [Fact] 20 | public void GivenPage_WhenGetProperties_ThenReturnsCorrectProperties() 21 | { 22 | var page = new PropertyResolverPage(); 23 | var expected = new List 24 | { 25 | nameof(PropertyResolverPage.Heading), 26 | nameof(PropertyResolverPage.Description), 27 | nameof(PropertyResolverPage.Age), 28 | nameof(PropertyResolverPage.Starting), 29 | nameof(PropertyResolverPage.Private), 30 | nameof(PropertyResolverPage.Degrees), 31 | nameof(PropertyResolverPage.MainBody), 32 | nameof(PropertyResolverPage.MainContentArea), 33 | nameof(PropertyResolverPage.MainVideo), 34 | nameof(PropertyResolverPage.Include) 35 | }; 36 | 37 | var result = this._sut.GetProperties(page).ToList(); 38 | var includedPropertyNames = result.Select(x => x.Name); 39 | 40 | includedPropertyNames.ShouldBe(expected); 41 | result.ShouldNotContain(x => x.Name.Equals(nameof(PropertyResolverPage.Author))); 42 | result.ShouldNotContain(x => x.Name.Equals(nameof(PropertyResolverPage.Phone))); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/SelectStrategies/CustomSelectManyStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using EPiServer; 6 | using EPiServer.Core; 7 | using EPiServer.Shell.ObjectEditing; 8 | using JOS.ContentSerializer.Internal; 9 | using JOS.ContentSerializer.Internal.Default; 10 | using JOS.ContentSerializer.Tests.Pages; 11 | 12 | namespace JOS.ContentSerializer.Tests.SelectStrategies 13 | { 14 | public class CustomSelectManyStrategy : ISelectManyStrategy 15 | { 16 | private static readonly IReadOnlyDictionary> CustomProperties = 17 | new Dictionary> 18 | { 19 | { 20 | typeof(StringPropertyHandlerPage), new Dictionary 21 | { 22 | {nameof(StringPropertyHandlerPage.SelectedOnlyMany), false}, 23 | {nameof(StringPropertyHandlerPage.SelectedOnlyValueOnlyMany), true} 24 | } 25 | } 26 | }; 27 | 28 | private readonly ISelectManyStrategy _defaultSelectManyStrategy; 29 | 30 | public CustomSelectManyStrategy() 31 | { 32 | this._defaultSelectManyStrategy = new DefaultSelectStrategy(); 33 | } 34 | 35 | public object Execute(PropertyInfo property, IContentData contentData, ISelectionFactory selectionFactory) 36 | { 37 | var result = (IEnumerable)this._defaultSelectManyStrategy.Execute(property, contentData, selectionFactory); 38 | var type = contentData.GetOriginalType(); 39 | if (IsCustomContentType(type, property.Name)) 40 | { 41 | var onlyValue = CustomProperties[type][property.Name]; 42 | if (onlyValue) 43 | { 44 | return result.Where(x => x.Selected).Select(x => x.Value); 45 | } 46 | 47 | return result.Where(x => x.Selected); 48 | } 49 | 50 | return result; 51 | } 52 | 53 | private static bool IsCustomContentType(Type type, string propertyName) 54 | { 55 | return CustomProperties.ContainsKey(type) && CustomProperties[type].ContainsKey(propertyName); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/SelectStrategies/CustomSelectOneStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using EPiServer; 6 | using EPiServer.Core; 7 | using EPiServer.Shell.ObjectEditing; 8 | using JOS.ContentSerializer.Internal; 9 | using JOS.ContentSerializer.Internal.Default; 10 | using JOS.ContentSerializer.Tests.Pages; 11 | 12 | namespace JOS.ContentSerializer.Tests.SelectStrategies 13 | { 14 | public class CustomSelectOneStrategy : ISelectOneStrategy 15 | { 16 | private static readonly IReadOnlyDictionary> CustomProperties = 17 | new Dictionary> 18 | { 19 | { 20 | typeof(StringPropertyHandlerPage), new Dictionary 21 | { 22 | {nameof(StringPropertyHandlerPage.SelectedOnlyOne), false}, 23 | {nameof(StringPropertyHandlerPage.SelectedOnlyValueOnlyOne), true} 24 | } 25 | } 26 | }; 27 | 28 | private readonly ISelectOneStrategy _defaultSelectOneStrategy; 29 | public CustomSelectOneStrategy() 30 | { 31 | this._defaultSelectOneStrategy = new DefaultSelectStrategy(); 32 | } 33 | 34 | public object Execute(PropertyInfo property, IContentData contentData, ISelectionFactory selectionFactory) 35 | { 36 | var result = (IEnumerable)this._defaultSelectOneStrategy.Execute(property, contentData, selectionFactory); 37 | var type = contentData.GetOriginalType(); 38 | if (IsCustomContentType(type, property.Name)) 39 | { 40 | var onlyValue = CustomProperties[type][property.Name]; 41 | if (onlyValue) 42 | { 43 | return result.FirstOrDefault(x => x.Selected)?.Value; 44 | } 45 | 46 | return result.FirstOrDefault(x => x.Selected); 47 | } 48 | 49 | return result; 50 | } 51 | 52 | private static bool IsCustomContentType(Type type, string propertyName) 53 | { 54 | return CustomProperties.ContainsKey(type) && CustomProperties[type].ContainsKey(propertyName); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/SelectionFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using EPiServer.Shell.ObjectEditing; 3 | 4 | namespace JOS.ContentSerializer.Tests 5 | { 6 | public class SelectionFactory : ISelectionFactory 7 | { 8 | public IEnumerable GetSelections(ExtendedMetadata metadata) 9 | { 10 | return new List 11 | { 12 | new SelectItem {Text = "Option 1", Value = "option1"}, 13 | new SelectItem {Text = "Option 2", Value = "option2"}, 14 | new SelectItem {Text = "Option 3", Value = "option3"}, 15 | new SelectItem {Text = "Option 4", Value = "option4"}, 16 | new SelectItem {Text = "Option 5", Value = "option5"}, 17 | new SelectItem {Text = "Option 6", Value = "option6"}, 18 | new SelectItem {Text = "Option 7", Value = "option7"}, 19 | new SelectItem {Text = "Option 8", Value = "option8"}, 20 | new SelectItem {Text = "Option 9", Value = "option9"}, 21 | new SelectItem {Text = "Option 10", Value = "option10"}, 22 | }; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/StandardPageBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using EPiServer.Core; 4 | using JOS.ContentSerializer.Tests.Pages; 5 | using Ploeh.AutoFixture; 6 | 7 | namespace JOS.ContentSerializer.Tests 8 | { 9 | public class StandardPageBuilder 10 | { 11 | private string _heading = new Fixture().Create(); 12 | private string _description = new Fixture().Create(); 13 | private int _age = new Fixture().Create(); 14 | private double _degrees = new Fixture().Create(); 15 | private DateTime _starting = new Fixture().Create(); 16 | private bool _private = new Fixture().Create(); 17 | private XhtmlString _mainBody = new XhtmlString("

This is HTML

"); 18 | private ContentArea _mainContentArea = new ContentArea(); // TODO USE BUILDER HERE 19 | private VideoBlock _mainVideo = new VideoBlock(); // TODO USE BUILDER HERE. 20 | private ContentReference _contentReference = new ContentReference(1000); 21 | private PageReference _pageReference = new PageReference(2000); 22 | private IEnumerable _strings = new string[0]; 23 | private IEnumerable _ints = new int[0]; 24 | private IEnumerable _doubles = new double[0]; 25 | private IEnumerable _dateTimes = new DateTime[0]; 26 | 27 | public StandardPageBuilder WithHeading(string h) 28 | { 29 | this._heading = h; 30 | return this; 31 | } 32 | 33 | public StandardPageBuilder WithDescription(string d) 34 | { 35 | this._description = d; 36 | return this; 37 | } 38 | 39 | public StandardPageBuilder WithAge(int a) 40 | { 41 | this._age = a; 42 | return this; 43 | } 44 | 45 | public StandardPageBuilder WithDegrees(double d) 46 | { 47 | this._degrees = d; 48 | return this; 49 | } 50 | 51 | public StandardPageBuilder WithStarting(DateTime s) 52 | { 53 | this._starting = s; 54 | return this; 55 | } 56 | 57 | public StandardPageBuilder WithPrivate(bool p) 58 | { 59 | this._private = p; 60 | return this; 61 | } 62 | 63 | public StandardPageBuilder WithMainBody(XhtmlString m) 64 | { 65 | this._mainBody = m; 66 | return this; 67 | } 68 | 69 | public StandardPageBuilder WithMainBody(string m) 70 | { 71 | this._mainBody = new XhtmlString(m); 72 | return this; 73 | } 74 | 75 | public StandardPageBuilder WithMainContentArea(ContentArea m) 76 | { 77 | this._mainContentArea = m; 78 | return this; 79 | } 80 | 81 | public StandardPageBuilder WithMainContentArea(string m) 82 | { 83 | this._mainContentArea = new ContentArea(m); 84 | return this; 85 | } 86 | 87 | public StandardPageBuilder WithMainVideo(VideoBlock v) 88 | { 89 | this._mainVideo = v; 90 | return this; 91 | } 92 | 93 | public StandardPageBuilder WithContentReference(ContentReference c) 94 | { 95 | this._contentReference = c; 96 | return this; 97 | } 98 | 99 | public StandardPageBuilder WithPageReference(PageReference c) 100 | { 101 | this._pageReference = c; 102 | return this; 103 | } 104 | 105 | public StandardPageBuilder WithStrings(IEnumerable s) 106 | { 107 | this._strings = s; 108 | return this; 109 | } 110 | 111 | public StandardPageBuilder WithInts(IEnumerable i) 112 | { 113 | this._ints = i; 114 | return this; 115 | } 116 | 117 | public StandardPageBuilder WithDoubles(IEnumerable d) 118 | { 119 | this._doubles = d; 120 | return this; 121 | } 122 | 123 | public StandardPageBuilder WithDateTimes(IEnumerable d) 124 | { 125 | this._dateTimes = d; 126 | return this; 127 | } 128 | 129 | public StandardPage Build() 130 | { 131 | return new StandardPage 132 | { 133 | Heading = _heading, 134 | Description = _description, 135 | Age = _age, 136 | Degrees = _degrees, 137 | Private = _private, 138 | Starting = _starting, 139 | MainBody = _mainBody, 140 | MainContentArea = _mainContentArea, 141 | MainVideo = _mainVideo, 142 | ContentReference = _contentReference, 143 | PageReference = _pageReference, 144 | Strings = _strings, 145 | Ints = _ints, 146 | Doubles = _doubles, 147 | DateTimes = _dateTimes 148 | }; 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/StringPropertyHandlerWithCustomSelectStrategiesTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using JOS.ContentSerializer.Internal; 4 | using JOS.ContentSerializer.Internal.Default; 5 | using JOS.ContentSerializer.Tests.Pages; 6 | using JOS.ContentSerializer.Tests.SelectStrategies; 7 | using Shouldly; 8 | using Xunit; 9 | 10 | namespace JOS.ContentSerializer.Tests 11 | { 12 | public class StringPropertyHandlerWithCustomSelectStrategiesTests 13 | { 14 | private readonly StringPropertyHandler _sut; 15 | 16 | public StringPropertyHandlerWithCustomSelectStrategiesTests() 17 | { 18 | var customSelectOneStrategy = new CustomSelectOneStrategy(); 19 | var customSelectManyStrategy = new CustomSelectManyStrategy(); 20 | this._sut = new StringPropertyHandler(customSelectOneStrategy, customSelectManyStrategy, new ContentSerializerSettings()); 21 | } 22 | 23 | [Fact] 24 | public void GivenStringPropertyWithSelectOneAndSelectedOptionsOnly_WhenHandle_ThenReturnsCorrectValue() 25 | { 26 | var page = new StringPropertyHandlerPage 27 | { 28 | SelectedOnlyOne = "option4" 29 | }; 30 | 31 | var result = (SelectOption)this._sut.Handle(page.SelectedOnlyOne, 32 | page.GetType().GetProperty(nameof(StringPropertyHandlerPage.SelectedOnlyOne)), 33 | page); 34 | 35 | result.Selected.ShouldBeTrue(); 36 | result.Text.ShouldBe("Option 4"); 37 | result.Value.ShouldBe("option4"); 38 | } 39 | 40 | [Fact] 41 | public void GivenStringPropertyWithSelectOneAndSelectedOptionsOnly_ValueOnly_WhenHandle_ThenReturnsCorrectValue() 42 | { 43 | var page = new StringPropertyHandlerPage 44 | { 45 | SelectedOnlyValueOnlyOne = "option5" 46 | }; 47 | 48 | var result = (string)this._sut.Handle(page.SelectedOnlyValueOnlyOne, 49 | page.GetType().GetProperty(nameof(StringPropertyHandlerPage.SelectedOnlyValueOnlyOne)), 50 | page); 51 | 52 | result.ShouldBe("option5"); 53 | } 54 | 55 | [Fact] 56 | public void GivenStringPropertyWithSelectManyAndSelectedOptionsOnly_WhenHandle_ThenReturnsCorrectValue() 57 | { 58 | var page = new StringPropertyHandlerPage 59 | { 60 | SelectedOnlyMany = "option5,option6,option7" 61 | }; 62 | 63 | var result = ((IEnumerable)this._sut.Handle(page.SelectedOnlyMany, 64 | page.GetType().GetProperty(nameof(StringPropertyHandlerPage.SelectedOnlyMany)), 65 | page)).ToList(); 66 | 67 | result.ShouldContain(x => x.Selected && x.Value.Equals("option5") && x.Text.Equals("Option 5")); 68 | result.ShouldContain(x => x.Selected && x.Value.Equals("option6") && x.Text.Equals("Option 6")); 69 | result.ShouldContain(x => x.Selected && x.Value.Equals("option7") && x.Text.Equals("Option 7")); 70 | result.Count(x => x.Selected).ShouldBe(3); 71 | result.Count.ShouldBe(3); 72 | } 73 | 74 | [Fact] 75 | public void GivenStringPropertyWithSelectManyAndSelectedOptionsOnly_ValueOnly_WhenHandle_ThenReturnsCorrectValue() 76 | { 77 | var page = new StringPropertyHandlerPage 78 | { 79 | SelectedOnlyValueOnlyMany = "option5,option6,option7" 80 | }; 81 | 82 | var result = ((IEnumerable)this._sut.Handle(page.SelectedOnlyValueOnlyMany, 83 | page.GetType().GetProperty(nameof(StringPropertyHandlerPage.SelectedOnlyValueOnlyMany)), 84 | page)).ToList(); 85 | 86 | result.ShouldContain(x => x == "option5"); 87 | result.ShouldContain(x => x == "option6"); 88 | result.ShouldContain(x => x == "option7"); 89 | result.Count.ShouldBe(3); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/UrlHelperAdapterTests.cs: -------------------------------------------------------------------------------- 1 | namespace JOS.ContentSerializer.Tests 2 | { 3 | class UrlHelperAdapterTests 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/UrlPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using EPiServer; 2 | using JOS.ContentSerializer.Internal.Default; 3 | using NSubstitute; 4 | using Shouldly; 5 | using Xunit; 6 | 7 | namespace JOS.ContentSerializer.Tests 8 | { 9 | public class UrlPropertyHandlerTests 10 | { 11 | private readonly IContentSerializerSettings _contentSerializerSettings; 12 | private readonly UrlPropertyHandler _sut; 13 | private readonly IUrlHelper _urlHelper; 14 | 15 | public UrlPropertyHandlerTests() 16 | { 17 | this._contentSerializerSettings = new ContentSerializerSettings(); 18 | this._urlHelper = Substitute.For(); 19 | this._sut = new UrlPropertyHandler(this._urlHelper, _contentSerializerSettings); 20 | } 21 | 22 | [Fact] 23 | public void GivenNullUrl_WhenHandle_ThenReturnsNull() 24 | { 25 | var result = this._sut.Handle(null, null, null); 26 | 27 | result.ShouldBeNull(); 28 | } 29 | 30 | [Fact] 31 | public void GivenMailToUrl_WhenHandle_ThenReturnsCorrectValue() 32 | { 33 | var value = "mailto:mail@example.com"; 34 | var url = new Url(value); 35 | 36 | var result = this._sut.Handle(url, null, null); 37 | 38 | result.ShouldBe(value); 39 | } 40 | 41 | [Fact] 42 | public void GivenExternalLink_WhenHandle_ThenReturnsAbsoluteUrlWithQuery() 43 | { 44 | var value = "https://josef.guru/example/page?anyQueryString=true&anyOtherQuery"; 45 | var url = new Url(value); 46 | 47 | var result = this._sut.Handle(url, null, null); 48 | 49 | result.ShouldBe(value); 50 | } 51 | 52 | [Fact] 53 | public void GivenExternalLink_WhenHandleWithAbsoluteUrlSetToFalse_ThenReturnsRelativeUrlWithQuery() 54 | { 55 | this._contentSerializerSettings.UrlSettings = new UrlSettings {UseAbsoluteUrls = false}; 56 | var value = "https://josef.guru/example/page?anyQueryString=true&anyOtherQuery"; 57 | var url = new Url(value); 58 | 59 | var result = this._sut.Handle(url, null, null); 60 | 61 | result.ShouldBe(url.PathAndQuery); 62 | } 63 | 64 | [Fact] 65 | public void GivenEpiserverPage_WhenHandle_ThenReturnsRewrittenPrettyAbsoluteUrl() 66 | { 67 | var siteUrl = "https://example.com"; 68 | var prettyPath = "/rewritten/pretty-url/"; 69 | var value = "/link/d40d0056ede847d5a2f3b4a02778d15b.aspx"; 70 | var url = new Url(value); 71 | this._urlHelper.ContentUrl(Arg.Any(), this._contentSerializerSettings.UrlSettings).Returns($"{siteUrl}{prettyPath}"); 72 | 73 | var result = this._sut.Handle(url, null, null); 74 | 75 | result.ShouldBe($"{siteUrl}{prettyPath}"); 76 | } 77 | 78 | [Fact] 79 | public void GivenEpiserverPage_WhenHandleWithAbsoluteUrlSetToFalse_ThenReturnsRewrittenPrettyRelativeUrl() 80 | { 81 | var prettyPath = "/rewritten/pretty-url/"; 82 | var value = "/link/d40d0056ede847d5a2f3b4a02778d15b.aspx"; 83 | var url = new Url(value); 84 | this._contentSerializerSettings.UrlSettings = new UrlSettings { UseAbsoluteUrls = false }; 85 | this._urlHelper.ContentUrl(Arg.Any(), this._contentSerializerSettings.UrlSettings).Returns(prettyPath); 86 | 87 | var result = this._sut.Handle(url, null, null); 88 | 89 | result.ShouldBe(prettyPath); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ValueTypeListPropertyHandlers/DateTimeListPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using JOS.ContentSerializer.Internal.Default.ValueListPropertyHandlers; 5 | using Shouldly; 6 | using Xunit; 7 | 8 | namespace JOS.ContentSerializer.Tests.ValueTypeListPropertyHandlers 9 | { 10 | public class DateTimeListPropertyHandlerTests 11 | { 12 | private readonly DateTimeListPropertyHandler _sut; 13 | 14 | public DateTimeListPropertyHandlerTests() 15 | { 16 | this._sut = new DateTimeListPropertyHandler(new ContentSerializerSettings()); 17 | } 18 | 19 | [Fact] 20 | public void GivenNullList_WhenHandle_ThenReturnsNull() 21 | { 22 | var result = this._sut.Handle(null, null, null); 23 | 24 | result.ShouldBeNull(); 25 | } 26 | 27 | [Fact] 28 | public void GivenEmptyList_WhenHandle_ThenReturnsSameList() 29 | { 30 | var result = this._sut.Handle(Enumerable.Empty(), null, null); 31 | 32 | ((IEnumerable)result).ShouldBeEmpty(); 33 | } 34 | 35 | [Fact] 36 | public void GivenPopulatedList_WhenHandle_ThenReturnsSameList() 37 | { 38 | var year2000 = new DateTime(2000, 1, 20); 39 | var year3000 = new DateTime(3000, 1, 20); 40 | var items = new List { year2000, year3000}; 41 | 42 | var result = this._sut.Handle(items, null, null); 43 | 44 | ((IEnumerable)result).ShouldContain(year2000); 45 | ((IEnumerable)result).ShouldContain(year3000); 46 | ((IEnumerable)result).Count().ShouldBe(2); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ValueTypeListPropertyHandlers/DoubleListPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using JOS.ContentSerializer.Internal.Default.ValueListPropertyHandlers; 4 | using Shouldly; 5 | using Xunit; 6 | 7 | namespace JOS.ContentSerializer.Tests.ValueTypeListPropertyHandlers 8 | { 9 | public class DoubleListPropertyHandlerTests 10 | { 11 | private readonly DoubleListPropertyHandler _sut; 12 | 13 | public DoubleListPropertyHandlerTests() 14 | { 15 | this._sut = new DoubleListPropertyHandler(new ContentSerializerSettings()); 16 | } 17 | 18 | [Fact] 19 | public void GivenNullList_WhenHandle_ThenReturnsNull() 20 | { 21 | var result = this._sut.Handle(null, null, null); 22 | 23 | result.ShouldBeNull(); 24 | } 25 | 26 | [Fact] 27 | public void GivenEmptyList_WhenHandle_ThenReturnsSameList() 28 | { 29 | var result = this._sut.Handle(Enumerable.Empty(), null, null); 30 | 31 | ((IEnumerable)result).ShouldBeEmpty(); 32 | } 33 | 34 | [Fact] 35 | public void GivenPopulatedList_WhenHandle_ThenReturnsSameList() 36 | { 37 | var items = new List { 1000, 20.50 }; 38 | 39 | var result = this._sut.Handle(items, null, null); 40 | 41 | ((IEnumerable)result).ShouldContain(1000); 42 | ((IEnumerable)result).ShouldContain(20.50); 43 | ((IEnumerable)result).Count().ShouldBe(2); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ValueTypeListPropertyHandlers/IntListPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using JOS.ContentSerializer.Internal.Default.ValueListPropertyHandlers; 4 | using Shouldly; 5 | using Xunit; 6 | 7 | namespace JOS.ContentSerializer.Tests.ValueTypeListPropertyHandlers 8 | { 9 | public class IntListPropertyHandlerTests 10 | { 11 | private readonly IntListPropertyHandler _sut; 12 | 13 | public IntListPropertyHandlerTests() 14 | { 15 | this._sut = new IntListPropertyHandler(new ContentSerializerSettings()); 16 | } 17 | 18 | [Fact] 19 | public void GivenNullList_WhenHandle_ThenReturnsNull() 20 | { 21 | var result = this._sut.Handle(null, null, null); 22 | 23 | result.ShouldBeNull(); 24 | } 25 | 26 | [Fact] 27 | public void GivenEmptyList_WhenHandle_ThenReturnsSameList() 28 | { 29 | var result = this._sut.Handle(Enumerable.Empty(), null, null); 30 | 31 | ((IEnumerable)result).ShouldBeEmpty(); 32 | } 33 | 34 | [Fact] 35 | public void GivenPopulatedList_WhenHandle_ThenReturnsSameList() 36 | { 37 | var items = new List { 1000, 2000 }; 38 | 39 | var result = this._sut.Handle(items, null, null); 40 | 41 | ((IEnumerable)result).ShouldContain(1000); 42 | ((IEnumerable)result).ShouldContain(2000); 43 | ((IEnumerable)result).Count().ShouldBe(2); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ValueTypeListPropertyHandlers/StringListPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using JOS.ContentSerializer.Internal.Default.ValueListPropertyHandlers; 4 | using Shouldly; 5 | using Xunit; 6 | 7 | namespace JOS.ContentSerializer.Tests.ValueTypeListPropertyHandlers 8 | { 9 | public class StringListPropertyHandlerTests 10 | { 11 | private readonly StringListPropertyHandler _sut; 12 | 13 | public StringListPropertyHandlerTests() 14 | { 15 | this._sut = new StringListPropertyHandler(new ContentSerializerSettings()); 16 | } 17 | 18 | [Fact] 19 | public void GivenNullList_WhenHandle_ThenReturnsNull() 20 | { 21 | var result = this._sut.Handle(null, null, null); 22 | 23 | result.ShouldBeNull(); 24 | } 25 | 26 | [Fact] 27 | public void GivenEmptyList_WhenHandle_ThenReturnsSameList() 28 | { 29 | var result = this._sut.Handle(Enumerable.Empty(), null, null); 30 | 31 | ((IEnumerable)result).ShouldBeEmpty(); 32 | } 33 | 34 | [Fact] 35 | public void GivenPopulatedList_WhenHandle_ThenReturnsSameList() 36 | { 37 | var items = new List{"any", "value"}; 38 | 39 | var result = this._sut.Handle(items, null, null); 40 | 41 | ((IEnumerable)result).ShouldContain("any"); 42 | ((IEnumerable)result).ShouldContain("value"); 43 | ((IEnumerable)result).Count().ShouldBe(2); 44 | } 45 | 46 | [Fact] 47 | public void GivenStringArray_WhenHandle_ThenReturnsIEnumerableString() 48 | { 49 | var items = new[] { "any", "value" }; 50 | 51 | var result = this._sut.Handle(items, null, null); 52 | 53 | ((IEnumerable)result).ShouldContain("any"); 54 | ((IEnumerable)result).ShouldContain("value"); 55 | ((IEnumerable)result).Count().ShouldBe(2); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ValueTypePropertyHandlers/BoolPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using JOS.ContentSerializer.Internal.Default; 2 | using JOS.ContentSerializer.Tests.Pages; 3 | using Shouldly; 4 | using Xunit; 5 | 6 | namespace JOS.ContentSerializer.Tests.ValueTypePropertyHandlers 7 | { 8 | public class BoolPropertyHandlerTests 9 | { 10 | private readonly BoolPropertyHandler _sut; 11 | public BoolPropertyHandlerTests() 12 | { 13 | this._sut = new BoolPropertyHandler(new ContentSerializerSettings()); 14 | } 15 | 16 | [Fact] 17 | public void GivenBoolProperty_WhenHandle_ThenReturnsCorrectValue() 18 | { 19 | var page = new ValueTypePropertyHandlerPage 20 | { 21 | Bool = true 22 | }; 23 | 24 | var result = (bool)this._sut.Handle( 25 | page.Bool, 26 | page.GetType().GetProperty(nameof(ValueTypePropertyHandlerPage.Bool)), 27 | page); 28 | 29 | result.ShouldBeTrue(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ValueTypePropertyHandlers/DateTimePropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JOS.ContentSerializer.Internal.Default.ValueTypePropertyHandlers; 3 | using JOS.ContentSerializer.Tests.Pages; 4 | using Shouldly; 5 | using Xunit; 6 | 7 | namespace JOS.ContentSerializer.Tests.ValueTypePropertyHandlers 8 | { 9 | public class DateTimePropertyHandlerTests 10 | { 11 | private readonly DateTimePropertyHandler _sut; 12 | public DateTimePropertyHandlerTests() 13 | { 14 | this._sut = new DateTimePropertyHandler(new ContentSerializerSettings()); 15 | } 16 | 17 | [Fact] 18 | public void GivenDateTimeProperty_WhenHandle_ThenReturnsCorrectValue() 19 | { 20 | var expected = new DateTime(2000, 01, 01, 12, 00, 30); 21 | var page = new ValueTypePropertyHandlerPage 22 | { 23 | DateTime = expected 24 | }; 25 | 26 | var result = (DateTime)this._sut.Handle( 27 | page.DateTime, 28 | page.GetType().GetProperty(nameof(ValueTypePropertyHandlerPage.DateTime)), 29 | page); 30 | 31 | result.ShouldBe(expected); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ValueTypePropertyHandlers/DoublePropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using JOS.ContentSerializer.Internal.Default.ValueTypePropertyHandlers; 2 | using JOS.ContentSerializer.Tests.Pages; 3 | using Shouldly; 4 | using Xunit; 5 | 6 | namespace JOS.ContentSerializer.Tests.ValueTypePropertyHandlers 7 | { 8 | public class DoublePropertyHandlerTests 9 | { 10 | private readonly DoublePropertyHandler _sut; 11 | public DoublePropertyHandlerTests() 12 | { 13 | this._sut = new DoublePropertyHandler(new ContentSerializerSettings()); 14 | } 15 | 16 | [Fact] 17 | public void GivenDoubleProperty_WhenHandle_ThenReturnsCorrectValue() 18 | { 19 | var page = new ValueTypePropertyHandlerPage 20 | { 21 | Double = 10.50 22 | }; 23 | 24 | var result = (double)this._sut.Handle( 25 | page.Double, 26 | page.GetType().GetProperty(nameof(ValueTypePropertyHandlerPage.Double)), 27 | page); 28 | 29 | result.ShouldBe(10.50); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ValueTypePropertyHandlers/IntPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using JOS.ContentSerializer.Internal.Default.ValueTypePropertyHandlers; 2 | using JOS.ContentSerializer.Tests.Pages; 3 | using Shouldly; 4 | using Xunit; 5 | 6 | namespace JOS.ContentSerializer.Tests.ValueTypePropertyHandlers 7 | { 8 | public class IntPropertyHandlerTests 9 | { 10 | private readonly IntPropertyHandler _sut; 11 | 12 | public IntPropertyHandlerTests() 13 | { 14 | this._sut = new IntPropertyHandler(new ContentSerializerSettings()); 15 | } 16 | 17 | [Fact] 18 | public void GivenIntProperty_WhenHandle_ThenReturnsCorrectValue() 19 | { 20 | var page = new ValueTypePropertyHandlerPage 21 | { 22 | Integer = 1000 23 | }; 24 | 25 | var result = (int)this._sut.Handle( 26 | page.Integer, 27 | page.GetType().GetProperty(nameof(ValueTypePropertyHandlerPage.Integer)), 28 | page); 29 | 30 | result.ShouldBe(1000); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/ValueTypePropertyHandlers/StringPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using JOS.ContentSerializer.Internal; 4 | using JOS.ContentSerializer.Internal.Default; 5 | using JOS.ContentSerializer.Tests.Pages; 6 | using Shouldly; 7 | using Xunit; 8 | 9 | namespace JOS.ContentSerializer.Tests.ValueTypePropertyHandlers 10 | { 11 | public class StringPropertyHandlerTests 12 | { 13 | private readonly StringPropertyHandler _sut; 14 | 15 | public StringPropertyHandlerTests() 16 | { 17 | var selectStrategy = new DefaultSelectStrategy(); 18 | this._sut = new StringPropertyHandler(selectStrategy, selectStrategy, new ContentSerializerSettings()); 19 | } 20 | 21 | [Theory] 22 | [InlineData("This is the heading of the page")] 23 | [InlineData("")] 24 | [InlineData(null)] 25 | public void GivenStringProperty_WhenHandle_ThenReturnsCorrectValue(string heading) 26 | { 27 | var page = new StringPropertyHandlerPage 28 | { 29 | Heading = heading 30 | }; 31 | 32 | var result = this._sut.Handle(page.Heading, 33 | page.GetType().GetProperty(nameof(StringPropertyHandlerPage.Heading)), 34 | page); 35 | 36 | ((string)result).ShouldBe(heading); 37 | } 38 | 39 | [Fact] 40 | public void GivenStringPropertyWithSelectOneAttribute_WhenHandle_ThenReturnsCorrectValue() 41 | { 42 | var page = new StringPropertyHandlerPage 43 | { 44 | SelectOne = "option3" 45 | }; 46 | 47 | var result = (List)this._sut.Handle(page.SelectOne, 48 | page.GetType().GetProperty(nameof(StringPropertyHandlerPage.SelectOne)), 49 | page); 50 | 51 | result.ShouldContain(x => x.Selected && x.Value.Equals("option3") && x.Text.Equals("Option 3")); 52 | result.Count(x => x.Selected).ShouldBe(1); 53 | } 54 | 55 | [Theory] 56 | [InlineData(null)] 57 | [InlineData("")] 58 | public void GivenNullOrEmptyStringWithSelectOneAttribute_WhenGet_ThenReturnsCorrectValue(string selectOneValue) 59 | { 60 | var page = new StringPropertyHandlerPage 61 | { 62 | SelectOne = selectOneValue 63 | }; 64 | 65 | var result = (IEnumerable)this._sut.Handle(page.SelectOne, 66 | page.GetType().GetProperty(nameof(StringPropertyHandlerPage.SelectOne)), 67 | page); 68 | 69 | result.Count(x => x.Selected).ShouldBe(0); 70 | } 71 | 72 | [Fact] 73 | public void GivenStringPropertyWithSelectManyAttribute_WhenHandle_ThenReturnsCorrectValue() 74 | { 75 | var page = new StringPropertyHandlerPage 76 | { 77 | SelectMany = "option3,option4,option5" 78 | }; 79 | 80 | var result = (List)this._sut.Handle(page.SelectMany, 81 | page.GetType().GetProperty(nameof(StringPropertyHandlerPage.SelectMany)), 82 | page); 83 | 84 | result.ShouldContain(x => x.Selected && x.Value.Equals("option3") && x.Text.Equals("Option 3")); 85 | result.ShouldContain(x => x.Selected && x.Value.Equals("option4") && x.Text.Equals("Option 4")); 86 | result.ShouldContain(x => x.Selected && x.Value.Equals("option5") && x.Text.Equals("Option 5")); 87 | result.Count(x => x.Selected).ShouldBe(3); 88 | } 89 | 90 | [Theory] 91 | [InlineData(null)] 92 | [InlineData("")] 93 | public void GivenNullOrEmptyStringWithSelectManyAttribute_WhenGet_ThenReturnsCorrectValue(string selectManyValue) 94 | { 95 | var page = new StringPropertyHandlerPage 96 | { 97 | SelectMany = selectManyValue 98 | }; 99 | 100 | var result = (IEnumerable)this._sut.Handle(page.SelectMany, 101 | page.GetType().GetProperty(nameof(StringPropertyHandlerPage.SelectOne)), 102 | page); 103 | 104 | result.Count(x => x.Selected).ShouldBe(0); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/XhtmlStringPropertyHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using JOS.ContentSerializer.Internal.Default; 2 | using Shouldly; 3 | using Xunit; 4 | 5 | namespace JOS.ContentSerializer.Tests 6 | { 7 | public class XhtmlStringPropertyHandlerTests 8 | { 9 | private readonly XhtmlStringPropertyHandler _sut; 10 | 11 | public XhtmlStringPropertyHandlerTests() 12 | { 13 | this._sut = new XhtmlStringPropertyHandler(new ContentSerializerSettings()); 14 | } 15 | 16 | [Fact] 17 | public void GivenNullXhtmlString_WhenHandle_ThenReturnsNull() 18 | { 19 | var result = this._sut.Handle(null, null, null); 20 | 21 | result.ShouldBeNull(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.6 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JOS.ContentSerializer", "JOS.ContentSerializer\JOS.ContentSerializer.csproj", "{8A190000-F8C2-429E-931A-692C8DED1168}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JOS.ContentSerializer.Tests", "JOS.ContentSerializer.Tests\JOS.ContentSerializer.Tests.csproj", "{4A97CB84-60AB-4517-BE5D-73976D33EA91}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionFolder", "SolutionFolder", "{38D0146A-381C-4536-99A0-3EA6E553F095}" 11 | ProjectSection(SolutionItems) = preProject 12 | ..\README.md = ..\README.md 13 | EndProjectSection 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|Any CPU = Debug|Any CPU 18 | Release|Any CPU = Release|Any CPU 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {8A190000-F8C2-429E-931A-692C8DED1168}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {8A190000-F8C2-429E-931A-692C8DED1168}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {8A190000-F8C2-429E-931A-692C8DED1168}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {8A190000-F8C2-429E-931A-692C8DED1168}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {4A97CB84-60AB-4517-BE5D-73976D33EA91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {4A97CB84-60AB-4517-BE5D-73976D33EA91}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {4A97CB84-60AB-4517-BE5D-73976D33EA91}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {4A97CB84-60AB-4517-BE5D-73976D33EA91}.Release|Any CPU.Build.0 = Release|Any CPU 29 | EndGlobalSection 30 | GlobalSection(SolutionProperties) = preSolution 31 | HideSolutionNode = FALSE 32 | EndGlobalSection 33 | EndGlobal 34 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Attributes/ContentSerializerIgnoreAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace JOS.ContentSerializer.Attributes 4 | { 5 | [AttributeUsage(AttributeTargets.Property)] 6 | public class ContentSerializerIgnoreAttribute : Attribute 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Attributes/ContentSerializerIncludeAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace JOS.ContentSerializer.Attributes 4 | { 5 | [AttributeUsage(AttributeTargets.Property)] 6 | public class ContentSerializerIncludeAttribute : Attribute 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Attributes/ContentSerializerNameAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace JOS.ContentSerializer.Attributes 4 | { 5 | public class ContentSerializerNameAttribute : Attribute 6 | { 7 | public ContentSerializerNameAttribute(string name) 8 | { 9 | Name = name; 10 | } 11 | 12 | public string Name { get; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Attributes/ContentSerializerPropertyHandlerAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace JOS.ContentSerializer.Attributes 4 | { 5 | [AttributeUsage(AttributeTargets.Property)] 6 | public class ContentSerializerPropertyHandlerAttribute : Attribute 7 | { 8 | public ContentSerializerPropertyHandlerAttribute(Type propertyHandler) 9 | { 10 | PropertyHandler = propertyHandler; 11 | } 12 | 13 | public Type PropertyHandler { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Attributes/ContentSerializerWrapItemsAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace JOS.ContentSerializer.Attributes 4 | { 5 | [AttributeUsage(AttributeTargets.Property)] 6 | public class ContentSerializerWrapItemsAttribute : Attribute 7 | { 8 | public ContentSerializerWrapItemsAttribute(bool wrapItems) 9 | { 10 | WrapItems = wrapItems; 11 | } 12 | 13 | public bool WrapItems { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/ContentSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EPiServer.Core; 3 | 4 | namespace JOS.ContentSerializer 5 | { 6 | public class ContentSerializer 7 | { 8 | private readonly IContentSerializer _contentSerializer; 9 | 10 | public ContentSerializer(IContentSerializer contentSerializer) 11 | { 12 | _contentSerializer = contentSerializer ?? throw new ArgumentNullException(nameof(contentSerializer)); 13 | } 14 | 15 | public string ToJson(IContentData contentData) 16 | { 17 | return this._contentSerializer.Serialize(contentData); 18 | } 19 | 20 | public string ToJson(IContentData contentData, IContentSerializerSettings settings) 21 | { 22 | return this._contentSerializer.Serialize(contentData, settings); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/ContentSerializerSettings.cs: -------------------------------------------------------------------------------- 1 | namespace JOS.ContentSerializer 2 | { 3 | public class ContentSerializerSettings : IContentSerializerSettings 4 | { 5 | public bool WrapContentAreaItems { get; set; } = true; 6 | public IUrlSettings UrlSettings { get; set; } = new UrlSettings(); 7 | public string BlockTypePropertyName { get; set; } = "__type__"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IContentDataExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using EPiServer.Core; 4 | using EPiServer.ServiceLocation; 5 | 6 | namespace JOS.ContentSerializer 7 | { 8 | public static class IContentDataExtensions 9 | { 10 | public static string Serialize(this IContentData contentData) 11 | { 12 | var contentSerializer = ServiceLocator.Current.GetInstance(); 13 | return contentSerializer.Serialize(contentData); 14 | } 15 | 16 | public static string Serialize(this IContentData contentData, IContentSerializerSettings contentSerializerSettings) 17 | { 18 | var contentSerializer = ServiceLocator.Current.GetInstance(); 19 | return contentSerializer.Serialize(contentData, contentSerializerSettings); 20 | } 21 | 22 | public static string ToJson(this IContentData contentData) 23 | { 24 | var stopwatch = new Stopwatch(); 25 | stopwatch.Start(); 26 | var contentSerializer = GetContentJsonSerializer(); 27 | var result = contentSerializer.Serialize(contentData); 28 | stopwatch.Stop(); 29 | Trace.WriteLine($".ToJson took {stopwatch.ElapsedMilliseconds}ms"); 30 | return result; 31 | } 32 | 33 | public static string ToJson(this IContentData contentData, IContentSerializerSettings contentSerializerSettings) 34 | { 35 | var contentSerializer = GetContentJsonSerializer(); 36 | return contentSerializer.Serialize(contentData, contentSerializerSettings); 37 | } 38 | 39 | private static IContentJsonSerializer GetContentJsonSerializer() 40 | { 41 | var contentSerializer = ServiceLocator.Current.GetInstance(); 42 | return contentSerializer ?? throw new Exception($"No implementation of {nameof(IContentJsonSerializer)} could be found"); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IContentJsonSerializer.cs: -------------------------------------------------------------------------------- 1 | namespace JOS.ContentSerializer 2 | { 3 | public interface IContentJsonSerializer : IContentSerializer {} 4 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IContentSerializer.cs: -------------------------------------------------------------------------------- 1 | using EPiServer.Core; 2 | 3 | namespace JOS.ContentSerializer 4 | { 5 | public interface IContentSerializer 6 | { 7 | string Serialize(IContentData contentData); 8 | string Serialize(IContentData contentData, IContentSerializerSettings settings); 9 | object GetStructuredData(IContentData contentData); 10 | object GetStructuredData(IContentData contentData, IContentSerializerSettings settings); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IContentSerializerSettings.cs: -------------------------------------------------------------------------------- 1 | namespace JOS.ContentSerializer 2 | { 3 | public interface IContentSerializerSettings 4 | { 5 | bool WrapContentAreaItems { get; set; } 6 | IUrlSettings UrlSettings { get; set; } 7 | string BlockTypePropertyName { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using EPiServer.Core; 3 | 4 | namespace JOS.ContentSerializer 5 | { 6 | public interface IPropertyHandler 7 | { 8 | object Handle(T value, PropertyInfo property, IContentData contentData); 9 | object Handle(T value, PropertyInfo property, IContentData contentData, IContentSerializerSettings settings); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IPropertyHandlerService.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace JOS.ContentSerializer 4 | { 5 | public interface IPropertyHandlerService 6 | { 7 | object GetPropertyHandler(PropertyInfo property); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IPropertyManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using EPiServer.Core; 3 | 4 | namespace JOS.ContentSerializer 5 | { 6 | public interface IPropertyManager 7 | { 8 | Dictionary GetStructuredData( 9 | IContentData contentData, 10 | IContentSerializerSettings contentSerializerSettings); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IPropertyNameStrategy.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace JOS.ContentSerializer 4 | { 5 | public interface IPropertyNameStrategy 6 | { 7 | string GetPropertyName(PropertyInfo property); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IPropertyResolver.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | 5 | namespace JOS.ContentSerializer 6 | { 7 | public interface IPropertyResolver 8 | { 9 | IEnumerable GetProperties(IContentData contentData); 10 | } 11 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/ISelectManyStrategy.cs: -------------------------------------------------------------------------------- 1 | using JOS.ContentSerializer.Internal; 2 | 3 | namespace JOS.ContentSerializer 4 | { 5 | public interface ISelectManyStrategy : ISelectStrategy {} 6 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/ISelectOneStrategy.cs: -------------------------------------------------------------------------------- 1 | using JOS.ContentSerializer.Internal; 2 | 3 | namespace JOS.ContentSerializer 4 | { 5 | public interface ISelectOneStrategy : ISelectStrategy {} 6 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IUrlHelper.cs: -------------------------------------------------------------------------------- 1 | using EPiServer; 2 | using EPiServer.Core; 3 | 4 | namespace JOS.ContentSerializer 5 | { 6 | public interface IUrlHelper 7 | { 8 | string ContentUrl(Url url); 9 | string ContentUrl(Url url, IUrlSettings urlSettings); 10 | string ContentUrl(ContentReference contentReference); 11 | string ContentUrl(ContentReference contentReference, IUrlSettings contentReferenceSettings); 12 | } 13 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/IUrlSettings.cs: -------------------------------------------------------------------------------- 1 | namespace JOS.ContentSerializer 2 | { 3 | public interface IUrlSettings 4 | { 5 | bool UseAbsoluteUrls { get; set; } 6 | bool FallbackToWildcard { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/ContentSerializerInitalizationModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using EPiServer; 5 | using EPiServer.Core; 6 | using EPiServer.DataAbstraction; 7 | using EPiServer.Framework; 8 | using EPiServer.Framework.Initialization; 9 | using EPiServer.ServiceLocation; 10 | using EPiServer.SpecializedProperties; 11 | using JOS.ContentSerializer.Internal.Default; 12 | using JOS.ContentSerializer.Internal.Default.ValueListPropertyHandlers; 13 | using JOS.ContentSerializer.Internal.Default.ValueTypePropertyHandlers; 14 | 15 | namespace JOS.ContentSerializer.Internal 16 | { 17 | [InitializableModule] 18 | [ModuleDependency(typeof(EPiServer.Web.InitializationModule))] 19 | public class ContentSerializerInitalizationModule : IConfigurableModule 20 | { 21 | public void Uninitialize(InitializationEngine context) 22 | { 23 | 24 | } 25 | 26 | public void ConfigureContainer(ServiceConfigurationContext context) 27 | { 28 | var stopwatch = new Stopwatch(); 29 | stopwatch.Start(); 30 | context.Services.AddSingleton(); 31 | context.Services.AddSingleton(); 32 | context.Services.AddSingleton(); 33 | context.Services.AddSingleton(); 34 | context.Services.AddSingleton(); 35 | context.Services.AddSingleton(); 36 | context.Services.AddSingleton(); 37 | context.Services.AddSingleton(); 38 | 39 | context.Services.AddSingleton, IntPropertyHandler>(); 40 | context.Services.AddSingleton, BoolPropertyHandler>(); 41 | context.Services.AddSingleton, DoublePropertyHandler>(); 42 | context.Services.AddSingleton, DateTimePropertyHandler>(); 43 | context.Services.AddSingleton, ContentAreaPropertyHandler>(); 44 | context.Services.AddSingleton, ContentReferencePropertyHandler>(); 45 | context.Services.AddSingleton, PageReferencePropertyHandler>(); 46 | context.Services.AddSingleton>, ContentReferenceListPropertyHandler>(); 47 | context.Services.AddSingleton, LinkItemCollectionPropertyHandler>(); 48 | context.Services.AddSingleton, PageTypePropertyHandler>(); 49 | context.Services.AddSingleton, StringPropertyHandler>(); 50 | context.Services.AddSingleton, UrlPropertyHandler>(); 51 | context.Services.AddSingleton, XhtmlStringPropertyHandler>(); 52 | context.Services.AddSingleton, BlockDataPropertyHandler>(); 53 | 54 | context.Services.AddSingleton(); 55 | context.Services.AddSingleton>>(x => x.GetInstance()); 56 | context.Services.AddSingleton>>(x => x.GetInstance()); 57 | context.Services.AddSingleton>>(x => x.GetInstance()); 58 | context.Services.AddSingleton>(x => x.GetInstance()); 59 | context.Services.AddSingleton(); 60 | context.Services.AddSingleton>>(x => x.GetInstance()); 61 | context.Services.AddSingleton>>(x => x.GetInstance()); 62 | context.Services.AddSingleton>>(x => x.GetInstance()); 63 | context.Services.AddSingleton(); 64 | context.Services.AddSingleton>>(x => x.GetInstance()); 65 | context.Services.AddSingleton>>(x => x.GetInstance()); 66 | context.Services.AddSingleton>>(x => x.GetInstance()); 67 | context.Services.AddSingleton(); 68 | context.Services.AddSingleton>>(x => x.GetInstance()); 69 | context.Services.AddSingleton>>(x => x.GetInstance()); 70 | context.Services.AddSingleton>>(x => x.GetInstance()); 71 | context.Services.AddSingleton, NullableTimeSpanPropertyHandler>(); 72 | 73 | var defaultSelectStrategy = new DefaultSelectStrategy(); 74 | context.Services.AddSingleton(defaultSelectStrategy); 75 | context.Services.AddSingleton(defaultSelectStrategy); 76 | 77 | stopwatch.Stop(); 78 | Trace.WriteLine($"{nameof(ContentSerializerInitalizationModule)} took {stopwatch.ElapsedMilliseconds}ms"); 79 | } 80 | 81 | public void Initialize(InitializationEngine context) 82 | { 83 | 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/BlockDataPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | 5 | namespace JOS.ContentSerializer.Internal.Default 6 | { 7 | public class BlockDataPropertyHandler : IPropertyHandler 8 | { 9 | private readonly IPropertyManager _propertyManager; 10 | private readonly IContentSerializerSettings _contentSerializerSettings; 11 | 12 | public BlockDataPropertyHandler( 13 | IPropertyManager propertyManager, 14 | IContentSerializerSettings contentSerializerSettings) 15 | { 16 | _propertyManager = propertyManager ?? throw new ArgumentNullException(nameof(propertyManager)); 17 | _contentSerializerSettings = contentSerializerSettings; 18 | } 19 | 20 | public object Handle(BlockData value, PropertyInfo property, IContentData contentData) 21 | { 22 | return Handle(value, property, contentData, _contentSerializerSettings); 23 | } 24 | 25 | public object Handle( 26 | BlockData value, 27 | PropertyInfo property, 28 | IContentData contentData, 29 | IContentSerializerSettings settings) 30 | { 31 | return this._propertyManager.GetStructuredData(value, settings); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/BoolPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | 5 | namespace JOS.ContentSerializer.Internal.Default 6 | { 7 | public class BoolPropertyHandler : IPropertyHandler 8 | { 9 | private readonly IContentSerializerSettings _contentSerializerSettings; 10 | 11 | public BoolPropertyHandler(IContentSerializerSettings contentSerializerSettings) 12 | { 13 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 14 | } 15 | 16 | public object Handle(bool value, PropertyInfo property, IContentData contentData) 17 | { 18 | return Handle(value, property, contentData, _contentSerializerSettings); 19 | } 20 | 21 | public object Handle( 22 | bool value, 23 | PropertyInfo property, 24 | IContentData contentData, 25 | IContentSerializerSettings settings) 26 | { 27 | return value; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ContentAreaPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using EPiServer; 6 | using EPiServer.Core; 7 | using JOS.ContentSerializer.Attributes; 8 | 9 | namespace JOS.ContentSerializer.Internal.Default 10 | { 11 | public class ContentAreaPropertyHandler : IPropertyHandler 12 | { 13 | private readonly IContentLoader _contentLoader; 14 | private readonly IPropertyManager _propertyManager; 15 | private readonly IContentSerializerSettings _contentSerializerSettings; 16 | 17 | public ContentAreaPropertyHandler( 18 | IContentLoader contentLoader, 19 | IPropertyManager propertyManager, 20 | IContentSerializerSettings contentSerializerSettings) 21 | { 22 | _contentLoader = contentLoader ?? throw new ArgumentNullException(nameof(contentLoader)); 23 | _propertyManager = propertyManager ?? throw new ArgumentNullException(nameof(propertyManager)); 24 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 25 | } 26 | 27 | public object Handle(ContentArea contentArea, PropertyInfo propertyInfo, IContentData contentData) 28 | { 29 | return Handle(contentArea, propertyInfo, contentData, _contentSerializerSettings); 30 | } 31 | 32 | public object Handle( 33 | ContentArea contentArea, 34 | PropertyInfo property, 35 | IContentData contentData, 36 | IContentSerializerSettings settings) 37 | { 38 | if (contentArea == null) 39 | { 40 | return null; 41 | } 42 | var contentAreaItems = GetContentAreaItems(contentArea); 43 | if (WrapItems(contentArea, settings)) 44 | { 45 | var items = new Dictionary>(); 46 | foreach (var item in contentAreaItems) 47 | { 48 | var result = this._propertyManager.GetStructuredData(item, settings); 49 | var typeName = item.GetOriginalType().Name; 50 | result.Add(settings.BlockTypePropertyName, typeName); 51 | if (items.ContainsKey(typeName)) 52 | { 53 | items[typeName].Add(result); 54 | } 55 | else 56 | { 57 | items[typeName] = new List { result }; 58 | } 59 | } 60 | 61 | return items; 62 | } 63 | else 64 | { 65 | var items = new List(); 66 | foreach (var item in contentAreaItems) 67 | { 68 | var result = this._propertyManager.GetStructuredData(item, settings); 69 | result.Add(settings.BlockTypePropertyName, item.GetOriginalType().Name); 70 | items.Add(result); 71 | } 72 | 73 | return items; 74 | } 75 | } 76 | 77 | private IEnumerable GetContentAreaItems(ContentArea contentArea) 78 | { 79 | if (contentArea?.FilteredItems == null || !contentArea.FilteredItems.Any()) 80 | { 81 | return Enumerable.Empty(); 82 | } 83 | 84 | var content = new List(); 85 | foreach (var contentAreaItem in contentArea.FilteredItems) 86 | { 87 | var loadedContent = this._contentLoader.Get(contentAreaItem.ContentLink); 88 | if (loadedContent != null) 89 | { 90 | content.Add(loadedContent); 91 | } 92 | } 93 | 94 | return content; 95 | } 96 | 97 | private static bool WrapItems(ContentArea contentArea, IContentSerializerSettings contentSerializerSettings) 98 | { 99 | var wrapItemsAttribute = contentArea.GetType().GetCustomAttribute(); 100 | var wrapItems = wrapItemsAttribute?.WrapItems ?? contentSerializerSettings.WrapContentAreaItems; 101 | return wrapItems; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ContentReferenceListPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using EPiServer.Core; 5 | 6 | namespace JOS.ContentSerializer.Internal.Default 7 | { 8 | public class ContentReferenceListPropertyHandler : IPropertyHandler> 9 | { 10 | private readonly IPropertyHandler _contentReferencePropertyHandler; 11 | private readonly IContentSerializerSettings _contentSerializerSettings; 12 | 13 | public ContentReferenceListPropertyHandler( 14 | IPropertyHandler contentReferencePropertyHandler, 15 | IContentSerializerSettings contentSerializerSettings) 16 | { 17 | _contentReferencePropertyHandler = contentReferencePropertyHandler ?? throw new ArgumentNullException(nameof(contentReferencePropertyHandler)); 18 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 19 | } 20 | 21 | public object Handle( 22 | IEnumerable contentReferences, 23 | PropertyInfo property, 24 | IContentData contentData) 25 | { 26 | return Handle(contentReferences, property, contentData, _contentSerializerSettings); 27 | } 28 | 29 | public object Handle( 30 | IEnumerable contentReferences, 31 | PropertyInfo property, 32 | IContentData contentData, 33 | IContentSerializerSettings settings) 34 | { 35 | if (contentReferences == null) 36 | { 37 | return null; 38 | } 39 | var links = new List(); 40 | 41 | foreach (var contentReference in contentReferences) 42 | { 43 | var result = this._contentReferencePropertyHandler.Handle( 44 | contentReference, 45 | property, 46 | contentData, 47 | settings); 48 | links.Add(result); 49 | } 50 | 51 | return links; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ContentReferencePropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | 5 | namespace JOS.ContentSerializer.Internal.Default 6 | { 7 | public class ContentReferencePropertyHandler : IPropertyHandler 8 | { 9 | private readonly IUrlHelper _urlHelper; 10 | private readonly IContentSerializerSettings _contentSerializerSettings; 11 | 12 | public ContentReferencePropertyHandler(IUrlHelper urlHelper, IContentSerializerSettings contentSerializerSettings) 13 | { 14 | _urlHelper = urlHelper; 15 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 16 | } 17 | 18 | public object Handle(ContentReference contentReference, PropertyInfo propertyInfo, IContentData contentData) 19 | { 20 | return Handle(contentReference, propertyInfo, contentData, _contentSerializerSettings); 21 | } 22 | 23 | public object Handle( 24 | ContentReference contentReference, 25 | PropertyInfo property, 26 | IContentData contentData, 27 | IContentSerializerSettings settings) 28 | { 29 | if (contentReference == null || contentReference == ContentReference.EmptyReference) 30 | { 31 | return null; 32 | } 33 | 34 | var url = new Uri(this._urlHelper.ContentUrl(contentReference, settings.UrlSettings)); 35 | 36 | if (settings.UrlSettings.UseAbsoluteUrls && url.IsAbsoluteUri) 37 | { 38 | return url.AbsoluteUri; 39 | } 40 | 41 | return url.PathAndQuery; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/DefaultSelectStrategy.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Reflection; 4 | using EPiServer.Core; 5 | using EPiServer.Shell.ObjectEditing; 6 | 7 | namespace JOS.ContentSerializer.Internal.Default 8 | { 9 | public class DefaultSelectStrategy : ISelectOneStrategy, ISelectManyStrategy 10 | { 11 | public object Execute(PropertyInfo property, IContentData contentData, ISelectionFactory selectionFactory) 12 | { 13 | return GetStructuredData(property, contentData, selectionFactory); 14 | } 15 | 16 | private static object GetStructuredData(PropertyInfo property, IContentData contentData, ISelectionFactory selectionFactory) 17 | { 18 | var selectOptions = GetSelectionOptions(selectionFactory, property); 19 | var propertyValue = (string)property.GetValue(contentData); 20 | return GetSelectOptions(propertyValue, selectOptions); 21 | } 22 | 23 | private static IEnumerable GetSelectionOptions(ISelectionFactory selectionFactory, object property) 24 | { 25 | var options = selectionFactory.GetSelections(property as ExtendedMetadata); 26 | return options; 27 | } 28 | 29 | private static IEnumerable GetSelectOptions(string property, IEnumerable selectOptions) 30 | { 31 | var items = new List(); 32 | var selectedValues = property?.Split(',') ?? Enumerable.Empty(); 33 | 34 | foreach (var option in selectOptions) 35 | { 36 | var item = new SelectOption 37 | { 38 | Selected = selectedValues.Contains(option.Value.ToString()), 39 | Text = option.Text, 40 | Value = option.Value.ToString() 41 | }; 42 | 43 | items.Add(item); 44 | } 45 | 46 | return items; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/LinkItemCollectionPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using EPiServer; 6 | using EPiServer.Core; 7 | using EPiServer.SpecializedProperties; 8 | 9 | namespace JOS.ContentSerializer.Internal.Default 10 | { 11 | public class LinkItemCollectionPropertyHandler : IPropertyHandler 12 | { 13 | private readonly IUrlHelper _urlHelper; 14 | private readonly IContentSerializerSettings _contentSerializerSettings; 15 | 16 | public LinkItemCollectionPropertyHandler(IUrlHelper urlHelper, IContentSerializerSettings contentSerializerSettings) 17 | { 18 | _urlHelper = urlHelper ?? throw new ArgumentNullException(nameof(urlHelper)); 19 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 20 | } 21 | 22 | public object Handle(LinkItemCollection linkItemCollection, PropertyInfo propertyInfo, IContentData contentData) 23 | { 24 | return Handle(linkItemCollection, propertyInfo, contentData, _contentSerializerSettings); 25 | } 26 | 27 | public object Handle(LinkItemCollection linkItemCollection, 28 | PropertyInfo property, 29 | IContentData contentData, 30 | IContentSerializerSettings settings) 31 | { 32 | if (linkItemCollection == null) 33 | { 34 | return null; 35 | } 36 | var links = new List(); 37 | 38 | foreach (var link in linkItemCollection) 39 | { 40 | string prettyUrl = null; 41 | if (link.ReferencedPermanentLinkIds.Any()) 42 | { 43 | var url = new Url(link.Href); 44 | prettyUrl = this._urlHelper.ContentUrl(url, settings.UrlSettings); 45 | } 46 | links.Add(new LinkItem 47 | { 48 | Text = link.Text, 49 | Target = link.Target, 50 | Title = link.Title, 51 | Href = prettyUrl ?? link.Href 52 | }); 53 | } 54 | 55 | return links; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/NullableTimeSpanPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | 5 | namespace JOS.ContentSerializer.Internal.Default 6 | { 7 | public class NullableTimeSpanPropertyHandler : IPropertyHandler 8 | { 9 | private readonly IContentSerializerSettings _contentSerializerSettings; 10 | 11 | public NullableTimeSpanPropertyHandler(IContentSerializerSettings contentSerializerSettings) 12 | { 13 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 14 | } 15 | 16 | public object Handle( 17 | TimeSpan? value, 18 | PropertyInfo property, 19 | IContentData contentData) 20 | { 21 | return Handle(value, property, contentData, _contentSerializerSettings); 22 | } 23 | 24 | public object Handle( 25 | TimeSpan? value, 26 | PropertyInfo property, 27 | IContentData contentData, 28 | IContentSerializerSettings settings) 29 | { 30 | return value?.ToString(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/PageReferencePropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | 5 | namespace JOS.ContentSerializer.Internal.Default 6 | { 7 | public class PageReferencePropertyHandler : IPropertyHandler 8 | { 9 | private readonly IPropertyHandler _contentReferencePropertyHandler; 10 | private readonly IContentSerializerSettings _contentSerializerSettings; 11 | 12 | public PageReferencePropertyHandler( 13 | IPropertyHandler contentReferencePropertyHandler, 14 | IContentSerializerSettings contentSerializerSettings) 15 | { 16 | _contentReferencePropertyHandler = contentReferencePropertyHandler ?? throw new ArgumentNullException(nameof(contentReferencePropertyHandler)); 17 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 18 | } 19 | 20 | public object Handle(PageReference value, PropertyInfo property, IContentData contentData) 21 | { 22 | return Handle(value, property, contentData, _contentSerializerSettings); 23 | } 24 | 25 | public object Handle( 26 | PageReference value, 27 | PropertyInfo property, 28 | IContentData contentData, 29 | IContentSerializerSettings settings) 30 | { 31 | return this._contentReferencePropertyHandler.Handle(value, property, contentData, settings); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/PageTypeModel.cs: -------------------------------------------------------------------------------- 1 | namespace JOS.ContentSerializer.Internal.Default 2 | { 3 | public class PageTypeModel 4 | { 5 | public PageTypeModel(string name, int contentTypeId) 6 | { 7 | Name = name; 8 | ContentTypeId = contentTypeId; 9 | } 10 | 11 | public string Name { get; } 12 | public int ContentTypeId { get; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/PageTypePropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | using EPiServer.DataAbstraction; 5 | 6 | namespace JOS.ContentSerializer.Internal.Default 7 | { 8 | public class PageTypePropertyHandler : IPropertyHandler 9 | { 10 | private readonly IContentSerializerSettings _contentSerializerSettings; 11 | 12 | public PageTypePropertyHandler(IContentSerializerSettings contentSerializerSettings) 13 | { 14 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 15 | } 16 | 17 | public object Handle( 18 | PageType value, 19 | PropertyInfo propertyInfo, 20 | IContentData contentData) 21 | { 22 | return Handle(value, propertyInfo, contentData, _contentSerializerSettings); 23 | } 24 | 25 | public object Handle( 26 | PageType value, 27 | PropertyInfo property, 28 | IContentData contentData, 29 | IContentSerializerSettings settings) 30 | { 31 | return value == null ? null : new PageTypeModel(value.Name, value.ID); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/StringPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | using EPiServer.Shell.ObjectEditing; 5 | 6 | namespace JOS.ContentSerializer.Internal.Default 7 | { 8 | public class StringPropertyHandler : IPropertyHandler 9 | { 10 | private readonly ISelectOneStrategy _selectOneStrategy; 11 | private readonly ISelectManyStrategy _selectManyStrategy; 12 | private readonly IContentSerializerSettings _contentSerializerSettings; 13 | 14 | public StringPropertyHandler( 15 | ISelectOneStrategy selectOneStrategy, 16 | ISelectManyStrategy selectManyStrategy, 17 | IContentSerializerSettings contentSerializerSettings) 18 | { 19 | _selectOneStrategy = selectOneStrategy ?? throw new ArgumentNullException(nameof(selectOneStrategy)); 20 | _selectManyStrategy = selectManyStrategy ?? throw new ArgumentNullException(nameof(selectManyStrategy)); 21 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 22 | } 23 | 24 | public object Handle( 25 | string stringValue, 26 | PropertyInfo property, 27 | IContentData contentData) 28 | { 29 | return Handle(stringValue, property, contentData, _contentSerializerSettings); 30 | } 31 | 32 | public object Handle(string stringValue, PropertyInfo property, IContentData contentData, IContentSerializerSettings settings) 33 | { 34 | if (HasSelectAttribute(property)) 35 | { 36 | var selectOneAttribute = GetSelectOneAttribute(property); 37 | if (selectOneAttribute != null) 38 | { 39 | var selectionFactory = CreateSelectionFactoryInstance(selectOneAttribute.SelectionFactoryType); 40 | return this._selectOneStrategy.Execute(property, contentData, selectionFactory); 41 | } 42 | else 43 | { 44 | var selectManyAttribute = GetSelectManyAttribute(property); 45 | var selectionFactory = CreateSelectionFactoryInstance(selectManyAttribute.SelectionFactoryType); 46 | return this._selectManyStrategy.Execute(property, contentData, selectionFactory); 47 | } 48 | } 49 | 50 | return stringValue; 51 | } 52 | 53 | private static ISelectionFactory CreateSelectionFactoryInstance(Type type) 54 | { 55 | return (ISelectionFactory) Activator.CreateInstance(type); 56 | } 57 | 58 | private static bool HasSelectAttribute(PropertyInfo property) 59 | { 60 | var selectOne = GetSelectOneAttribute(property); 61 | if (selectOne != null) return true; 62 | 63 | var selectMany = GetSelectManyAttribute(property); 64 | return selectMany != null; 65 | } 66 | 67 | private static SelectOneAttribute GetSelectOneAttribute(PropertyInfo propertyInfo) 68 | { 69 | var attribute = (SelectOneAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(SelectOneAttribute)); 70 | return attribute; 71 | } 72 | 73 | private static SelectManyAttribute GetSelectManyAttribute(PropertyInfo propertyInfo) 74 | { 75 | var selectMany = (SelectManyAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(SelectManyAttribute)); 76 | return selectMany; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/UrlPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer; 4 | using EPiServer.Core; 5 | 6 | namespace JOS.ContentSerializer.Internal.Default 7 | { 8 | public class UrlPropertyHandler : IPropertyHandler 9 | { 10 | private readonly IUrlHelper _urlHelper; 11 | private readonly IContentSerializerSettings _contentSerializerSettings; 12 | private const string MailTo = "mailto"; 13 | 14 | public UrlPropertyHandler(IUrlHelper urlHelper, IContentSerializerSettings contentSerializerSettings) 15 | { 16 | _urlHelper = urlHelper ?? throw new ArgumentNullException(nameof(urlHelper)); 17 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 18 | } 19 | 20 | public object Handle( 21 | Url url, 22 | PropertyInfo propertyInfo, 23 | IContentData contentData) 24 | { 25 | return Handle(url, propertyInfo, contentData, _contentSerializerSettings); 26 | } 27 | 28 | public object Handle( 29 | Url url, 30 | PropertyInfo property, 31 | IContentData contentData, 32 | IContentSerializerSettings settings) 33 | { 34 | if (url == null) 35 | { 36 | return null; 37 | } 38 | 39 | if (url.Scheme == MailTo) return url.OriginalString; 40 | 41 | if (url.IsAbsoluteUri) 42 | { 43 | if (settings.UrlSettings.UseAbsoluteUrls) 44 | { 45 | return url.OriginalString; 46 | } 47 | 48 | return url.PathAndQuery; 49 | } 50 | 51 | return this._urlHelper.ContentUrl(url, settings.UrlSettings); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ValueListPropertyHandlers/DateTimeListPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using EPiServer.Core; 5 | 6 | namespace JOS.ContentSerializer.Internal.Default.ValueListPropertyHandlers 7 | { 8 | public class DateTimeListPropertyHandler : IPropertyHandler> 9 | { 10 | private readonly IContentSerializerSettings _contentSerializerSettings; 11 | 12 | public DateTimeListPropertyHandler(IContentSerializerSettings contentSerializerSettings) 13 | { 14 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 15 | } 16 | 17 | public object Handle(IEnumerable value, PropertyInfo property, IContentData contentData) 18 | { 19 | return Handle(value, property, contentData, _contentSerializerSettings); 20 | } 21 | 22 | public object Handle( 23 | IEnumerable value, 24 | PropertyInfo property, 25 | IContentData contentData, 26 | IContentSerializerSettings settings) 27 | { 28 | return value; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ValueListPropertyHandlers/DoubleListPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using EPiServer.Core; 5 | 6 | namespace JOS.ContentSerializer.Internal.Default.ValueListPropertyHandlers 7 | { 8 | public class DoubleListPropertyHandler : IPropertyHandler> 9 | { 10 | private readonly IContentSerializerSettings _contentSerializerSettings; 11 | 12 | public DoubleListPropertyHandler(IContentSerializerSettings contentSerializerSettings) 13 | { 14 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 15 | } 16 | 17 | public object Handle(IEnumerable value, PropertyInfo property, IContentData contentData) 18 | { 19 | return Handle(value, property, contentData, _contentSerializerSettings); 20 | } 21 | 22 | public object Handle(IEnumerable value, PropertyInfo property, IContentData contentData, IContentSerializerSettings settings) 23 | { 24 | return value; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ValueListPropertyHandlers/IntListPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using EPiServer.Core; 5 | 6 | namespace JOS.ContentSerializer.Internal.Default.ValueListPropertyHandlers 7 | { 8 | public class IntListPropertyHandler : IPropertyHandler> 9 | { 10 | private readonly IContentSerializerSettings _contentSerializerSettings; 11 | 12 | public IntListPropertyHandler(IContentSerializerSettings contentSerializerSettings) 13 | { 14 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 15 | } 16 | 17 | public object Handle(IEnumerable value, PropertyInfo property, IContentData contentData) 18 | { 19 | return Handle(value, property, contentData, _contentSerializerSettings); 20 | } 21 | 22 | public object Handle(IEnumerable value, PropertyInfo property, IContentData contentData, IContentSerializerSettings settings) 23 | { 24 | return value; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ValueListPropertyHandlers/StringListPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using EPiServer.Core; 5 | 6 | namespace JOS.ContentSerializer.Internal.Default.ValueListPropertyHandlers 7 | { 8 | public class StringListPropertyHandler : IPropertyHandler> 9 | { 10 | private readonly IContentSerializerSettings _contentSerializerSettings; 11 | 12 | public StringListPropertyHandler(IContentSerializerSettings contentSerializerSettings) 13 | { 14 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 15 | } 16 | 17 | public object Handle(IEnumerable value, PropertyInfo property, IContentData contentData) 18 | { 19 | return Handle(value, property, contentData, _contentSerializerSettings); 20 | } 21 | 22 | public object Handle( 23 | IEnumerable value, 24 | PropertyInfo property, 25 | IContentData contentData, 26 | IContentSerializerSettings settings) 27 | { 28 | return value; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ValueTypePropertyHandlers/DateTimePropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | 5 | namespace JOS.ContentSerializer.Internal.Default.ValueTypePropertyHandlers 6 | { 7 | public class DateTimePropertyHandler : IPropertyHandler 8 | { 9 | private readonly IContentSerializerSettings _contentSerializerSettings; 10 | 11 | public DateTimePropertyHandler(IContentSerializerSettings contentSerializerSettings) 12 | { 13 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 14 | } 15 | 16 | public object Handle(DateTime value, PropertyInfo property, IContentData contentData) 17 | { 18 | return Handle(value, property, contentData, _contentSerializerSettings); 19 | } 20 | 21 | public object Handle(DateTime value, PropertyInfo property, IContentData contentData, IContentSerializerSettings settings) 22 | { 23 | return value; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ValueTypePropertyHandlers/DoublePropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | 5 | namespace JOS.ContentSerializer.Internal.Default.ValueTypePropertyHandlers 6 | { 7 | public class DoublePropertyHandler : IPropertyHandler 8 | { 9 | private readonly IContentSerializerSettings _contentSerializerSettings; 10 | 11 | public DoublePropertyHandler(IContentSerializerSettings contentSerializerSettings) 12 | { 13 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 14 | } 15 | 16 | public object Handle(double value, PropertyInfo property, IContentData contentData) 17 | { 18 | return Handle(value, property, contentData, _contentSerializerSettings); 19 | } 20 | 21 | public object Handle( 22 | double value, 23 | PropertyInfo property, 24 | IContentData contentData, 25 | IContentSerializerSettings settings) 26 | { 27 | return value; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ValueTypePropertyHandlers/IntPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | 5 | namespace JOS.ContentSerializer.Internal.Default.ValueTypePropertyHandlers 6 | { 7 | public class IntPropertyHandler : IPropertyHandler 8 | { 9 | private readonly IContentSerializerSettings _contentSerializerSettings; 10 | 11 | public IntPropertyHandler(IContentSerializerSettings contentSerializerSettings) 12 | { 13 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 14 | } 15 | 16 | public object Handle(int value, PropertyInfo property, IContentData contentData) 17 | { 18 | return Handle(value, property, contentData, _contentSerializerSettings); 19 | } 20 | 21 | public object Handle(int value, 22 | PropertyInfo property, 23 | IContentData contentData, 24 | IContentSerializerSettings settings) 25 | { 26 | return value; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/ValueTypePropertyHandlers/StringPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using EPiServer.Core; 6 | using EPiServer.Shell.ObjectEditing; 7 | 8 | namespace JOS.ContentSerializer.Internal.Default.ValueTypePropertyHandlers 9 | { 10 | public class StringPropertyHandler : IPropertyHandler 11 | { 12 | public object Handle(string stringValue, PropertyInfo property, IContentData contentData) 13 | { 14 | if (HasSelectAttribute(property)) 15 | { 16 | var selectOneAttribute = GetSelectOneAttribute(property); 17 | Type selectionFactoryType; 18 | if (selectOneAttribute != null) 19 | { 20 | selectionFactoryType = selectOneAttribute.SelectionFactoryType; 21 | } 22 | else 23 | { 24 | var selectManyAttribute = GetSelectManyAttribute(property); 25 | selectionFactoryType = selectManyAttribute.SelectionFactoryType; 26 | } 27 | 28 | var valueAsDictionary = GetStructuredData(property, contentData, selectionFactoryType); 29 | return valueAsDictionary; 30 | } 31 | 32 | return stringValue; 33 | } 34 | 35 | private static bool HasSelectAttribute(PropertyInfo property) 36 | { 37 | var selectOne = GetSelectOneAttribute(property); 38 | if (selectOne != null) return true; 39 | 40 | var selectMany = GetSelectManyAttribute(property); 41 | return selectMany != null; 42 | } 43 | 44 | private static SelectOneAttribute GetSelectOneAttribute(PropertyInfo propertyInfo) 45 | { 46 | var attribute = (SelectOneAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(SelectOneAttribute)); 47 | return attribute; 48 | } 49 | 50 | private static SelectManyAttribute GetSelectManyAttribute(PropertyInfo propertyInfo) 51 | { 52 | var selectMany = (SelectManyAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(SelectManyAttribute)); 53 | return selectMany; 54 | } 55 | 56 | private static object GetStructuredData(PropertyInfo property, IContentData contentData, Type selectionFactoryType) 57 | { 58 | var selectOptions = GetSelectionOptions(selectionFactoryType, property); 59 | var propertyValue = (string)property.GetValue(contentData); 60 | return GetSelectOptions(propertyValue, selectOptions); 61 | } 62 | 63 | private static IEnumerable GetSelectionOptions(Type selectionFactoryType, object property) 64 | { 65 | var factory = (ISelectionFactory)Activator.CreateInstance(selectionFactoryType); 66 | var options = factory.GetSelections(property as ExtendedMetadata); 67 | return options; 68 | } 69 | 70 | private static IEnumerable GetSelectOptions(string property, IEnumerable selectOptions) 71 | { 72 | var items = new List(); 73 | var selectedValues = property?.Split(',') ?? Enumerable.Empty(); 74 | 75 | foreach (var option in selectOptions) 76 | { 77 | var item = new SelectOption 78 | { 79 | Selected = selectedValues.Contains(option.Value.ToString()), 80 | Text = option.Text, 81 | Value = option.Value.ToString() 82 | }; 83 | 84 | items.Add(item); 85 | } 86 | 87 | return items; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/Default/XhtmlStringPropertyHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.Core; 4 | 5 | namespace JOS.ContentSerializer.Internal.Default 6 | { 7 | public class XhtmlStringPropertyHandler : IPropertyHandler 8 | { 9 | private readonly IContentSerializerSettings _contentSerializerSettings; 10 | 11 | public XhtmlStringPropertyHandler(IContentSerializerSettings contentSerializerSettings) 12 | { 13 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 14 | } 15 | 16 | public object Handle( 17 | XhtmlString value, 18 | PropertyInfo property, 19 | IContentData contentData) 20 | { 21 | return Handle(value, property, contentData, _contentSerializerSettings); 22 | } 23 | 24 | public object Handle( 25 | XhtmlString value, 26 | PropertyInfo property, 27 | IContentData contentData, 28 | IContentSerializerSettings settings) 29 | { 30 | //TODO Fix parsing of images/blocks/links etc so we can provide pretty links. 31 | return value?.ToHtmlString(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/ISelectStrategy.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using EPiServer.Core; 3 | using EPiServer.Shell.ObjectEditing; 4 | 5 | namespace JOS.ContentSerializer.Internal 6 | { 7 | public interface ISelectStrategy 8 | { 9 | object Execute(PropertyInfo property, IContentData contentData, ISelectionFactory selectionFactory); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/JsonContentSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EPiServer.Core; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Serialization; 5 | 6 | namespace JOS.ContentSerializer.Internal 7 | { 8 | public class JsonContentSerializer : IContentJsonSerializer 9 | { 10 | private readonly IPropertyManager _propertyManager; 11 | private readonly IContentSerializerSettings _contentSerializerSettings; 12 | private static readonly JsonSerializerSettings JsonSerializerSettings; 13 | 14 | static JsonContentSerializer() 15 | { 16 | JsonSerializerSettings = new JsonSerializerSettings 17 | { 18 | ContractResolver = new CamelCasePropertyNamesContractResolver() 19 | }; 20 | } 21 | 22 | public JsonContentSerializer(IPropertyManager propertyManager, IContentSerializerSettings contentSerializerSettings) 23 | { 24 | _propertyManager = propertyManager ?? throw new ArgumentNullException(nameof(propertyManager)); 25 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 26 | } 27 | 28 | public string Serialize(IContentData contentData) 29 | { 30 | return Execute(contentData, _contentSerializerSettings); 31 | } 32 | 33 | public string Serialize(IContentData contentData, IContentSerializerSettings settings) 34 | { 35 | return Execute(contentData, settings); 36 | } 37 | 38 | public object GetStructuredData(IContentData contentData) 39 | { 40 | return this._propertyManager.GetStructuredData(contentData, _contentSerializerSettings); 41 | } 42 | 43 | public object GetStructuredData(IContentData contentData, IContentSerializerSettings settings) 44 | { 45 | return this._propertyManager.GetStructuredData(contentData, settings); 46 | } 47 | 48 | private string Execute(IContentData contentData, IContentSerializerSettings settings) 49 | { 50 | var result = this._propertyManager.GetStructuredData(contentData, settings); 51 | return JsonConvert.SerializeObject(result, JsonSerializerSettings); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/LinkItem.cs: -------------------------------------------------------------------------------- 1 | namespace JOS.ContentSerializer.Internal 2 | { 3 | public class LinkItem 4 | { 5 | public string Href { get; set; } 6 | public string Title { get; set; } 7 | public string Target { get; set; } 8 | public string Text { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/PropertyHandlerService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using EPiServer.ServiceLocation; 4 | using JOS.ContentSerializer.Attributes; 5 | 6 | namespace JOS.ContentSerializer.Internal 7 | { 8 | public class PropertyHandlerService : IPropertyHandlerService 9 | { 10 | private readonly Type _propertyHandlerType = typeof(IPropertyHandler<>); 11 | 12 | public object GetPropertyHandler(PropertyInfo property) 13 | { 14 | if (property == null) 15 | { 16 | return null; 17 | } 18 | var customPropertyHandlerAttribute = property.GetCustomAttribute(); 19 | if (customPropertyHandlerAttribute != null) 20 | { 21 | ServiceLocator.Current.TryGetExistingInstance(customPropertyHandlerAttribute.PropertyHandler, out var attributePropertyHandler); 22 | return attributePropertyHandler; 23 | } 24 | 25 | var propertyHandlerType = this._propertyHandlerType.MakeGenericType(property.PropertyType); 26 | ServiceLocator.Current.TryGetExistingInstance(propertyHandlerType, out var propertyHandler); 27 | return propertyHandler; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/PropertyManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Reflection; 7 | using EPiServer.Core; 8 | 9 | namespace JOS.ContentSerializer.Internal 10 | { 11 | public class PropertyManager : IPropertyManager 12 | { 13 | private static readonly ConcurrentDictionary CachedHandleMethodInfos; 14 | private readonly IPropertyResolver _propertyResolver; 15 | private readonly IPropertyNameStrategy _propertyNameStrategy; 16 | private readonly IPropertyHandlerService _propertyHandlerService; 17 | 18 | static PropertyManager() 19 | { 20 | CachedHandleMethodInfos = new ConcurrentDictionary(); 21 | } 22 | 23 | public PropertyManager( 24 | IPropertyNameStrategy propertyNameStrategy, 25 | IPropertyResolver propertyResolver, 26 | IPropertyHandlerService propertyHandlerService 27 | ) 28 | { 29 | _propertyNameStrategy = propertyNameStrategy ?? throw new ArgumentNullException(nameof(propertyNameStrategy)); 30 | _propertyResolver = propertyResolver ?? throw new ArgumentNullException(nameof(propertyResolver)); 31 | _propertyHandlerService = propertyHandlerService; 32 | } 33 | 34 | public Dictionary GetStructuredData( 35 | IContentData contentData, 36 | IContentSerializerSettings settings) 37 | { 38 | var properties = this._propertyResolver.GetProperties(contentData); 39 | var structuredData = new Dictionary(); 40 | 41 | foreach (var property in properties) 42 | { 43 | var propertyHandler = this._propertyHandlerService.GetPropertyHandler(property); 44 | if (propertyHandler == null) 45 | { 46 | Trace.WriteLine($"No PropertyHandler was found for type '{property.PropertyType}'"); 47 | continue; 48 | } 49 | 50 | var method = GetMethodInfo(propertyHandler); 51 | 52 | var key = this._propertyNameStrategy.GetPropertyName(property); 53 | var value = property.GetValue(contentData); 54 | var result = method.Invoke(propertyHandler, new[] { value, property, contentData, settings }); 55 | structuredData.Add(key, result); 56 | } 57 | return structuredData; 58 | } 59 | 60 | private static MethodInfo GetMethodInfo(object propertyHandler) 61 | { 62 | var type = propertyHandler.GetType(); 63 | if (CachedHandleMethodInfos.ContainsKey(type)) 64 | { 65 | CachedHandleMethodInfos.TryGetValue(type, out var cachedMethod); 66 | return cachedMethod; 67 | } 68 | 69 | var method = propertyHandler.GetType().GetMethods() 70 | .Where(x => x.Name.Equals(nameof(IPropertyHandler.Handle))) 71 | .OrderByDescending(x => x.GetParameters().Length) 72 | .First(); 73 | 74 | CachedHandleMethodInfos.TryAdd(type, method); 75 | return method; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/PropertyNameStrategy.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using JOS.ContentSerializer.Attributes; 3 | 4 | namespace JOS.ContentSerializer.Internal 5 | { 6 | public class PropertyNameStrategy : IPropertyNameStrategy 7 | { 8 | public string GetPropertyName(PropertyInfo property) 9 | { 10 | var nameAttribute = property.GetCustomAttribute(); 11 | return nameAttribute == null ? property.Name : nameAttribute.Name; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/PropertyResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Reflection; 7 | using EPiServer; 8 | using EPiServer.Core; 9 | using JOS.ContentSerializer.Attributes; 10 | 11 | namespace JOS.ContentSerializer.Internal 12 | { 13 | public class PropertyResolver : IPropertyResolver 14 | { 15 | private static ConcurrentDictionary> _cachedContentTypes; 16 | 17 | public PropertyResolver() 18 | { 19 | _cachedContentTypes = new ConcurrentDictionary>(); 20 | } 21 | 22 | public IEnumerable GetProperties(IContentData contentData) 23 | { 24 | var type = contentData.GetOriginalType(); 25 | if (_cachedContentTypes.ContainsKey(type)) 26 | { 27 | return _cachedContentTypes[type]; 28 | } 29 | 30 | var properties = type.GetProperties().Where(ShouldBeIncluded).ToList(); 31 | _cachedContentTypes[type] = properties; 32 | return properties; 33 | } 34 | 35 | private static bool ShouldBeIncluded(PropertyInfo property) 36 | { 37 | var attributes = Attribute.GetCustomAttributes(property); 38 | 39 | var ignoreAttribute = attributes.OfType().FirstOrDefault(); 40 | 41 | if (ignoreAttribute != null) 42 | { 43 | return false; 44 | } 45 | 46 | var displayAttribute = attributes.OfType().FirstOrDefault(); 47 | if (displayAttribute != null) 48 | { 49 | return true; 50 | } 51 | 52 | var includeAttribute = attributes.OfType().FirstOrDefault(); 53 | return includeAttribute != null; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/SelectOption.cs: -------------------------------------------------------------------------------- 1 | namespace JOS.ContentSerializer.Internal 2 | { 3 | public class SelectOption 4 | { 5 | public bool Selected { get; set; } 6 | public string Text { get; set; } 7 | public string Value { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/Internal/UrlHelperAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Mvc; 3 | using EPiServer; 4 | using EPiServer.Core; 5 | using EPiServer.Web; 6 | using EPiServer.Web.Mvc.Html; 7 | 8 | namespace JOS.ContentSerializer.Internal 9 | { 10 | public class UrlHelperAdapter : IUrlHelper 11 | { 12 | private readonly UrlHelper _urlHelper; 13 | private readonly ISiteDefinitionResolver _siteDefinitionResolver; 14 | private readonly IRequestHostResolver _requestHostResolver; 15 | private readonly IContentSerializerSettings _contentSerializerSettings; 16 | 17 | public UrlHelperAdapter( 18 | UrlHelper urlHelper, 19 | ISiteDefinitionResolver siteDefinitionResolver, 20 | IRequestHostResolver requestHostResolver, 21 | IContentSerializerSettings contentSerializerSettings) 22 | { 23 | _requestHostResolver = requestHostResolver ?? throw new ArgumentNullException(nameof(requestHostResolver)); 24 | _urlHelper = urlHelper ?? throw new ArgumentNullException(nameof(urlHelper)); 25 | _siteDefinitionResolver = siteDefinitionResolver ?? throw new ArgumentNullException(nameof(siteDefinitionResolver)); 26 | _contentSerializerSettings = contentSerializerSettings ?? throw new ArgumentNullException(nameof(contentSerializerSettings)); 27 | } 28 | 29 | public string ContentUrl(Url url) 30 | { 31 | return Execute(url, this._contentSerializerSettings.UrlSettings); 32 | } 33 | 34 | public string ContentUrl(Url url, IUrlSettings urlSettings) 35 | { 36 | return Execute(url, urlSettings); 37 | } 38 | 39 | public string ContentUrl(ContentReference contentReference) 40 | { 41 | return Execute(contentReference, this._contentSerializerSettings.UrlSettings); 42 | } 43 | 44 | public string ContentUrl(ContentReference contentReference, IUrlSettings urlSettings) 45 | { 46 | return Execute(contentReference, urlSettings); 47 | } 48 | 49 | private string Execute(Url url, IUrlSettings urlSettings) 50 | { 51 | var prettyUrl = this._urlHelper.ContentUrl(url); 52 | if (urlSettings.UseAbsoluteUrls) 53 | { 54 | return CreateAbsoluteUrl(prettyUrl, urlSettings.FallbackToWildcard); 55 | } 56 | 57 | return prettyUrl; 58 | } 59 | 60 | private string Execute(ContentReference contentReference, IUrlSettings urlSettings) 61 | { 62 | var prettyUrl = this._urlHelper.ContentUrl(contentReference); 63 | if (urlSettings.UseAbsoluteUrls) 64 | { 65 | return CreateAbsoluteUrl(prettyUrl, urlSettings.FallbackToWildcard); 66 | } 67 | 68 | return prettyUrl; 69 | } 70 | 71 | private string CreateAbsoluteUrl(string relativeUrl, bool fallbackToWildcard) 72 | { 73 | var siteDefinition = this._siteDefinitionResolver.GetByHostname( 74 | this._requestHostResolver.HostName, 75 | fallbackToWildcard 76 | ); 77 | var uri = new Uri(siteDefinition.SiteUrl, relativeUrl); 78 | return uri.AbsoluteUri; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/JOS.ContentSerializer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8A190000-F8C2-429E-931A-692C8DED1168} 8 | Library 9 | Properties 10 | JOS.ContentSerializer 11 | JOS.ContentSerializer 12 | v4.6.1 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | ..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll 36 | 37 | 38 | ..\packages\Castle.Windsor.4.1.0\lib\net45\Castle.Windsor.dll 39 | 40 | 41 | ..\packages\EPiServer.CMS.Core.11.1.0\lib\net461\EPiServer.dll 42 | 43 | 44 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.ApplicationModules.dll 45 | 46 | 47 | ..\packages\EPiServer.CMS.AspNet.11.1.0\lib\net461\EPiServer.Cms.AspNet.dll 48 | 49 | 50 | ..\packages\EPiServer.CMS.UI.Core.11.1.0\lib\net461\EPiServer.Cms.Shell.UI.dll 51 | 52 | 53 | ..\packages\EPiServer.CMS.AspNet.11.1.0\lib\net461\EPiServer.Configuration.dll 54 | 55 | 56 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.Data.dll 57 | 58 | 59 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.Data.Cache.dll 60 | 61 | 62 | ..\packages\EPiServer.CMS.Core.11.1.0\lib\net461\EPiServer.Enterprise.dll 63 | 64 | 65 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.Events.dll 66 | 67 | 68 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.Framework.dll 69 | 70 | 71 | ..\packages\EPiServer.Framework.AspNet.11.1.0\lib\net461\EPiServer.Framework.AspNet.dll 72 | 73 | 74 | ..\packages\EPiServer.CMS.AspNet.11.1.0\lib\net461\EPiServer.ImageLibrary.dll 75 | 76 | 77 | ..\packages\EPiServer.Framework.11.1.0\lib\net461\EPiServer.Licensing.dll 78 | 79 | 80 | ..\packages\EPiServer.CMS.Core.11.1.0\lib\net461\EPiServer.LinkAnalyzer.dll 81 | 82 | 83 | ..\packages\EPiServer.CMS.UI.Core.11.1.0\lib\net461\EPiServer.Shell.dll 84 | 85 | 86 | ..\packages\EPiServer.CMS.UI.Core.11.1.0\lib\net461\EPiServer.Shell.UI.dll 87 | 88 | 89 | ..\packages\EPiServer.CMS.UI.Core.11.1.0\lib\net461\EPiServer.UI.dll 90 | 91 | 92 | ..\packages\EPiServer.CMS.AspNet.11.1.0\lib\net461\EPiServer.Web.WebControls.dll 93 | 94 | 95 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 96 | 97 | 98 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 99 | 100 | 101 | 102 | ..\packages\System.ComponentModel.Annotations.4.4.0\lib\net461\System.ComponentModel.Annotations.dll 103 | 104 | 105 | 106 | 107 | ..\packages\System.Data.SqlClient.4.4.0\lib\net461\System.Data.SqlClient.dll 108 | 109 | 110 | 111 | ..\packages\System.Security.AccessControl.4.4.0\lib\net461\System.Security.AccessControl.dll 112 | 113 | 114 | ..\packages\System.Security.Cryptography.Xml.4.4.0\lib\net461\System.Security.Cryptography.Xml.dll 115 | 116 | 117 | ..\packages\System.Security.Permissions.4.4.0\lib\net461\System.Security.Permissions.dll 118 | 119 | 120 | ..\packages\System.Security.Principal.Windows.4.4.0\lib\net461\System.Security.Principal.Windows.dll 121 | 122 | 123 | ..\packages\System.Threading.AccessControl.4.4.0\lib\net461\System.Threading.AccessControl.dll 124 | 125 | 126 | ..\packages\Microsoft.Tpl.Dataflow.4.5.24\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll 127 | True 128 | 129 | 130 | 131 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll 132 | 133 | 134 | ..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll 135 | 136 | 137 | ..\packages\Microsoft.AspNet.Razor.2.0.20710.0\lib\net40\System.Web.Razor.dll 138 | 139 | 140 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll 141 | 142 | 143 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll 144 | 145 | 146 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/JOS.ContentSerializer.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | JOS.ContentSerializer 5 | $version$ 6 | Josef Ottosson 7 | A library that lets you serialize any ContentData object by simply calling .Serialize or .ToJson on it. 8 | en-US 9 | https://github.com/joseftw/JOS.ContentSerializer 10 | 11 | Fixes ContentSerializerSettings bug 12 | 13 | episerver json 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/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("JOS.DefaultContentSerializer")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("JOS.DefaultContentSerializer")] 13 | [assembly: AssemblyCopyright("Copyright © 2021")] 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("8a190000-f8c2-429e-931a-692c8ded1168")] 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("5.0.0.0")] 36 | [assembly: AssemblyFileVersion("5.0.0.0")] 37 | [assembly: InternalsVisibleTo("JOS.DefaultContentSerializer.Tests")] -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/UrlSettings.cs: -------------------------------------------------------------------------------- 1 | namespace JOS.ContentSerializer 2 | { 3 | public class UrlSettings : IUrlSettings 4 | { 5 | public bool UseAbsoluteUrls { get; set; } = true; 6 | public bool FallbackToWildcard { get; set; } = true; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/JOS.ContentSerializer/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | --------------------------------------------------------------------------------