NullReferenceException when creating form from data source
Anyone seen this issue before. Am I doing something wrong or is this a bug?
Product
Contour (1.1?)
Description
When attempting to use a drop down list in a form created from data source, getting NullReferenceException. I have setup a data source that points to my "Listing" document types. I am trying to create a form from the data source. One of the properties of the "Listing" document is "Listing Type". This property should be a drop down, check box, radio button list, or list box. Something that presents the user with prevalues. When I go to create the form, i select a drop down list for the Listing Type property. Then, i select create form and immediately get the null reference exception. The data type for the Listing Type uses the ultimate picker control.
[NullReferenceException: Object reference not set to an instance of an object.]
Umbraco.Forms.UI.Usercontrols.EditForm.GetPrevalueAttributes(Field f) in d:\TeamCity6\buildAgent\work\278191fcc80f7b16\Umbraco.Forms.UI\Usercontrols\EditForm.ascx.cs:233
ASP.usercontrols_umbracocontour_editform_ascx.__DataBind__control9(Object sender, EventArgs e) +2243
System.Web.UI.Control.OnDataBinding(EventArgs e) +91
System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) +92
System.Web.UI.Control.DataBind() +15
System.Web.UI.Control.DataBindChildren() +201
System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding) +101
It seems the issue is that the UmbracoNode data source type does not support properties that use the ultimatepicker data type (or any that use the ultimatepicker as their render control). According to the Contour shared source, only data types that use KeyValuePrevalueEditor type Prevalue Editor get setup for prevalues. I had to create a custom data source type to get around this.
This does pretty much the same thing with a couple exceptions...
In the GetAvailableFields() method, i added some logic that runs if the data type uses the ultimatepickerprevalueeditor. If it does, then i find the first prevalue source that matches the root node specified in the ultimate picker data type. So yes, this requires that you have a node prevalue source setup to work with your ultimate picker. Last, i set the prevaluesource so i know what prevalue source to work with in the GetPrevalues method. I assume the mapper wouldnt know what prevaluesource to use unless i set it where i did.
In the GetPrevalues(), i added some logic to get the prevalue source for the current field (the one i set in the GetAvailableFields() method). Then i basically cycle through and add the prevalues from the prevalue source. You will notice that i also set a couple things on the field itself. I believe this also makes it so that when you drop down the additional settings in contour on the field, the prevalue type is set to the correct prevalue source (not set to standard).
It essentially, makes umbraco think that any field tied to an ultimatepicker datatype gets its prevalues from a prevalue source.
public class Entities : Umbraco.Forms.Core.Providers.DatasourceTypes.UmbracoNodes
{
public Entities()
{
this.Id = new Guid("0004F913-3677-42D9-BE69-9BEC2E0EA0BC");
this.Name = "Entities";
this.Description = "Saves record data as a umbraco document/entity";
}
[Setting("Document Type", description = "ID of the type", control = "Umbraco.Forms.Core.FieldSetting.Pickers.DocumentType")]
public string DocType { get; set; }
[Setting("Parent Node", description = "ID of node to save the new pages under", control = "Umbraco.Forms.Core.FieldSetting.Pickers.Content")]
public string Parent { get; set; }
[Setting("Publish On Submit", description = "Publish node instantly", control = "Umbraco.Forms.Core.FieldSetting.Checkbox")]
public string PublishOnSubmit { get; set; }
public override List GetRecords(Form form, int page, int maxItems, object sortByField, Sorting Order)
{
return base.GetRecords(form, page, maxItems, sortByField, Order);
}
public override Record InsertRecord(Record record)
{
return base.InsertRecord(record);
}
public override Dictionary GetAvailableFields()
{
Dictionary result = new Dictionary();
DocumentType dt = new DocumentType(int.Parse(DocType));
foreach (PropertyType pt in dt.PropertyTypes)
{
FormDataSourceField prop = new FormDataSourceField();
prop.Name = pt.Name;
prop.Key = pt.Alias;
prop.IsMandatory = pt.Mandatory;
prop.AllowNulls = !pt.Mandatory;
Type prEditor = pt.DataTypeDefinition.DataType.PrevalueEditor.GetType();
LogHelper.Debug(prEditor.ToString());
LogHelper.Debug((prEditor == typeof(umbraco.editorControls.KeyValuePrevalueEditor)).ToString());
if (prEditor == typeof(umbraco.editorControls.KeyValuePrevalueEditor))
{
prop.PrevalueSource = pt.DataTypeDefinition.Id.ToString();
prop.PrevalueValueField = "value";
prop.PrevalueKeyField = "key";
prop.IsForeignKey = true;
}
else if (prEditor == typeof(umbraco.editorControls.ultimatepicker.ultimatePickerPrevalueEditor))
{
//Instantiate a ultimateprevalueeditor so we can get the extract the root node.
ultimatePickerPrevalueEditor uprevalueeditor = new ultimatePickerPrevalueEditor((ultimatePickerDataType)pt.DataTypeDefinition.DataType);
string configstring = uprevalueeditor.Configuration;
char[] delimiter = { '|' };
string[] configitems = configstring.Split(delimiter);
//root node is always the second (index 1) item.
string rootnode = configitems[1];
PrevalueSourceStorage prevaluestorage = new PrevalueSourceStorage();
IList prevaluesources = prevaluestorage.GetAllPrevalueSources();
FieldPreValueSource prevaluesource = null;
//We have to cycle through like this instead of using the Linq SingleOrDefault method. Comparing off Settings["RootNode"] throws an error, not sure why.
foreach (FieldPreValueSource test in prevaluesources)
{
if (test.Type is NodePrevalues)
{
NodePrevalues test2 = new NodePrevalues();
test2 = (NodePrevalues)test.Type;
test2.LoadSettings(test);
//If it matches the root node, grab it and exit the loop.
if (test2.RootNode == rootnode)
{
prevaluesource = test;
break;
}
}
}
if(prevaluesource != null)
{
prop.PrevalueSource = prevaluesource.Id.ToString();
prop.IsForeignKey = true;
}
}
DBTypes umbType = ((BaseDataType)pt.DataTypeDefinition.DataType).DBType;
switch (umbType)
{
case DBTypes.Date:
prop.Type = typeof(DateTime);
break;
case DBTypes.Integer:
prop.Type = typeof(int);
break;
case DBTypes.Ntext:
prop.Type = typeof(string);
prop.MaxLength = 5001;
break;
case DBTypes.Nvarchar:
prop.Type = typeof(string);
break;
default:
break;
}
prop.Position = pt.SortOrder;
result.Add(prop.Key, prop);
}
return result;
}
public override Dictionary GetPrevalues(Field field)
{
Dictionary retval = new Dictionary();
retval = base.GetPrevalues(field);
Umbraco.Forms.Data.Storage.DataSourceFieldMappingsStorage mappings = new Umbraco.Forms.Data.Storage.DataSourceFieldMappingsStorage();
FormDataSourceMapping mapping = mappings.GetFieldMapping(field);
mappings.Dispose();
if (mapping != null)
{
Guid prevaluetable = new Guid();
//If a prevaluesource was set in the GetAvailableFields method, try to match it to a prevalue source.
if(Guid.TryParse(mapping.PrevalueTable, out prevaluetable))
{
PrevalueSourceStorage prevaluestorage = new PrevalueSourceStorage();
FieldPreValueSource prevaluesource = prevaluestorage.GetPrevalueSource(prevaluetable);
field.PreValueSource = prevaluesource;
field.PreValueSourceId = prevaluesource.Id;
Umbraco.Forms.Core.Providers.Prevalues.NodePrevalues nodeprovider = new Umbraco.Forms.Core.Providers.Prevalues.NodePrevalues();
nodeprovider.LoadSettings(prevaluesource);
//IList prevalues = nodeprovider.GetPreValues(field);
field.PreValues = nodeprovider.GetPreValues(field);
foreach (Umbraco.Forms.Core.PreValue prevalue in field.PreValues)
{
retval.Add(prevalue.Id, prevalue.Value);
}
}
}
return retval;
}
}
NullReferenceException when creating form from data source
Anyone seen this issue before. Am I doing something wrong or is this a bug?
Product
Contour (1.1?)
Description
When attempting to use a drop down list in a form created from data source, getting NullReferenceException. I have setup a data source that points to my "Listing" document types. I am trying to create a form from the data source. One of the properties of the "Listing" document is "Listing Type". This property should be a drop down, check box, radio button list, or list box. Something that presents the user with prevalues. When I go to create the form, i select a drop down list for the Listing Type property. Then, i select create form and immediately get the null reference exception. The data type for the Listing Type uses the ultimate picker control.
Think i figured this one out...
It seems the issue is that the UmbracoNode data source type does not support properties that use the ultimatepicker data type (or any that use the ultimatepicker as their render control). According to the Contour shared source, only data types that use KeyValuePrevalueEditor type Prevalue Editor get setup for prevalues. I had to create a custom data source type to get around this.
This does pretty much the same thing with a couple exceptions...
In the GetAvailableFields() method, i added some logic that runs if the data type uses the ultimatepickerprevalueeditor. If it does, then i find the first prevalue source that matches the root node specified in the ultimate picker data type. So yes, this requires that you have a node prevalue source setup to work with your ultimate picker. Last, i set the prevaluesource so i know what prevalue source to work with in the GetPrevalues method. I assume the mapper wouldnt know what prevaluesource to use unless i set it where i did.
In the GetPrevalues(), i added some logic to get the prevalue source for the current field (the one i set in the GetAvailableFields() method). Then i basically cycle through and add the prevalues from the prevalue source. You will notice that i also set a couple things on the field itself. I believe this also makes it so that when you drop down the additional settings in contour on the field, the prevalue type is set to the correct prevalue source (not set to standard).
It essentially, makes umbraco think that any field tied to an ultimatepicker datatype gets its prevalues from a prevalue source.
is working on a reply...