Tags selector error
I am trying to implement a tag selector on my MVC widget designer. I am following the instruction that is posted here: www.sitefinity.com/.../creating-a-custom-widget-designer-using-sitefinity-and-sitefinity-thunder-part-2
I originally followed the original instruction but keep getting an error cannot cast System.String to System.Guid[]. So I decided that I just need one tag instead of multiple tags
<
sitefinity:FlatTaxonField
ID
=
"TagsSelector"
runat
=
"server"
DisplayMode
=
"Write"
WebServiceUrl
=
"~/Sitefinity/Services/Taxonomies/FlatTaxon.svc/cb0f3a19-a211-48a7-88ec-77495c0f5374"
TaxonomyMetafieldName
=
"Tags"
AllowMultipleSelection
=
"false"
Expanded
=
"false"
Title
=
"Tags"
/>
I modified the .js file to:
/* Called when the designer window gets opened and here is place to "bind" your designer to the control properties */
refreshUI:
function
()
var
controlData =
this
._propertyEditor.get_control().Settings;
/* JavaScript clone of your control - all the control properties will be properties of the controlData too */
/* RefreshUI SelectedTagId */
jQuery(
this
.get_selectedTagId()).val(controlData.SelectedTagId);
// load tags
var
t =
this
.get_TagsSelector();
debugger;
if
(controlData.SelectedTagId !==
null
&& controlData.SelectedTagId !==
'00000000-0000-0000-0000-000000000000'
)
t.set_value(controlData.SelectedTagId);
,
/* Called when the "Save" button is clicked. Here you can transfer the settings from the designer to the control */
applyChanges:
function
()
var
controlData =
this
._propertyEditor.get_control().Settings;
debugger;
/* ApplyChanges SelectedTagId */
controlData.SelectedTagId = jQuery(
this
.get_selectedTagId()).val();
// save selected tags
var
t =
this
.get_TagsSelector();
var
tags = t.get_value();
if
(tags !=
null
)
controlData.SelectedTagId = t.get_value();
else
controlData.SelectedTagId =
'00000000-0000-0000-0000-000000000000'
;
,
I received an error when I click the 'Save' button:
PUT 192.168.21.142:8888/.../ControlPropertyService…radePageVersion=False&propertyLocalization=0&isOpenedByBrowseAndEdit=false 500 (There was an error deserializing the object of type Telerik.Sitefinity.Modules.Pages.Web.Services.Model.WcfControlProperty[]. End element 'PropertyValue' from namespace '' expected. Found element 'item' from namespace ''.)
I attached the more detailed error message from Chrome. Could anyone point out what I am doing wrong here?
Hello,
Please note that in the documentation the selectedTags field and property of type Guid[]. If you want to assign or get a value of type System.String you should either use Guid.Parse(stringValue) or Guid.ToString() methods.
About the error you are encountering currently, I will need more information in order to find what cause it. Could you share the code-behind used by the TagSelector?
Regards,
Andrey
Telerik
I think the root of the problem here is having the public access modifier on the SelectedTags properties. That properties somehow is picked up by the Designer and the value is always 'System.Guid[]', so when I click the save button that string value will be passed to the SelectedTags value that expects an array of Guid.
I changed the access modifier of selectedTags field and SelectedTags properties to private and the selector starts to work properly.
Attached is the screenshot of the error and the Advanced mode of the designer
Hello,
Yes, there is a mistake in the demo code. Actually the selectedTags field should be private, otherwise you could violate the property initialization and get an exception.
By making the properties private you are hiding them from the designer. Sitefinity only iterates through the public properties of the designer file. Could you verify that you are modifying the widget UI file and not the designer UI file?
Additionally, I was not able to find any of the attachments you are referring to. Could you share your code behind file?
Regards,
Andrey
Telerik
I believe the SelectedTags properties has to be private also, not only the selectedTags field. Otherwise that properties will be picked up by Sitefinity Designer and the javascript will try to pass string ('System.Guid[]) to the SelectedTags (array of Guid) which is the root of the problem.
I did not post the code on the previous post, I am not sure why you need it now, because I don't experience the problem again, but here it is.
using
System;
using
System.Linq;
using
System.Web.UI;
using
Telerik.Sitefinity.Web.UI;
using
Telerik.Sitefinity.Web.UI.ControlDesign;
using
System.Collections.Generic;
using
System.Web.UI.WebControls;
using
System.Web;
using
Telerik.Sitefinity.Modules.Pages;
using
System.Web.UI.HtmlControls;
using
Telerik.Sitefinity.Web.UI.Fields;
using
Telerik.Sitefinity.Taxonomies;
namespace
SitefinityWebApp.WidgetDesigners.TagTest
/// <summary>
/// Represents a designer for the <typeparamref name="SitefinityWebApp.Mvc.Controllers.TagTestController"/> widget
/// </summary>
public
class
TagTestDesigner : ControlDesignerBase
#region Properties
/// <summary>
/// Obsolete. Use LayoutTemplatePath instead.
/// </summary>
protected
override
string
LayoutTemplateName
get
return
string
.Empty;
/// <summary>
/// Gets the layout template's relative or virtual path.
/// </summary>
public
override
string
LayoutTemplatePath
get
if
(
string
.IsNullOrEmpty(
base
.LayoutTemplatePath))
return
AssociatedInsightsDesigner.layoutTemplatePath;
return
base
.LayoutTemplatePath;
set
base
.LayoutTemplatePath = value;
protected
override
HtmlTextWriterTag TagKey
get
return
HtmlTextWriterTag.Div;
#endregion
#region Control references
protected
virtual
Control TagValue
get
return
this
.Container.GetControl<Control>(
"TagValue"
,
true
);
protected
FlatTaxonField TagsSelector
get
return
Container.GetControl<FlatTaxonField>(
"TagsSelector"
,
true
);
#endregion
#region Methods
protected
override
void
InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container)
// initialize the taxonomy selectors
TagsSelector.TaxonomyId = TaxonomyManager.TagsTaxonomyId;
#endregion
#region IScriptControl implementation
/// <summary>
/// Gets a collection of script descriptors that represent ECMAScript (JavaScript) client components.
/// </summary>
public
override
System.Collections.Generic.IEnumerable<System.Web.UI.ScriptDescriptor> GetScriptDescriptors()
var scriptDescriptors =
new
List<ScriptDescriptor>(
base
.GetScriptDescriptors());
var descriptor = (ScriptControlDescriptor)scriptDescriptors.Last();
descriptor.AddElementProperty(
"tagValue"
,
this
.TagValue.ClientID);
descriptor.AddComponentProperty(
"TagsSelector"
,
this
.TagsSelector.ClientID);
return
scriptDescriptors;
/// <summary>
/// Gets a collection of ScriptReference objects that define script resources that the control requires.
/// </summary>
public
override
System.Collections.Generic.IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
var scripts =
new
List<ScriptReference>(
base
.GetScriptReferences());
scripts.Add(
new
ScriptReference(TagTestDesigner.scriptReference));
return
scripts;
#endregion
#region Private members & constants
public
static
readonly
string
layoutTemplatePath =
"~/WidgetDesigners/TagTest/TagTestDesigner.ascx"
;
public
const
string
scriptReference =
"~/WidgetDesigners/TagTest/TagTestDesigner.js"
;
#endregion
Hi,
Yes, one way is to leave the properties as private if you do not intend to use them elsewhere, however, you could just mark the SelectedTags
property as Browsable(false). Thus the designer will skip it when enumerating the properties.
Regards,
Andrey
Telerik