thenerdery / umbracovault Goto Github PK
View Code? Open in Web Editor NEWAn easy-to-use, extensible ORM to quickly and easily convert Umbraco documents to C# objects
License: Apache License 2.0
An easy-to-use, extensible ORM to quickly and easily convert Umbraco documents to C# objects
License: Apache License 2.0
Vault.Context.GetAncestors<BaseDocumentViewModel>()
Vault.Context.GetChildren<BaseDocumentViewModel>()
Vault.Context.GetDescendents<BaseDocumentViewModel>()
If you want to get a bunch of documents that inherit from the same document type and share the same base properties.
Is it possible map these objects
[UmbracoEntity(AutoMap = true)]
public class Master
{
public M4_1 M4_1 { get; set; } //composition type
}
[UmbracoEntity(AutoMap = true)]
public class M4_1
{
public string Home_M4_Title { get; set; }
}
When I look at my object master m4 is null. If I directly add home_m4_title to master's class it fills it without a problem.
Did I miss something?
@technicallyerik reported this issue:
Hey Guys.
I did a minor refactor to one of my Umbraco Vault applications, and it randomly stops.. "vaulting" after using the website for a little bit.
"The model item passed into the dictionary is of type 'Umbraco.Web.Models.RenderModel', but this dictionary requires a model item of type '<My Page's Specific View Model>'"
It slowly happens one template at a time, but then that template is broken forever until I restart the app pool.
I can't reproduce this corruption consistently. I backed out most of my refactoring I did and it was still happening.
Pulling my hair out. Anything obvious I'm missing before I start digging through every line of Umbraco vault?
If I have a class with properties derived from an interface, those properties are not automapped.
public Interface INavItem
{
string Name { get; set; }
}
[UmbracoEntity(Automap = true)]
public class BrokenViewModel : INavItem
{
public string Name { get; set; }
}
[UmbracoEntity(Automap = true)]
public class WorkingViewModel : INavItem
{
public string Name { get; set; }
string INavItem.Name
{
get { return Name; }
set { Name = value; }
}
}
Doing Vault.Context.GetContentById<BrokenViewModel>(id)
will result in Name being null, but Vault.Context.GetContentById<WorkingViewModel>(id)
will fix it. Properties not defined in the interface still work as expected.
On multi-site instances you might want to get all documents by type, within the site you are currently in. We ended up writing an extension method like this. Worth adding into the core code?
/// <summary>
/// Gets all documents of type T within the current internationalized site
/// </summary>
/// <param name="context">Umbraco context</param>
public static IEnumerable<T> GetByDocumentTypeWithinSite<T>(this IUmbracoContext context)
{
int rootNode = ResolveRootNodeId(context);
// Get all documents under the home node with the specified document type
// Document paths in the Umbraco cache are defined as "-1,<root node>,..."
var documents = Vault.Context.QueryRelative<T>(
XpathHelper.GetXpathForDocumentTypeUnderHomeNode(GetUmbracoEntityAliasFromType(typeof(T)), rootNode));
return documents;
}
/// <summary>
/// Gets the Xpath query for a document type underneith a home node id
/// </summary>
/// <param name="documentTypeId">The document type</param>
/// <param name="homeNodeId">The home node id</param>
public static string GetXpathForDocumentTypeUnderHomeNode(string documentTypeId, int homeNodeId)
{
return string.Format("//{0}[starts-with(@path, '-1,{1},')]", documentTypeId, homeNodeId);
}
Content editors can not enter a date in a date picker, so we should support that.
/// <summary>
/// Handles nullable date picker
/// </summary>
public class DateTypeHandler : ITypeHandler
{
/// <summary>
/// Gets value as a nullable date picker
/// </summary>
/// <param name="input">Input to convert to date</param>
public object GetAsType<T>(object input)
{
DateTime result;
var value = input.ToString();
if (!DateTime.TryParse(value, out result))
{
return null;
}
return result == DateTime.MinValue ? (DateTime?)null : result;
}
/// <summary>
/// Type supported
/// </summary>
public Type TypeSupported
{
get { return typeof(DateTime?); }
}
}
I upgraded Vault from Alpha 1 to Build 43 and get this error:
Type 'Castle.Proxies.BaseViewModelProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is attempting to implement an inaccessible interface.
at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type) at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() at System.Reflection.Emit.TypeBuilder.CreateType() at
Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateType(TypeBuilder type) at
Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType() at
Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope) at
Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory) at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors) at UmbracoVault.Proxy.ProxyInstanceFactory.BuildProxy[T](IPublishedContent node) at UmbracoVault.Proxy.ProxyInstanceFactory.CreateInstance[T](IPublishedContent content) at UmbracoVault.ClassConstructor.CreateWithNode[T](IPublishedContent content) at UmbracoVault.UmbracoWebContext.GetItem[T](IPublishedContent n) at
UmbracoVault.UmbracoWebContext.GetContentById[T](Int32 id)
I tried copying the database from the Umbraco 6 site, but it threw a bunch of exceptions. I assume its not compatible.
Are you using a different database for the 7 reference site? Could you commit it?
Thanks!
With lazy loading enabled, accessing a virtual property annotated with [UmbracoProperty(Recursive = true)] or [UmbracoDataTypeGridProperty(Recursive = true)] when no value is set in the cms throws following exception
[NullReferenceException: Object reference not set to an instance of an object.]
UmbracoVault.Proxy.ProxyInterceptor.PropertyIsOptedIn(PropertyInfo property) +46
UmbracoVault.Proxy.ProxyInterceptor.ShouldInterceptMethod(IInvocation invocation, PropertyInfo& property) +102
UmbracoVault.Proxy.ProxyInterceptor.Intercept(IInvocation invocation) +39
Castle.DynamicProxy.AbstractInvocation.Proceed() +447
Castle.Proxies.ContactViewModelProxy.get_InquiryPurposeOptions() +166
Add a generic type handler to handle any custom Umbraco control that stores JSON data.
/// <summary>
/// Umbraco Vault Type handler for any custom json made data types
/// </summary>
/// <typeparam name="T">Model of custom data type</typeparam>
public class JsonDataTypeHandler<T> : ITypeHandler where T : class, new()
{
/// <summary>
/// Retrieves the property
/// </summary>
/// <typeparam name="T">Not used</typeparam>
/// <param name="input">Value to be retrieved as model</param>
/// <returns></returns>
public object GetAsType<T>(object input)
{
return Get(input);
}
/// <summary>
/// The type supported by the handler
/// </summary>
public Type TypeSupported
{
get { return typeof(T); }
}
/// <summary>
/// Converts the data as a given tyoe
/// </summary>
/// <param name="data">Data to be converted</param>
/// <returns></returns>
private static T Get(object data)
{
try
{
return data as T ?? JsonConvert.DeserializeObject<T>(data.ToString()) ?? new T();
}
catch
{
return new T();
}
}
}
Usage:
UmbracoVault.TypeHandlers.TypeHandlerFactory.Instance.RegisterTypeHandler<CustomDataTypeHandler<MyCustomClass>>();
where MyCustomClass is [Serializable]
If the members of a list property that maps to a uComponents datatype grid contain virtual members the list property will be null instead of getting mapped.
Views break when in preview mode even though valid content is entered.
Currently when an inheritance model is used, behavior within Vault is undefined. For example, for the Castle factory, this test currently passes
public class InnerClassNoAttributeExtendsBaseClassAutoMap : BaseClassWithAutoMap
{
[UmbracoProperty]
public string Introduction { get; set; }
[UmbracoProperty]
public string Body { get; set; }
[UmbracoProperty]
public string ImageUrl { get; set; }
[UmbracoProperty]
public virtual string ButtonText { get; set; }
[UmbracoIgnoreProperty]
public string Ignore1 { get; set; }
public virtual string Ignore2 { get; set; }
}
[UmbracoEntity(AutoMap = true)]
public class BaseClassWithAutoMap
{
public string BaseProperty { get; set; }
[UmbracoIgnoreProperty]
public string BaseIgnore { get; set; }
public virtual string BaseVirtual { get; set; }
}
[TestMethod]
public void GetPropertiesToFill_For_InnerClassNoAttributeExtendsBaseClassAutoMap_ShouldReturnCorrectProperties_WithoutAutomap()
{
var properties = _factory.GetPropertiesToFill<InnerClassNoAttributeExtendsBaseClassAutoMap>();
Assert.AreEqual(4, properties.Count);
Assert.IsNotNull(properties.FirstOrDefault(p => p.Name == "Introduction"));
Assert.IsNotNull(properties.FirstOrDefault(p => p.Name == "Body"));
Assert.IsNotNull(properties.FirstOrDefault(p => p.Name == "ImageUrl"));
Assert.IsNotNull(properties.FirstOrDefault(p => p.Name == "BaseProperty"));
}
and for the default factory, this currently is a passing test:
public class InnerClassNoAttributeExtendsBaseClass : BaseClass
{
public string Introduction { get; set; }
public string Body { get; set; }
public string ImageUrl { get; set; }
public virtual string ButtonText { get; set; }
public string Ignore1 { get; set; }
public virtual string Ignore2 { get; set; }
}
[UmbracoEntity] // AutoMap = False
public class BaseClass
{
[UmbracoProperty]
public string BaseProperty { get; set; }
public string BaseIgnore { get; set; }
[UmbracoProperty]
public virtual string BaseVirtual { get; set; }
}
[TestMethod]
public void GetPropertiesToFill_For_InnerClassNoAttributeExtendsBaseClass_ShouldReturnCorrectProperties_WithoutAutomap()
{
var properties = _factory.GetPropertiesToFill<InnerClassNoAttributeExtendsBaseClass>();
Assert.AreEqual(2, properties.Count);
Assert.IsNotNull(properties.FirstOrDefault(p => p.Name == "BaseProperty"));
Assert.IsNotNull(properties.FirstOrDefault(p => p.Name == "BaseVirtual"));
}
and on the proxy factory:
// TODO: Change this behavior later on, probably shouldn't work like this, but retain for now
// for backewards compatibility
[TestMethod]
public void GetPropertiesToFill_For_InnerClassNoAttributeExtendsBaseClass_ShouldReturnCorrectProperties_WithoutAutomap()
{
var properties = _factory.GetPropertiesToFill<InnerClassNoAttributeExtendsBaseClass>();
Assert.AreEqual(1, properties.Count);
Assert.IsNotNull(properties.FirstOrDefault(p => p.Name == "BaseProperty"));
}
Occasionally I get this error in application startup:
System.IO.FileNotFoundException: Could not load file or assembly 'log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a' or one of its dependencies. The system cannot find the file specified.
File name: 'log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a'
at System.ModuleHandle.ResolveType(RuntimeModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type)
at System.ModuleHandle.ResolveTypeHandleInternal(RuntimeModule module, Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, Assembly& lastAptcaOkAssembly, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, Object[] attributes, IList derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctor, Boolean& ctorHasParameters, Boolean& isVarArg)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType)
at UmbracoVault.TypeHandlers.TypeHandlerFactory.<GetExternalTypeHandlers>b__0(Assembly x)
at System.Linq.Enumerable.WhereArrayIterator`1.MoveNext()
at UmbracoVault.TypeHandlers.TypeHandlerFactory.GetExternalTypeHandlers()
at UmbracoVault.TypeHandlers.TypeHandlerFactory..ctor()
at UmbracoVault.TypeHandlers.TypeHandlerFactory.get_Instance()
at Baker.MvcApplication.RegisterUmbracoVault() in c:\Jenkins\sharedspace\BakerSharedWorkspace\Baker\Global.asax.cs:line 203
at Baker.MvcApplication.OnApplicationStarting(Object sender, EventArgs e) in c:\Jenkins\sharedspace\BakerSharedWorkspace\Baker\Global.asax.cs:line 62
at Umbraco.Core.CoreBootManager.Startup(Action`1 afterStartup)
at Umbraco.Core.UmbracoApplicationBase.StartApplication(Object sender, EventArgs e)
I'm using Umbraco 6.2.5 and Vault 1.1.1, and walked through my entire dependency tree and haven't the faintest idea what references log4net 1.2.13 (everything in my solution is 1.2.11).
Any thoughts?
Like Entity Framework have vault return proxy classes wrapping POCO models. This would enable the following:
The first item, lazy mapping, is the primary objective. On some projects with tight performance requirements we've found ourselves creating smaller POCOs to reduce mapping overhead in hot spots. Lazy mapping would mean only what is actually used is mapped and would eliminate the need for specialized models. Thinking underlying implementation would use Lazy{T} and do whatever Vault is currently doing now.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.