Skip to content

Releases: OnTopicCMS/OnTopic-Library

v5.2.0

26 Jun 19:43
Compare
Choose a tag to compare

OnTopic 5.2.0 introduces support for response caching (#89), a new ErrorController for HTTP error codes (#91), and improvements to ITopicMappingService performance via optional AttributeDictionary constructors (#99), updates to the internal reflection libraries (#90), and caching of compatible properties (#102). In addition, it also includes a number of internal code improvements, such as adoption of new C# 10 capabilities (#96), including global using directives (#93).

Features

  • #89 Response caching is now supported on TopicController, via OnTopic support for cache profiles
  • #91 (Re)introduced an ErrorController to fully handle HTTP error handling within ASP.NET Core
  • #99 Support for AttributeDictionary constructors on view models to improve performance of ITopicMappingService

Improvements

  • #90 Improved performance in reflection by use of Delegate.CreateDelegate()
  • #90 Significant refactoring of the OnTopic.Internal.Reflection classes around the TypeAccessor(Cache), instead of (Type)MemberInfoCollection (reference)
  • #101 Allow the ErrorController to be bypassed for static files, thus preferring a lightweight response code instead of a friendly error page
  • #102 Cache mappings to compatible members on corresponding Topic classes (e.g., ContentTypeDescriptor) via MemberAccessor.IsCompatible()
  • #106 Add a SQL constraint to ensure that topics under a given parent topic can't have duplicate keys

For a comprehensive list of features, improvements, and code changes, see Pull Request #108.

v5.1.0

12 Apr 19:53
Compare
Choose a tag to compare

OnTopic 5.1.0 is a minor release which introduces support for mapping constructor parameters (#35) and defining what model to use when mapping associations via the [MapAs()] attribute (#41). Primarily, however, it is focused on bug fixes, and resolves a number of priority issues.

Features

  • #37 Reference configuration posted to OnTopic-Schema
  • #41 [MapAs()] attribute for specifying the mapping type of a property or collection
  • #35 Map constructor parameters

Improvements

  • #83 TopicMappingService: Proactively check type compatibility
  • #72 Sitemap: Exclude Private or System Branches with IsProtected
  • #77 Validate !IsNew on TopicRepository methods
  • #42 ReverseTopicMappingService: Overwrite existing topic references

Bugs

  • #47 Delete() throws exception if topic references are present
  • #46 Load() treats deleted references as unresolved
  • #76 Unable to move first child after a sibling
  • #53 Existing Topics w/ Parent marked IsDirty()
  • #73 Implicitly IsDirty() topics not being saved
  • #86 Versions getting saved even if no attributes have been modified
  • #71 Null values overwrite initialized defaults
  • #38, #52 IncomingRelationships are not being removed from TopicReferenceCollection.Clear() or SetValue() w/null
  • #79 Remove() and Clear() offer a backdoor to enforceBusinessLogic
  • #50 TopicRenamed event not being raised
  • #75, #88 Factor associations into ConsolidateVersions, DeleteOrphanedLastModifiedAttributes
  • #78 VersionHistoryIndex should account for all versioned tables, not just Attributes
  • #60, #61 Prioritize area views over regular views, and fall back
  • #61 Views should fall back to using the controller action, if available
  • #63 TopicViewResultExecutor fails if there are multiple HTTP Accept Header values

For a comprehensive list of bug fixes and improvements, see Pull Request #85.

v5.0.0

03 Mar 00:25
Compare
Choose a tag to compare

OnTopic 5.0.0 is a major release primarily focused on reliability and tidying up the interface. It includes a significant number of breaking changes—though only a handful of them will affect most implementers.

New Features

  • Metapackage: Established OnTopic.All metapackage which includes a reference to all of the core packages and implementations (c15bf2e).
  • SourceLink: Configured SourceLink with references to GitHub commits so that packages can be properly debugged by implementers (f7fb979).
  • IntelliSense: The NuGet packages now include the XML documentation, thus allowing implementers to benefit from IntelliSense annotations in Visual Studio (219ece4).
  • Lookup Fallback Types: Allow multiple fallback types to be defined when calling ITypeLookupService.Lookup() (ab4253d).
  • Topic References: Introduced support for keyed topic references via Topic.References, with full support for enforcing business logic (31144cc).
  • Full Versioning Support: Introduced versioning support for Relationships and TopicReferences, in addition to the previous support for versioning in Attributes and ExtendedAttributes (0e808ea).
  • Repository Caching: Established a ITopicRepository.Refresh() interface (3d51b14), SqlTopicRepository.Refresh() implementation (6dbf973), as well as a GetTopicUpdates stored procedure (0f36947) to allow occasional cache updates without needing to reload the entire topic graph (164de05).
  • Contextual Loading: When calling ITopicRepository.Load(), an optional referenceTopic can now be passed; this allows individual topics or topic branches to be loaded, while still being able to connect relationships and topic references to elsewhere in the topic graph (180526e). It can also be used to update topics already in the topic graph.
  • Resolve Associations: TopicRepository.Save() will now recurse over Children and attempt to resolve unresolved associations, such as relationships and topic references (fdd0025, e703de5); previously, this had to be implemented by each individual implementation.
  • Repository Events: ITopicRepository now supports the TopicLoaded and TopicSaved events, in addition to the previous TopicRenamed, TopicMoved and TopicDeleted events (37b38f5).
  • C# 9.0 Records: Introduced support for mapping C# 9.0 records with init setters in the topic mapping services (75dea66, 145c2a4) and updated all view models and binding models from read/write classes to C#'s new read-only, immutable record types (10d0652).
  • Core Attributes: TopicKey, ContentType, and ParentID are now first-class columns in the Topics table (c50f44d), greatly simplifying querying for the core attributes.
  • SQL Unit Tests: Introduced unit tests for stored procedures and functions for SQL Server database schema (91e3fe4) as well as for the SqlDataReader extension methods used by SqlTopicRepository (b91c292), thus offering far more assurances over the correctness and regression testing.

Bug Fixes

  • Post-Exception Business Logic Enforcement: If an exception occurs while enforcing business logic on Topic.Attributes, the request will be de-registered, thus ensuring any subsequent attempts to set an item with the same key will have business logic enforced (1b5dd5b). Previously, the exception could prevent that process from being completed, thus introducing a potential loophole during subsequent actions.
  • Track Deleted Attributes: Ensured that AttributeCollection.Clear() correctly marked the collection as IsDirty(), if appropriate, by accounting any DeletedAttributes (ce3cc43).
  • Track Attribute Reversions: Ensured that all modified AttributeRecord instances in a TopicRepositoryBase.Rollback() operation were correctly marked as IsDirty, thus ensuring they would be properly Save()d (e77d8eb).
  • Allow Duplicate Topic Keys in Relationships: The Topic.Relationships collection now allows relationships to different topics with the same Topic.Key (66ccd9d). Previously, this used a KeyedTopicCollection, which artificially restricted it to relationships with a unique Key.
  • Allow Duplication Topic Keys in FindAll(): Fixed a bug in the Topic.FindAll() extension methods which prevented it from returning multiple topics which the same Key, even if they represented different entities (75f6369).
  • Track Version in Reversion: Fixed bug in the GetTopicVersion stored procedure which resulted in the Version column not being returned for Attributes or ExtendedAttributes, and thus the AttributeRecord.LastModified not being properly updated during e.g. a Rollback() (622d575). In practice, this didn't harm anything, but it prevented removal of legacy schema validation which explicitly looked for the Version column.
  • Map Overriden Members and Overloaded Methods: Resolved an issue where the MemberInfoCollection<T>—used by the topic mapping services—would throw an exception if an overloaded or overridden member was present on a type (75dea66). Now, it will simply defer to the first or most derived instance of a member, and ignore all others. This enables support for C# 9.0 records, which have an implicit compiler-injected override, and is also a logical default for most scenarios where this might occur.
  • Allow Multiple Roots: Fixed bug where calling the CreateTopic or MoveTopic stored procedures with a null @ParentID would result in a corrupted hierarchy (500ca09). This isn't an expected use case, but we obviously want to make sure there's no risk of corrupting the hierarchy if it does occur.
  • Stored Procedure Errors: Fixed the RAISERROR() calls in the MoveTopic stored procedure; these weren't working correctly due to a formatting bug (bfdec1c).

Breaking changes

For a quick summary of all renamed and removed types, members, and methods, see #27.

  • .NET Framework Support: Removed support for .NET Standard 2.0 and, thus, .NET Framework; this effectively ends support for OnTopic-WebForms, OnTopic-MVC, and OnTopic-Editor-WebForms (b3ba1a0).
  • Topic.DerivedTopic: Renamed Topic.DerivedTopic to the more semantically accurate Topic.BaseTopic (2486ab2). This breaks not only calls to Topic.DerivedTopic, but also database records for e.g. ReferenceKeys storing the DerivedTopic value. The OnTopic 5.x database migration script addresses the data aspects of the migrations.
  • Immutable View Models: Changed all view models and binding models from read/write classes to C#'s new read-only, immutable record types (10d0652). This necessitates that all adopters that rely on these migrate any derived types from classes to records.
  • Keyed Topic Collections: Renamed TopicCollection classes (such as TopicCollection<T>, ReadOnlyTopicCollection) to KeyedTopicCollection (e.g., KeyedTopicCollection<T>, ReadOnlyKeyedTopicCollection) to better communicate that the items are indexed and, thus, must have a unique key, even if they represent different entities (826b93c).
  • Attribute Collection: Renamed AttributeValueCollection to AttributeCollection, and AttributeValue to AttributeRecord (f51407a).
  • TopicRelationshipMultiMap: The RelatedTopicCollection and NamedTopicCollection used by Topic.Relationships have been replaced with TopicRelationshipMultiMap (57ff3f9, 7129289), ReadOnlyTopicMultiMap (eb5c1c3), and TopicMultiMap (d049ea9). Care was taken to maintain the overall interface. The interface for calls to the underlying collections, however, will have changed (66ccd9d). Most notably, all write operations must now go through SetValue(), Remove(), or Clear(). In addition, for callers iterating over the relationships, the relationship key is now Key not Name, the topics are now stored under a Values property, and the methods now require a full Topic reference, instead of just a Topic.Key (0d9dcd5).
  • GetValue() Syntax: Renamed (ReadOnly)KeyedTopicCollection<T>.GetTopic() to GetValue() (6674c7d); on TopicRelationshipMultiMap (i.e., Topic.Relationships), renamed GetAllTopics(), GetTopics(), RemoveTopic(), and ClearTopics() to GetAllValues(), GetValues(), Remove(), and Clear() for consistency with other collections, and especially the TrackedRecordCollection used by AttributeCollection and TopicRelationshipCollection (34a8c52).
  • OnTopic.Lookup namespace: Consolidated all ITypeLookupService implementations into a new OnTopic.Lookup namespace (f80e084).
  • Load() by Unique Key: Modified Load(topicKey) to instead expect a fully-qualified UniqueKey (e.g., Root:Web:Products); as part of that, renamed the topicKey parameter to uniqueKey to disambiguate usage (4c3d30f).
  • Mapping Attributes: Renamed [Relationship()] to [Collection()] (f84ae66), [Follow()] to [Include()] (7c150d8), RelationshipType to CollectionType (1daf799), and Relationships to AssociationTypes (78600fd) as part of a broader effort to establish a more consistent and unified nomenclature that distinguishes between topic associations and specific types of associations, such as Topic.Relationships, Topic.References, or Topic.BaseTopic (b01216e).
  • Filter by Content Type: The [FilterByAttribute()] attribute continues to operate as it previously did, but can no longer be used to filter by ContentType since content type is no longer stored in Topic.Attributes (4a9f5b7); instead, use the new [FilterByContentType()] attribute (105cfdd). If ContentType is used with [FilterByAttribute()], an ArgumentException will be thrown (c68040a).
  • IRouteBuilder Support: Removed (deprecated) support for IRouteBuilder extension methods in ASP.NET Core; implementers should use end point routing via IEndpointRouteBuilder instead (6be993b, 19612ac).
  • **`Navigat...
Read more

v4.6.0

01 Dec 00:14
Compare
Choose a tag to compare

OnTopic 4.6.0 includes a few minor features, most notably improvements over routing and reporting for the ASP.NET Core TopicController. In addition, it upgrades the underlying code to C# 9.0 in order to take advantage of some new capabilities such as improved pattern matching and implicitly typed initializers.

Features

  • Updated [ValidateTopic] attribute to redirect to canonical URL to ensure consistency in analytics, indexes (0edab34)
  • Updated Topic.Load(RouteData) extension to return null if an invalid Key is submitted (b303f13); this results in the TopicController treating incorrect topic paths (e.g., /Web/!@~/) as 404s instead of exceptions
  • Added support for enabling (IsIndexed) and configuring (IndexLabel) an optional table of contents to the ContentListTopicViewModel (e9ccb06)

Bug Fixes

  • Fixed issue with where the delegate is validated in the HierarchicalTopicMappingService.GetViewModelAsnc() method (69dff49)

Improvements

  • Updated code to use C# 9.0 pattern matching and implicitly typed initializers (d63f2b5)
  • Updated to latest versions of internal packages, and implemented (4838da8)
  • Updated to latest version of Code Analysis and fixed most issues introduced with C# 9.0 (089c96a)

Note: There are some Code Analysis false positives that remain with C# 9.0. Those are presumably fixed with the new Microsoft.CodeAnalysis.NetAnalyzers 5.0.0. There appears to be a bug in getting that to work with .NET 3.x projects, however, so it's not yet implemented. That will be revisited in a future release.

v4.5.0

30 Sep 23:24
Compare
Choose a tag to compare

This update focuses primarily on minor feature improvements, such as new extension methods for Topic (7d08ac6) and AttributeValueCollection (9795dd1), as well as new utility functions in the SQL schema (1e9b1d5), such as GetUniqueKey() (a2ac659) and GetTopicIDByUniqueKey() (ea97f91). It also includes a number of bug fixes as well as some cleanup. Most notably, it fixes a bug where existing attributes values cannot be reset to empty under certain circumstances—notably include those involving the OnTopic Editor (1e4812f).

Features and Improvements

  • Added MarkClean() methods to AttributeValueCollection to improve the semantics for IsDirty tracking and to better account for deleted attributes (1e4812f)
  • Added FindAll() (4dbf872), FindFirstParent() (aa54ccf), and GetContentTypeDescriptor() (026e7a3) extension methods for Topic (7d08ac6)
  • Added GetDouble() (148a1b1) and SetDouble() (23f9ce2) extension methods to AttributeValueCollection (9795dd1)
  • Added GetChildTopicIDs() (8e0eca5) and FindTopicIDs() (1dfd333) functions in order to facilitate tree traversal and lookups in SQL
  • Added GetUniqueKey() (a2ac659), GetTopicIDByUniqueKey() (ea97f91), and GetExtendedAttribute() (28a4694) functions, as well as a UniqueKeyIndex view (b09ca5d) to the SQL database schema (1e9b1d5)
  • Added and implemented (68492d2) the AddOrReplace() (cd92791) and TryAdd() (027ae25) methods to the StaticTypeLookupService to simplify inheritance (6687431)
  • Significant updates to GenerateNestedSet to support transactions and topic ordering, while eliminating the need for Topics.RangeRight to allow NULL (c6b50f3)

Bug Fixes

  • Fixed a bug where a deleted attribute might not get saved since deleted attributes didn't result in the AttributeValueCollection being marked as IsDirty() (1e4812f)
  • Updated GetAttributes() stored procedure as a function (aa040ef) to return the latest version of both indexed and extended attributes (05ae378)
  • Used UTC time for @Version parameter when updating the database via SqlTopicRepository.Save() to avoid time mismatches between computers (d85743d)
  • Updated RelatedTopicCollection.RemoveTopic() to remove reciprocal IncomingRelationships in order to avoid stale content or orphaned references (4514244)
  • Improved validation for TopicRepositoryBase.Delete() (67b70ca), including checks for isRecursive mismatches (29c904a) and orphaned DerivedTopics (58057e1), as well as handling of orphaned relationships (13e4fe9, 2550779)

Cleanup

  • Cleanup of SQL objects (c997b0e), including moving UniqueKeyIndex (4a17205), LeftRightRange (e565f0e), and Hierarchy (now AdjacencyList) to the Utilities schema (17b98b4), and removal of legacy SimpleIntListToTbl and Split functions (f0e781b).
  • Applied updates based on new code analysis warnings (b00cfad)

Potentially Breaking Changes

  • Moving, renaming, and deleting of utility objects in SQL database schema (c997b0e)
  • Setting default for ITopicRepositoryBase.Delete()'s isRecursive parameter from false to true to maintain backward compatibility (1773113)

Note: These aren't expected to break any actual implementations. In particular, utility objects are not referenced from the products, and most weren't previously documented, so it's not expected that they would have been integrated with or called from third-party implementations. Similarly, while the change to ITopicRepositoryBase.Delete() changes the default, it does so to avoid a behavioral change.

v4.4.0

21 Aug 20:23
Compare
Choose a tag to compare

This update primarily focuses on introducing new extension methods for registering topic areas (66c53c9). In addition, it also shores up the implementation of Oroborus Configuration, helping ensure that updates to ContentTypeDescriptor and AttributeDescriptor instances are reflected immediately in e.g. the OnTopic Editor. These were caused by version conflicts introduced by multiple in-memory instances of the same topic entities stored in e.g., TopicRepositoryBase._contentTypeDescriptors and CachedTopicRepository._cache (85216c4). Finally, this separates out the verbose sitemap into an Extended() action—which includes all relationships and attribute metadata; the default Index() now outputs a shorter form sitemap, based on the data most search agents utilize (86df229).

Features

  • Introduced a series of extension methods for configuring topic areas—including MapTopicAreaRoute(), MapDefaultAreaControllerRoute(), and MapImplicitAreaControllerRoute() (66c53c9)
  • Introduced a new Extended() action on SitemapController to display extended metadata, while setting the default Index() action to display a standard—and much smaller—sitemap (86df229)
  • Containers are used to organize topics, but aren't intended to be displayed to users. They are now hidden from the Sitemap (87b6d1b) and will return a 403 Unauthorized if accessed (e4130cf)

Improvements

  • Significantly improved real-time updates of Oroborus Configuration via OnTopic by introducing code to centralize references of GetContentTypeDescriptors() in order to avoid version conflicts with e.g. CachedTopicRepository (85216c4)
  • Extended the search criteria for mapping routing variables to topic paths in order to support implicit controllers (74a8a76)
  • Implementing .NET Core 3.x's {**path} catch-all route handling for the path variable, ensuring it is not encoded (30c6691)

Maintenance

  • Updated development and build dependencies in NuGet (21a9ad7)

v4.3.0

30 May 20:42
Compare
Choose a tag to compare

This update provides backend functionality and bug fixes to improve performance and reliability, with a particular emphasis on importing and saving large topic graphs. The OnTopic library can now connect to empty databases, and persist in-memory topic graphs to them. To do this, it dynamically identifies content type and attribute descriptors from that topic graph. Further, when recursively saving topic graphs, there are significant performance improvements—while simultaneously fixing bugs that can occur when there are mismatches between the configuration of the saved and in-memory schemas.

Functionality

  • ContentTypeDescriptors (a9ea634) and AttributeDescriptors (b0c5a5e) are now updated dynamically when saved, and thus configuration changes are now available immediately without requiring an application restart (fb3366e).
  • The byline (LastModifiedBy) and dateline (LastModified) are now only persisted to the underlying topic repository if any other attributes (d8d41b7) or relationships (8caa148) have changed (d8d41b7).
  • Arbitrary attributes (i.e., attributes not defined in the ContentTypeDescriptor) can now be programmatically added (c3c01ef), modified, or deleted (2151a08) via the OnTopic Library (8b7dffe).
  • Empty databases can now be connected to without throwing exceptions, thus allowing a reference schema can be Import()ed via the OnTopic Data Transfer library using the OnTopic Editor (695664d).
  • TopicRepository.Save() will now loop back and save any topics with previously unresolved (i.e., unsaved) references (including relationships or DerivedTopic) (913b68d).
  • UpdateRelationships now synchronizes relationships, instead of just inserting them. It accepts an optional @DeleteUnmatched argument which can be disabled to append new relationships, instead of also deleting unmatched relationships (cbba817).

Bug Fixes

  • Fixed a bug where topics from the previous relationship were saved to each subsequent relationship for a topic (27d9bfe).
  • Fixed a bug where attributes that had been reconfigured away from IsIndexedAttribute, but not otherwise changed, would be orphaned (7a61005) deleted (d64d242) on Save().
  • Fixed a bug where an off-target exception would be thrown if SqlTopicRepository.Load(string topicKey) wasn't able to identify a matching topic (c97dcb3).
  • Fixed a bug where unsaved relationships (6da3fa4) and derived topics (a3b6da1) were saving -1 to the database if they referenced unsaved topics.

Code Changes

Performance

  • Reduced execution time of UpdateTopic by 50% through optimization of queries (fae0e8d).
  • SqlTopicRepository.Save() will only save topics which have actually changed; this greatly increases the performance of recursive saves when merging large topic graphs (afa1e9b).

API Changes

  • Introduced AttributeValuesDataTable (313fe71) and TopicListDataTable (7a37dc9) to encapsulate the corresponding user-defined, table-valued types in SQL, and extended SqlCommand.AddParameter() to support them (0cd2506).
  • Introduced TopicNotFoundException (2300e69), which derives from TopicRepositoryException and is used in ITopicRepository.Load().
  • Introduced TopicRepositoryBase.GetContentTypeDescriptor() convenience method (408d01a) for loading a ContentTypeDescriptor—either from the database, or from the local topic graph.
  • Introduced TopicRepositoryBase.GetAttributes() method for retrieving extended or indexed attributes, optionally filtered by IsDirty (120c55e).
  • Introduced Topic.GetTopicByUniqueKey() (867b110) and Topic.GetRootTopic() (0bddfb0) extension methods to OnTopic.Queryable namespace (d18984d).
  • Introduced Topic.IsNew property for tracking whether a topic is new, or if it has been persisted to the database (1678523, f046179).
  • Introduced a NamedTopicCollection.IsDirty property (4762694), RelatedTopicCollection.IsDirty() (2adef58), and AttributeValueCollection.IsDirty() (d3b49ff) for tracking if any relationships or attributes have changed (afa1e9b).
  • Removed legacy SqlTopicRepository.CreateRelationshipsXml() private helper function, as that functionality is no longer used (7bea7d3).

General

  • Migrated to C# 8.0's new block-level using statement, in favor of placing explicit Dispose() calls in finally blocks (f85aab2)
  • Migrated to GitVersion's ContinuousDeployment mode for all branches except master to simplify version incrementing on feature branches (b4105f3).

Maintenance

v4.2.0

18 Apr 22:19
Compare
Choose a tag to compare

The 4.2.0 release includes backend refactoring, new maintenance scripts for database administrators, a bug fix for versioning, and some new deprecation warnings in anticipation of future updates.

New Features

Database Scripts

  • Moved maintenance-oriented stored procedures to a new [Utilities] schema (402301f).
  • Officially documented maintenance-oriented stored procedures (2df59ad).
  • Introduced new stored procedures for reducing extraneous records and old versions stored in the SQL database:
    • DeleteConsecutiveAttributes
    • DeleteConsecutiveExtendedAttributes
    • ConsolidateVersion
    • DeleteOrphanedLastModifiedAttributes

Note: With the exception of ConsolidateVersions, these new procedures are "lossless", meaning they compress the data without losing any historical versioning information.

Code Changes

OnTopic.Data.Sql

  • Much of the topic loading code was moved to the new SqlReaderExtensions (7ca6c0e).
  • Helper methods for creating parameters have been moved to a set of extension methods in the new SqlCommandExtensions class (7ca6c0e).

Note: These changes don't have any impact on the public API; they just makes the code itself more maintainable and easier to read.

Deprecation Notices

While OnTopic 5.0 hasn't been planned out yet, we have identified a few parts of the public API which will be deprecated. In anticipation of that, deprecation warnings have been implemented on those classes and members (b49ce5e). Most of these aren't being used by any implementors, and shouldn't cause problems. These include:

  • All ITopicRepository events, such as DeleteEvent, RenameEvent, and MoveEvent
  • A couple of Topic convenience accessors for retrieving attributes, including View and Description
  • Members of classes such as some helpers in SitemapController which should have been marked as private when they were introduced

Bug Fixes

  • Topic versions are now created using a lower precision so that they match the exact value in the database (90c83d4). This fixes a bug which prevented rolling back to versions created since the last application reset.

v4.1.1

18 Apr 22:04
Compare
Choose a tag to compare

Resolves a bug with [MapToParent] support in the ReverseTopicMappingService (6616794). Previously, this would fail validation as the AttributePrefix wasn't being properly relayed to the BindingModelValidator.

v4.1.0

18 Apr 21:56
Compare
Choose a tag to compare

The 4.1.0 release introduces bug fixes for the SitemapController, transaction support for certain database operations, unified support between TopicMappingService and ReverseTopicMappingService, as well as an update to how AttributeValue objects are created in order to supports merging topics.

New Features

  • The SitemapController now compresses the XML output by default (6a5f671). This can optionally be disabled by calling it with ?Indent=true.
  • The SqlTopicRepository now retrieves the precise Version for each attribute, and sets that value to the AttributeValue object (a83b844). This enables support for merging topics based on timestamp as part of the new OnTopic-Data-Transfer library.
  • The TopicMappingService now supports new attributes originally introduced for ReverseTopicMappingService (8e56be8). Notably, this includes support for [MapToParent] and [DisableMapping]. Critically, [MapToParent] allows attributes from a topic to be mapped to complex object types used for view model properties..
  • The MoveTopic and DeleteTopic stored procedures now implement table locks and transactions to prevent potential database corruption issues during concurrent updates (a16ea48). While a rare scenario, the potential consequences are sever.
  • The database project now includes a new ValidateHierarchy stored procedure (a16ea48), which allows the nested set hierarchy to be validated to ensure that no corruption has taken place.

Bug Fixes

  • The SitemapController now renders the output as UTF-8 not the default of UTF-16 (32e8289). This maintains compatibility with the Sitemap.org specification which mandates UTF-8.

Maintenance

  • Most NuGet package dependencies have either been removed or marked as <PrivateAssets /> (87b3034). This reduces the number of dependencies carried forward to downstream consumers.