More in this section

Forums / Developing with Sitefinity / store binary metafields

store binary metafields

8 posts, 0 answered
  1. Pierre
    Pierre avatar
    433 posts
    Registered:
    16 Feb 2006
    27 Jan 2010
    Link to this post
    Hi,

    I have created one binary metafield to store some data (not image) as binary during SaveContent(). Could you explain how to pass my binary content to the current item overriding the saveMethod. 

     protected override void SaveContent()  
            {  
           
                byte[] binaryData = myby.GetBinaryFormatData(Data);  //(serialized)
                // ?  
            Guid guiditem = base.DataItemId; <-- not getting the current itemID in View  
                IContent cnt = base.Manager.GetStagedContent(guiditem);  
                cnt.SetMetaData("MetafieldID", binaryData);  
                //  
                base.SaveContent();  
            } 

    Thanks
       
  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    28 Jan 2010
    Link to this post
    Hi Pierre,

    You could try using this code

    protected override void SaveContent()
       {
           IContent cnt = null;
           Guid itemID = Guid.Empty;
           itemID = this.DataItemId;
               if (itemID == Guid.Empty)
               {
                   cnt = this.Manager.CreateContent("text/html");
                   itemID = cnt.ID;
                   foreach (IMetaInfo info in this.Manager.MetaKeys.Values)
                   {
                       bool found = false;
                       if (info.Key == "Name" || info.Key == "Title")
                       {
                           Control ctrl = GetField(info.Key, info.Mandatory);
                           ITextControl txt = ctrl as ITextControl;
                           if (txt != null)
                           {
                               cnt.SetMetaData(info.Key, txt.Text);
                           }
                           found = true;
                       }
      
                       if (found)
                           break;
                   }
      
                   // other logic here
                   MetaFields.ContentManager = this.Manager;
                   MetaFields.Content = cnt;
                   Manager.SaveContent(cnt);
               }
      
       }
     
     
             ....
                     ....
        public ContentManager secondManager;


    Sincerely yours,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  3. Pierre
    Pierre avatar
    433 posts
    Registered:
    16 Feb 2006
    28 Jan 2010
    Link to this post
    Hi Ivan,

    It's seams that have some problem storing binary items as metafields. I have tried many times using serialized items, images or simple byte date and i have always the same issue :

    Cannot cast null to byte[]. The metadata field MYFIEL(As Binary) can accept only the following data types: byte[].   
       
     
    System.InvalidCastException: Cannot cast null to byte[]. The metadata field Planing can accept only the following data types: byte[].  
     
    Error de código fuente:   
     
     
    Línea 188:            this.MetaFields.SaveContent();  
    Línea 189:            this.Host.Manager.SaveTags(stagedContent.ID, this.SelectedTags);  
    Línea 190:            this.Manager.SaveContent(stagedContent);  <========================== HERE !
    Línea 191:            HttpContext.Current.Response.Redirect(this.GetPreviewCommand(empty));  
    Línea 192:        }  
       
     

    Sample of tested codes
                        //Byte[] bytedata = SerializeDataTable(iniplan.Load_DataSet_Ini().Tables[0]);  
                        System.Drawing.Image img = System.Drawing.Image.FromFile("C:\\Temp\\SampleImage.jpg");  
                        Byte[] bytedata = imageToByteArray(img);  
                        bytedata = new byte[8];  
                        if (bytedata != null)  
                        {  
                            stagedContent.SetMetaData("MyMetafieldasBinary", new byte[8]);//in place of binaryData or img  
                            flag = true;  
                        } 

    Have you other experiences about this?, Thanks Romi
  4. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    29 Jan 2010
    Link to this post
    Hi Pierre,

    In your code you have this:
    Byte[] bytedata = imageToByteArray(img); 
    bytedata = new byte[8];


    This code is making your byte array an empty array, and you can not store it as it is empty. Can you try with something like this:
    System.Drawing.Image img = System.Drawing.Image.FromFile("C:\\Temp\\SampleImage.jpg");
    Byte[] bytedata = new Byte[];
    bytedata = imageToByteArray(img);
    if(bytedata!=null
    {
        ...
    }

    Best wishes,
    Radoslav Georgiev
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  5. Pierre
    Pierre avatar
    433 posts
    Registered:
    16 Feb 2006
    29 Jan 2010
    Link to this post
    Hi,

    II's normal. I have added as byte[8] to explain that no add anything is posible as binary Metefield. Sending data, images or a simple bity[8] as same result one error. This is the problem, no digest anything. Romi
  6. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    29 Jan 2010
    Link to this post
    Hello Pierre,

    Most probably there is something wrong with the method you are using to convert the image from image object to binary array. Consider sample code bellow. It takes an image from libraries and saves the binary data to a meta field of newly created content item. Then as a proof of concept it redraws the image in a new image object taking the byte array from meta field:
    Telerik.Cms.Engine.ContentManager contentManager = new ContentManager("Generic_Content");
    IContent newContent = contentManager.CreateContent("text/html");
    newContent.Content = "Test content with binary metafield";
    LibraryManager libraryManager = new LibraryManager();
    //get image by ID from libraries
    IContent image = libraryManager.GetContent(new Guid("23b003a8-2341-4872-8722-5ff2a48cdc87"));
    if (image != null)
    {
       //save binary conent of image from library as a metafield of generic content item
       newContent.SetMetaData("BinaryMetaField", (byte[])image.Content);
    }
    contentManager.SaveContent(newContent);
    //pull saved binary data from metafield
    byte[] binarymetafield = (byte[])newContent.GetMetaData("BinaryMetaField");
    //construct image from the binary array
    System.Drawing.Image testImage = System.Drawing.Image.FromStream(new MemoryStream(binarymetafield));

    Metafield is added like this:
    <add key="Generic_Content.BinaryMetaField" valueType="Binary" visible="false" searchable="False" sortable="True" defaultValue=""/>


    Kind regards,
    Radoslav Georgiev
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  7. Pierre
    Pierre avatar
    433 posts
    Registered:
    16 Feb 2006
    29 Jan 2010
    Link to this post
    Hi Rado,

    I have tested many times using double casting and triing images from static files or simple byte[] of data, with casting or without. I can't save but i not understand why?. I have used this override method that override complete the original adding one Metafield for my item "MyBinaryField". I use only GC Module to make, no libraries, registration of Metafield is like your sample. Any input as byte[] are NOT diggest in this SaveContent override. I have created other binary metafields changing the originals to prevent others issues or memory cache. nothing, nothing. The object of this work is store one RadGrid as binary.

    protected override void SaveContent()  
            {  
                
     
                IContent stagedContent;  
                Guid empty = Guid.Empty;  
                if (!this.IsNewItem())  
                {  
                    empty = this.DataItemId;  
                }  
                if (empty == Guid.Empty)  
                {  
                    this.DemandPermission(CrudRights.Create);  
                    stagedContent = this.Manager.CreateContent("text/html");  
                    empty = stagedContent.ID;  
                }  
                else  
                {  
                    stagedContent = this.Manager.GetStagedContent(empty);  
                    this.DemandPermission(CrudRights.Modify, stagedContent);  
                }  
                stagedContent.Content = LinkParser.UnresolveLinks(this.Editor.Text);  
                if ((this.ParentId != Guid.Empty) && this.IsNewItem())  
                {  
                    stagedContent.ParentID = this.ParentId;  
                }  
                if (this.Manager.MetaKeys.ContainsKey("Category") && (stagedContent.GetMetaData("Category") != null))  
                {  
                    this.Manager.InvalidateCategoryCountCache(stagedContent.GetMetaData("Category").ToString());  
                }  
                foreach (IMetaInfo info in this.Manager.MetaKeys.Values)  
                {  
                    bool flag = false;  
                    if ((info.Key == "Name") || (info.Key == "Title"))  
                    {  
                        ITextControl field = this.GetField(info.Key, info.Mandatory) as ITextControl;  
                        if (field != null)  
                        {  
                            stagedContent.SetMetaData(info.Key, field.Text);  
                        }  
                        flag = true;  
                    }  
                    //Added to original SaveContent method  
                    if ((info.Key == "MyBinaryField"))  
                    {  
                        System.Drawing.Image img = System.Drawing.Image.FromFile("C:\\Temp\\sampleimage.jpg");  
                        Byte[] bytedata = imageToByteArray(img);  
                        if (bytedata != null)  
                        {  
                            stagedContent.SetMetaData("Planning", (byte[])imageToByteArray(img));  
                            flag = true;  
                        }  
                    }  
                    //  
                    if (flag)  
                    {  
                        break;  
                    }  
                }  
                //**TESTED WITH OR WITHOUT THIS ZONE
                thisthis.MetaFields.ContentManager = this.Manager;  
                this.MetaFields.Content = stagedContent;  
                this.MetaFields.SaveContent();  
                this.Host.Manager.SaveTags(stagedContent.ID, this.SelectedTags);  
                //**
                this.Manager.SaveContent(stagedContent);  <========================== HERE BLOCKING
                HttpContext.Current.Response.Redirect(this.GetPreviewCommand(empty));  
            }  
        public byte[] imageToByteArray(System.Drawing.Image imageIn)  
            {  
                MemoryStream ms = new MemoryStream();  
                imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);  
                return ms.GetBuffer();//<--Like telerik in Libs  
                //return ms.ToArray();  
            }   
  8. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    29 Jan 2010
    Link to this post
    Hi Pierre,

    Thank you for getting back to me. The logic in the method is not correct. As soon the flag is set for the first time to true the foreach loop is escaped and you never go to the logic for setting the meta field. Just try setting it like this (you may have to change metafield name according to your setup):
    protected override void SaveContent()
    {
        IContent stagedContent;
        Guid empty = Guid.Empty;
        if (!this.IsNewItem())
        {
            empty = this.DataItemId;
        }
        if (empty == Guid.Empty)
        {
            this.DemandPermission(CrudRights.Create);
            stagedContent = this.Manager.CreateContent("text/html");
            empty = stagedContent.ID;
        }
        else
        {
            stagedContent = this.Manager.GetStagedContent(empty);
            this.DemandPermission(CrudRights.Modify, stagedContent);
        }
        stagedContent.Content = LinkParser.UnresolveLinks(this.Editor.Text);
        if ((this.ParentId != Guid.Empty) && this.IsNewItem())
        {
            stagedContent.ParentID = this.ParentId;
        }
        if (this.Manager.MetaKeys.ContainsKey("Category") && (stagedContent.GetMetaData("Category") != null))
        {
            this.Manager.InvalidateCategoryCountCache(stagedContent.GetMetaData("Category").ToString());
        }
        foreach (IMetaInfo info in this.Manager.MetaKeys.Values)
        {
            bool flag = false;
            if ((info.Key == "Name") || (info.Key == "Title"))
            {
                ITextControl field = this.GetField(info.Key, info.Mandatory) as ITextControl;
                if (field != null)
                {
                    stagedContent.SetMetaData(info.Key, field.Text);
                }
                flag = true;
            }
            if (flag)
            {
                break;
            }
        }
        System.Drawing.Image img = System.Drawing.Image.FromFile("C:\\Temp\\sampleimage.jpg");
        Byte[] bytedata = imageToByteArray(img);
        if (bytedata != null)
        {
            stagedContent.SetMetaData("BinaryMetaField", bytedata);
        }
        this.MetaFields.ContentManager = this.Manager;
        this.MetaFields.Content = stagedContent;
        this.MetaFields.SaveContent();
        this.Host.Manager.SaveTags(stagedContent.ID, this.SelectedTags);
        this.Manager.SaveContent(stagedContent);
        HttpContext.Current.Response.Redirect(this.GetPreviewCommand(empty));
    }
     
    public byte[] imageToByteArray(System.Drawing.Image imageIn)
    {
        MemoryStream ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        return ms.GetBuffer();//<--Like telerik in Libs 
        //return ms.ToArray(); 
    }


    I hope all is clear now.

    Regards,
    Radoslav Georgiev
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Register for webinar
8 posts, 0 answered