Developer forum

Forum » Templates » 'ProductGroupRelation' does not contain a definition for 'GetProductGroupRelations' - Easycatalog

'ProductGroupRelation' does not contain a definition for 'GetProductGroupRelations' - Easycatalog

Davy Capiau
Reply

Hi,

DW10

I'm having issues with this file which generates an XML-feed for Easy Catalog. I get the following errors and can't get them properly fixed:

Line 145: 'Uri.EscapeUriString(string)' is obsolete: 'Uri.EscapeUriString can corrupt the Uri string in some cases. Consider using Uri.EscapeDataString for query string components instead.'
Line 175: 'ProductGroupRelation' does not contain a definition for 'GetProductGroupRelations'

This is the original code:

@using Dynamicweb.Rendering;
@using Dynamicweb.Ecommerce.ProductCatalog;
@using Dynamicweb.Environment;
@using Newtonsoft.Json;
@using System.Xml.Linq;
@inherits ViewModelTemplate<ProductListViewModel>
@functions
{
    public enum FieldType
    {
        System,
        Standard,
        Custom,
        CategoryField
    };
 
    public class Field
    {
        public string ID { get; set; }
        public FieldType FieldType { get; set; }
        public string Label { get; set; }
        public string Prefix { get; set; }
        public bool IsRTE { get; set; }
 
        public Field(string id, string label, string prefix, FieldType type, bool isRTE)
        {
            ID = id;
            Label = label;
            FieldType = type;
            Prefix = prefix;
            IsRTE = isRTE;
        }
    }
 
    private class Utf8StringWriter : System.IO.StringWriter
    {
        public override System.Text.Encoding Encoding { get { return System.Text.Encoding.UTF8; } }
    }
 
    public string GenerateXML()
    {
        var fields = GetFields();
 
        XDocument xdoc = new XDocument();
        xdoc.Declaration = new XDeclaration("1.0", "utf-8", null);
 
        var rootElement = new XElement("Root");
        var productsElement = new XElement("Products");
 
        foreach (ProductViewModel product in Model.Products)
        {
            ProcessProductXml(productsElement, fields, product);
        }
 
        rootElement.Add(productsElement);
        xdoc.Add(rootElement);
 
        var wr = new Utf8StringWriter();
        xdoc.Save(wr);
        return wr.ToString();
    }
 
    public List<Field> GetFields()
    {
        var fields = new List<Field>();
 
        fields.Add(new Field("Id", "Id", "s", FieldType.Standard, false));
        fields.Add(new Field("VariantId", "Variant id", "s", FieldType.Standard, false));
        fields.Add(new Field("LanguageId", "Language id", "s", FieldType.Standard, false));
        fields.Add(new Field("Name", "Name", "v", FieldType.Standard, false));
        fields.Add(new Field("Number", "Number", "v", FieldType.Standard, false));
        fields.Add(new Field("ShortDescription", "Short description", "v", FieldType.Standard, true));
        fields.Add(new Field("LongDescription", "Long description", "v", FieldType.Standard, true));
        fields.Add(new Field("Price", "Price", "v", FieldType.Standard, false));
        fields.Add(new Field("Created", "Created", "s", FieldType.System, false));
 
        fields.Add(new Field("DefaultImage", "DefaultImage", "a", FieldType.Standard, false));
        fields.Add(new Field("DefaultStockUnit", "DefaultStockUnit", "v", FieldType.Standard, false));
        fields.Add(new Field("Discount", "Discount", "v", FieldType.Standard, false));
        fields.Add(new Field("ImagePatternImages", "ImagePatternImages", "a", FieldType.Standard, false));
        fields.Add(new Field("Images", "Images", "a", FieldType.Standard, false));
        fields.Add(new Field("Keywords", "Keywords", "v", FieldType.Standard, false));
        fields.Add(new Field("Manufacturer", "Manufacturer", "v", FieldType.Standard, false));
        fields.Add(new Field("PriceBeforeDiscount", "PriceBeforeDiscount", "v", FieldType.Standard, false));
        fields.Add(new Field("RelatedGroups", "RelatedGroups", "v", FieldType.Standard, false));
        fields.Add(new Field("Rewards", "Rewards", "v", FieldType.Standard, false));
        fields.Add(new Field("StockLevel", "StockLevel", "v", FieldType.Standard, false));
        fields.Add(new Field("StockUnits", "StockUnits", "v", FieldType.Standard, false));
        fields.Add(new Field("Updated", "Updated", "s", FieldType.Standard, false));
        fields.Add(new Field("Variants", "Variants", "v", FieldType.Standard, false));
        fields.Add(new Field("Weight", "Weight", "v", FieldType.Standard, false));
 
        return fields;
    }
 
    private void ProcessProductXml(XElement rootElement, IEnumerable<Field> fields, ProductViewModel product)
    {
        var productElement = new XElement("Product");
 
        foreach (var field in fields)
        {
            if (field.FieldType == FieldType.System)
            {
            }
            else if (field.FieldType == FieldType.Standard)
            {
                if (field.ID == "Price")
                {
                    foreach (var priceProp in product.Price.GetType().GetProperties())
                    {
                        productElement.Add(createElement(priceProp.Name, "v", Dynamicweb.Core.Converter.ToString(priceProp.GetValue(product.Price)), false));
                    }
                }
                else
                {
                    var value = getValue(field, product);
 
                    if (value != null)
                    {
                        if(value is Dynamicweb.Ecommerce.ProductCatalog.MediaViewModel)
                        {
                            var castedValue = value as Dynamicweb.Ecommerce.ProductCatalog.MediaViewModel;
                            var imageRelativePath = castedValue.Value;
                            if(imageRelativePath.StartsWith("/Files/Files/"))
                            {
                                imageRelativePath = imageRelativePath.Replace("/Files/Files/", "/Files/");
                            }
 
                            imageRelativePath = System.Uri.EscapeUriString(imageRelativePath);
                           
                            value = string.Format("{0}://{1}{2}", Dynamicweb.Context.Current.Request.Url.Scheme, Dynamicweb.Context.Current.Request.Url.Host, imageRelativePath);
                        }
 
                        productElement.Add(createElement(field.ID, field.Prefix, value, field.IsRTE));
                    }
                }
            }
        }
 
        if (product.ProductFields != null && product.ProductFields.Any())
        {
            foreach (var field in product.ProductFields)
            {
                CreateLabelValueSection(productElement, null, field.Value);
            }
        }
 
        if (product.ProductCategories != null && product.ProductCategories.Any())
        {
            foreach (var category in product.ProductCategories)
            {
                foreach (var field in category.Value.Fields)
                {
                    CreateLabelValueSection(productElement, category.Key, field.Value);
                }
            }
        }
 
        var relations = Dynamicweb.Ecommerce.Products.ProductGroupRelation.GetProductGroupRelations(product.Id);
        foreach (var group in relations.GroupCollection.Where(g => g.ShopId == Dynamicweb.Context.Current.Request.GetString("Shopid")))
        {
            productElement.Add(createElement("Group", string.Empty, group.Name, false));
            var parentGroup = group.ParentGroups.FirstOrDefault();
            if (parentGroup != null)
            {
                productElement.Add(createElement("MainGroup", string.Empty, parentGroup.Name, false));
            }
        }
 
        rootElement.Add(productElement);
    }
 
    private string ReplaceFirst(string text, string search, string replace)
    {
        int pos = text.IndexOf(search);
        if (pos < 0)
        {
            return text;
        }
        return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
    }
 
    private void CreateLabelValueSection(XElement section, string categoryId, FieldValueViewModel field)
    {
        var value = "";
        if (field.Value != null && field.Value is List<FieldOptionValueViewModel>)
        {
            var options = (List<FieldOptionValueViewModel>)field.Value;
            value = string.Join(",", options.Select(x => x.Value));
        }
        else
        {
            value = Dynamicweb.Core.Converter.ToString(field.Value);
        }
        //Values
        //AE 20190309: Special case for images
        if (field.SystemName == "ProductImagePath")
        {
            value = ReplaceFirst(value, "\\", ":");
        }
 
        var fieldId = field.SystemName;
        if(!string.IsNullOrEmpty(categoryId))
        {
            fieldId = string.Format("{0}_{1}", categoryId, field.SystemName);
        }
        section.Add(createElement(fieldId, "v", value, false));
    }
 
    private object getValue(Field field, ProductViewModel product)
    {
        var value = product.GetType().GetProperty(field.ID)?.GetValue(product, null);
        return value;
    }
 
    public XElement createElement(string fieldId, string prefix, object value, bool wrapInCdata)
    {
        var valueElement = new XElement(string.Format("{0}_{1}", prefix, fieldId));
        valueElement.Value = Dynamicweb.Core.Converter.ToString(value);
 
        if(wrapInCdata)
        {
            valueElement.ReplaceNodes(new XCData(Dynamicweb.Core.Converter.ToString(value)));
        }
 
        return valueElement;
    }
    }
@GenerateXML()

Replies

 
Morten Bengtson Dynamicweb Employee
Morten Bengtson
Reply

When upgrading a solution with custom code from DW9 to DW10 it is recommended that you upgrade to latest DW9 first.
Then you can check if there are any build warnings in your custom code about use of obsolete functionality.
Often, it will contain a message about what you can use instead.

In this particular case you are calling a method on ProductGroupRelation which was obsoleted in DW9 and then removed in DW10.

You need to change this line:
var relations = Dynamicweb.Ecommerce.Products.ProductGroupRelation.GetProductGroupRelations(product.Id);

Into this:
var relations = Dynamicweb.Ecommerce.Services.ProductGroups.GetProductGroupRelations(product.Id);

 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

There is a complete article on migrating from Dynamicweb 9 to Dynamicweb 10 here: https://doc.dynamicweb.dev/documentation/fundamentals/dw10release/upgradingfromDW9.html

 
Davy Capiau
Reply
This post has been marked as an answer

Fyi my template that works attached

Votes for this answer: 1
 
Nicolai Pedersen Dynamicweb Employee
Nicolai Pedersen
Reply

Hi Davy

Thanks for sharing!

BR Nicolai

 

You must be logged in to post in the forum