本文介绍了如何为SitecoreQuery和SitecoreChildren属性在Sitecore中为Glass Mapper启用VersionCountDisabler的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

glass映射器将为放置在GlassModels上的SitecoreQuery和SitecoreChildren属性返回空对象或(无项目).这些属性没有任何这样的参数,如果上下文语言中不存在这些属性,我可以在其中指定它们以返回项目.物品例如在EN中存在,但在en-ES中不存在.我需要在视图中进行很多null检查,以避免Null异常并使视图或控制器非常混乱.要使它工作,必须编写许多样板代码.在页面编辑器中,SitecoreChildren返回项目,内容作者可以通过编辑项目的任何字段来创建该语言版本的项目.这将自动在该语言中创建项目.但是,相同的代码将在预览"模式下失败,因为SitecoreChidren将返回null,并且您会看到null指针异常.SitecoreQuery在页面编辑器中不返回任何项目,然后内容作者将无法在页面编辑器中创建项目.为了使体验更好,我们可以将参数传递给SiteocreQuery属性,以便禁用VsersionCount并返回该语言中不存在的项目.

The glass mapper will return null object or (no items) for SitecoreQuery and SitecoreChildren attribute that are placed on the GlassModels. These attributes don't take any such parameter where I can specify them to return items if they don't exist in the the context lanaguge. The items e.g. exist in EN but don't exist in en-ES. I need to put a lot of null check in my views to avoid Null exception and makes the views or controller very messy. It is lot of boiler plate code that one has to write to make it work.In Page Editor the SitecoreChildren returns item and content authors can create items in that langauge version by editing any field on the item. This automatically creates the item in that langauge. However the same code will fail in Preview mode as SitecoreChidren will return null and you see null pointer exception. SitecoreQuery doesn't return any items in page editor and then Content Authors wont be able to create items in Page editor.To make the experience good if we can pass a parameter to SiteocreQuery attribute so it disable VsersionCount and returns the items if they dont exist in that langauge.

推荐答案

实际上是不可能的.在GitHu上有一个问题 b,可以很容易地创建自定义属性处理这个非常容易.当前,您需要创建一个新的类型映射器,并复制SitecoreQueryMapper中的所有代码.我已经写了一个此处的博客文章,介绍如何创建自定义键入映射器.您需要创建以下类(SitecoreQuery的示例).

This is actually not possible. There is an issue on GitHub which would make it easy to create a custom attribute to handle this very easy. Currently you need to create a new type mapper and copy all the code from the SitecoreQueryMapper. I have written a blog post here about how you can create a custom type mapper. You need to create the following classes (example for the SitecoreQuery).

新配置:

public class SitecoreSharedQueryConfiguration : SitecoreQueryConfiguration
{
}

新属性:

public class SitecoreSharedQueryAttribute : SitecoreQueryAttribute
{
    public SitecoreSharedQueryAttribute(string query) : base(query)
    {
    }

    public override AbstractPropertyConfiguration Configure(PropertyInfo propertyInfo)
    {
        var config = new SitecoreSharedQueryConfiguration();
        this.Configure(propertyInfo, config);
        return config;
    }
}

新型映射器:

public class SitecoreSharedQueryTypeMapper : SitecoreQueryMapper
{
    public SitecoreSharedQueryTypeMapper(IEnumerable<ISitecoreQueryParameter> parameters)
        : base(parameters)
    {
    }

    public override object MapToProperty(AbstractDataMappingContext mappingContext)
    {
        var scConfig = Configuration as SitecoreQueryConfiguration;
        var scContext = mappingContext as SitecoreDataMappingContext;

        using (new VersionCountDisabler())
        {
            if (scConfig != null && scContext != null)
            {
                string query = this.ParseQuery(scConfig.Query, scContext.Item);

                if (scConfig.PropertyInfo.PropertyType.IsGenericType)
                {
                    Type outerType = Glass.Mapper.Sc.Utilities.GetGenericOuter(scConfig.PropertyInfo.PropertyType);

                    if (typeof(IEnumerable<>) == outerType)
                    {
                        Type genericType = Utilities.GetGenericArgument(scConfig.PropertyInfo.PropertyType);

                        Func<IEnumerable<Item>> getItems;
                        if (scConfig.IsRelative)
                        {
                            getItems = () =>
                                {
                                    try
                                    {
                                        return scContext.Item.Axes.SelectItems(query);
                                    }
                                    catch (Exception ex)
                                    {
                                        throw new MapperException("Failed to perform query {0}".Formatted(query), ex);
                                    }
                                };
                        }
                        else
                        {
                            getItems = () =>
                                {
                                    if (scConfig.UseQueryContext)
                                    {
                                        var conQuery = new Query(query);
                                        var queryContext = new QueryContext(scContext.Item.Database.DataManager);

                                        object obj = conQuery.Execute(queryContext);
                                        var contextArray = obj as QueryContext[];
                                        var context = obj as QueryContext;

                                        if (contextArray == null)
                                            contextArray = new[] { context };

                                        return contextArray.Select(x => scContext.Item.Database.GetItem(x.ID));
                                    }

                                    return scContext.Item.Database.SelectItems(query);
                                };
                        }

                        return Glass.Mapper.Sc.Utilities.CreateGenericType(typeof(ItemEnumerable<>), new[] { genericType }, getItems, scConfig.IsLazy, scConfig.InferType, scContext.Service);
                    }

                    throw new NotSupportedException("Generic type not supported {0}. Must be IEnumerable<>.".Formatted(outerType.FullName));
                }

                {
                    Item result;
                    if (scConfig.IsRelative)
                    {
                        result = scContext.Item.Axes.SelectSingleItem(query);
                    }
                    else
                    {
                        result = scContext.Item.Database.SelectSingleItem(query);
                    }

                    return scContext.Service.CreateType(scConfig.PropertyInfo.PropertyType, result, scConfig.IsLazy, scConfig.InferType, null);
                }
            }
        }

        return null;
    }

    public override bool CanHandle(AbstractPropertyConfiguration configuration, Context context)
    {
        return configuration is SitecoreSharedQueryConfiguration;
    }
}

并在glass配置(配置程序的映射器和参数)中配置新类型的映射器:

And configure the new type mapper in your glass config (mapper and parameters for the constructor):

container.Register(Component.For<AbstractDataMapper>().ImplementedBy<SitecoreSharedQueryTypeMapper>().LifeStyle.Transient);
container.Register(Component.For<IEnumerable<ISitecoreQueryParameter>>().ImplementedBy<List<ItemPathParameter>>().LifeStyle.Transient);
container.Register(Component.For<IEnumerable<ISitecoreQueryParameter>>().ImplementedBy<List<ItemIdParameter>>().LifeStyle.Transient);
container.Register(Component.For<IEnumerable<ISitecoreQueryParameter>>().ImplementedBy<List<ItemIdNoBracketsParameter>>().LifeStyle.Transient);
container.Register(Component.For<IEnumerable<ISitecoreQueryParameter>>().ImplementedBy<List<ItemEscapedPathParameter>>().LifeStyle.Transient);
container.Register(Component.For<IEnumerable<ISitecoreQueryParameter>>().ImplementedBy<List<ItemDateNowParameter>>().LifeStyle.Transient);

然后您只需将模型上的SitecoreQuery属性更改为SitecoreSharedQuery:

You can then simply change the SitecoreQuery attribute on your model to SitecoreSharedQuery:

[SitecoreSharedQuery("./*")]
public virtual IEnumerable<YourModel> YourItems { get; set; }

对于子级,您可以使用共享查询映射器并查询子级,也可以为新的SitecoreSharedChildren查询创建相同的类.

For the children you could either use the shared query mapper and querying the children or create the same classes for a new SitecoreSharedChildren query.

:由于缺少IEnumerable<ISitecoreQueryParameter>的绑定,因此发生了错误.

Added bindings for IEnumerable<ISitecoreQueryParameter> as they are missing and therefor it threw an error.

这篇关于如何为SitecoreQuery和SitecoreChildren属性在Sitecore中为Glass Mapper启用VersionCountDisabler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 23:55