ProNotion
08/15/2023, 2:08 PMPublishedContentModel
. In my abstract class I need to access the ModelTypeAlias
property but can't since it is not defined anywhere in the PublishedContentModel
hierarchy of classes, only directly on the generated class.
What is the best way of tackling this? It would have been good if the models perhaps implemented an interface that defined the available properties that are included on every generated class.Ambert
08/15/2023, 2:57 PMMyPublishedModel.GetModelPropertyType(_publishedSnapshotAccessor, x => x.CustomTitle)?.Alias);
ProNotion
08/15/2023, 3:12 PMpublic abstract class BaseDoctypeApiController<T> : ContentApiItemControllerBase where T : PublishedContentModel
I am then trying to get the ContentType as follows:
var publishedContentItems =
publishedSnapshot.Content.GetByContentType(T.GetModelContentType(_publishedSnapshotAccessor)).Select(x => x.Key);
But this is where I am coming unstuck because T.GetModelContentType
cannot be resolved by the compiler.Anders Bjerner
08/15/2023, 3:18 PMcsharp
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Umbraco.Cms.Core.Models.PublishedContent;
namespace code.Packages.ModelsBuilder {
public static class ModelsBuilderUtils {
public static bool TryGetModelTypeAlias<TModel>([NotNullWhen(true)] out string? result) where TModel : PublishedContentModel {
// Get a reference to the "ModelTypeAlias" field via reflection
var field = typeof(TModel)
.GetField("ModelTypeAlias", BindingFlags.Public | BindingFlags.Static);
// Get the value of the field
result = field?
.GetValue(null) as string;
// Method is successful if "result" is not null
return result is not null;
}
}
}
ProNotion
08/15/2023, 3:20 PMAnders Bjerner
08/15/2023, 3:25 PMPublishedContentModel
.
I guess it makes sense to add this to Umbraco, but for now you have to do this on your own. I'm maintaining my own version of Models Builder that has some extended features, so I might look into adding something there, as having a shared type declaring these fields and methods does make good sense.
https://marketplace.umbraco.com/package/limbo.umbraco.modelsbuilderProNotion
08/15/2023, 3:27 PMAnders Bjerner
08/15/2023, 3:29 PMModelTypeAlias
was a property. But it's a field/constant, so not sure they can be declared in an interface and then classes implementing the interface would have to implement it as well.ProNotion
08/15/2023, 3:31 PMT.GetModelContentType(_publishedSnapshotAccessor)
so you have given me some new avenues to explore, thank you.Anders Bjerner
08/15/2023, 3:40 PMGetModelPropertyType
, as it's a method, you can create an interface like this (I think - I haven't tested it yet):
csharp
public interface IPublishedContentModel<TModel> {
[return: global::System.Diagnostics.CodeAnalysis.MaybeNull]
static abstract IPublishedPropertyType GetModelPropertyType<TValue>(IPublishedSnapshotAccessor publishedSnapshotAccessor, Expression<Func<TModel, TValue>> selector);
}
ProNotion
08/15/2023, 4:01 PMAnders Bjerner
08/15/2023, 4:12 PMProNotion
08/15/2023, 4:15 PMProNotion
08/16/2023, 10:33 AMMyModel.ModelTypeAlias
then in the base controller I can get the content type using
var contentType = publishedSnapshot.Content.GetContentType(_contentTypeAlias);
var publishedContentItems = publishedSnapshot.Content.GetByContentType(contentType);
It would have been preferred to do it like this:
public class MyApiController : BaseDoctypeApiController<MyModel>
...but time is not on my side at the moment so will try and come back to it later on.A hub and casual space for you to interact with fellow community members and learn more about Umbraco!
Powered by