Unfortunately this problem is specific to Contour rather than Umbraco nodes, so in your example I didn't find any node problems.
My forms use custom PreValueFieldSourceTypes which I have written in C# and applied the FieldPreValueSource in C# too. In the CodeFirst form i've bound one custom value to a dropdown and one to a RadioButtonList. The whole thing is supposed to spring into action with Tims ContourFormBuilderHttpModule which get insert on app_startup as web.config entries.
When the CodeFirst forms incorporate these additional custom types I think i'm getting some kind of load order issue. I assume this is the case because I also get object exceptions, which would indicate the prevalue type hasn't been new'd up before the form.
If I remove my custom types altogether the problem goes away.
Here's some code just in case i'm doing something wrong, the prevalue first...
// Adds a multilingual list of countries as a pre-value datasource (en.xml)
public class Countries : FieldPreValueSourceType
{
public Countries()
{
this.Id = new Guid("8e9c49a9-68ca-4f81-8578-d3ebae2988d9");
this.Name = "List of countries";
this.Description = "Multilingual list of countries (http://unicode.org/ files need to be in /app_data/countrydata/)";
}
public override List ValidateSettings()
{
var ex = new List();
if (!File.Exists(HttpContext.Current.Server.MapPath("/App_Data/CountryData/common/main/en.xml")))
ex.Add(new Exception("Unicode Common Locale Data Repository not found, please download from http://cldr.unicode.org and place in /app_data/countrydata/ directory"));
return ex;
}
public override List GetPreValues(Field field)
{
var pvs = new List();
var d = new XmlDocument();
if (File.Exists(HttpContext.Current.Server.MapPath(
string.Format("/App_Data/CountryData/common/main/{0}.xml",
CultureInfo.CurrentCulture.TwoLetterISOLanguageName))))
{
d.Load(HttpContext.Current.Server.MapPath(
string.Format("/App_Data/CountryData/common/main/{0}.xml",
CultureInfo.CurrentCulture.TwoLetterISOLanguageName)));
}
else
{
d.Load(HttpContext.Current.Server.MapPath(
"/App_Data/CountryData/common/main/en.xml"));
}
var countries = new List>();
foreach (XmlNode c in d.SelectNodes("//territory [string-length(string(@type)) < 3]"))
countries.Add(new KeyValuePair(c.Attributes["type"].Value, c.InnerText));
countries.Sort((firstPair, nextPair) => String.Compare(firstPair.Value, nextPair.Value, StringComparison.Ordinal));
int sort = 0;
foreach (var c in countries)
{
PreValue pv = new PreValue();
pv.Id = c.Key;
pv.Value = c.Value;
if (field != null)
pv.Field = field.Id;
pv.SortOrder = sort;
pvs.Add(pv);
sort++;
}
return pvs;
}
}
// prepopulate sources in umbraco
[PrevalueSource("countries")]
public class PrevalueSourceCountries : PrevalueSourceBase
{
public override FieldPreValueSourceType Type
{
get
{
FieldPreValueSourceType pvs = new Countries();
return pvs;
}
}
}
And the form with the attribute to bind the pre-value
//Change of address form
[Form("Member forms/Change of address", ShowValidationSummary = false, DisableDefaultStylesheet = true,
Id = "d73be165-4fbb-45fe-9614-4e06b1576b0e")]
public class ChangeOfAddress : FormBase
{
[Field("Change of address", "", Mandatory = true, InvalidErrorMessage = "This field is required", Caption = "Address 1")]
public string AddressLine1 { get; set; }
[Field("Change of address", "", Mandatory = false, Caption = "Address 2")]
public string AddressLine2 { get; set; }
[Field("Change of address", "", Mandatory = false, Caption = "Address 3")]
public string AddressLine3 { get; set; }
[Field("Change of address", "", Mandatory = false, Caption = "Address 4")]
public string AddressLine4 { get; set; }
[Field("Change of address", "", Mandatory = false, Caption = "Country", Type = typeof(DropDownList), PrevalueSource = "countries", DefaultValue = "United Kingdom")]
public string Country { get; set; }
[Field("Change of address", "", Mandatory = false, Caption = "Postcode", AdditionalSettings = new string[] { "maxLength: 9" }, Type = typeof(TextFieldExtended))]
public string PostCode { get; set; }
public override IEnumerable<Exception> Validate()
{
var e = new List<Exception>();
return e;
}
public override void Submit()
{
var memberDetails = FormsHelpers.GetPeriodsOfService();
var memberId = 0;
if (memberDetails.Length > 0)
{
memberId = memberDetails[0].MemberId;
}
Node currentNode = Node.GetCurrent();
var allNodes = currentNode.GetAncestorOrSelfNodes();
var rootNode = allNodes.First(x => x.Level == 1);
var email = String.Empty;
if (rootNode.HasProperty("siteEmail") && rootNode.GetProperty("siteEmail") != null)
{
email = rootNode.GetProperty("siteEmail").Value;
}
var user = Membership.GetUser();
var memberEmail = user.Email;
var memberUserName = user.UserName;
StringBuilder builder = new StringBuilder();
builder.Append("<style>p, strong, h1, h2 { font-family: arial; } </style>");
builder.Append(String.Format("<p><strong>Member Id:</strong> {0}</p>", memberId));
builder.Append(String.Format("<p><strong>Address Line 1:</strong> {0}</p>", AddressLine1));
builder.Append(String.Format("<p><strong>Address Line 2:</strong> {0}</p>", AddressLine2));
builder.Append(String.Format("<p><strong>Address Line 3:</strong> {0}</p>", AddressLine3));
builder.Append(String.Format("<p><strong>Address Line 4:</strong> {0}</p>", AddressLine4));
builder.Append(String.Format("<p><strong>Country:</strong> {0}</p>", Country));
builder.Append(String.Format("<p><strong>Postcode:</strong> {0}</p>", PostCode));
library.SendMail(memberEmail, email, "Change of Address Form",
String.Format("<h1>New message from {0}</h1>{1}", memberUserName, builder.ToString()), true);
FormsHelpers.LogActivity(String.Format("Submitted '{0}'", Node.GetCurrent().Name));
}
}
Strange YSOD with CodeFirst approach
Hi Tim
I'm getting a really odd error on app startup, build is U7.1.5 / C 3.0.21.
I'm using codefirst forms and two custom fieldprevaluetypes.
Hi Martin
Not sure why it happens, but perhaps try running the script Mike Chambers mentions in the last post here? http://our.umbraco.org/forum/umbraco-7/using-umbraco-7/53211-Sequence-contains-not-matching-element?p=0#comment185351 (His first post).
/Jan
Hi Jan
Good morning and thanks for the suggestion! :-)
Unfortunately this problem is specific to Contour rather than Umbraco nodes, so in your example I didn't find any node problems.
My forms use custom PreValueFieldSourceTypes which I have written in C# and applied the FieldPreValueSource in C# too. In the CodeFirst form i've bound one custom value to a dropdown and one to a RadioButtonList. The whole thing is supposed to spring into action with Tims ContourFormBuilderHttpModule which get insert on app_startup as web.config entries.
When the CodeFirst forms incorporate these additional custom types I think i'm getting some kind of load order issue. I assume this is the case because I also get object exceptions, which would indicate the prevalue type hasn't been new'd up before the form.
If I remove my custom types altogether the problem goes away.
Here's some code just in case i'm doing something wrong, the prevalue first...
// Adds a multilingual list of countries as a pre-value datasource (en.xml) public class Countries : FieldPreValueSourceType { public Countries() { this.Id = new Guid("8e9c49a9-68ca-4f81-8578-d3ebae2988d9"); this.Name = "List of countries"; this.Description = "Multilingual list of countries (http://unicode.org/ files need to be in /app_data/countrydata/)"; } public override List ValidateSettings() { var ex = new List(); if (!File.Exists(HttpContext.Current.Server.MapPath("/App_Data/CountryData/common/main/en.xml"))) ex.Add(new Exception("Unicode Common Locale Data Repository not found, please download from http://cldr.unicode.org and place in /app_data/countrydata/ directory")); return ex; } public override List GetPreValues(Field field) { var pvs = new List(); var d = new XmlDocument(); if (File.Exists(HttpContext.Current.Server.MapPath( string.Format("/App_Data/CountryData/common/main/{0}.xml", CultureInfo.CurrentCulture.TwoLetterISOLanguageName)))) { d.Load(HttpContext.Current.Server.MapPath( string.Format("/App_Data/CountryData/common/main/{0}.xml", CultureInfo.CurrentCulture.TwoLetterISOLanguageName))); } else { d.Load(HttpContext.Current.Server.MapPath( "/App_Data/CountryData/common/main/en.xml")); } var countries = new List>(); foreach (XmlNode c in d.SelectNodes("//territory [string-length(string(@type)) < 3]")) countries.Add(new KeyValuePair(c.Attributes["type"].Value, c.InnerText)); countries.Sort((firstPair, nextPair) => String.Compare(firstPair.Value, nextPair.Value, StringComparison.Ordinal)); int sort = 0; foreach (var c in countries) { PreValue pv = new PreValue(); pv.Id = c.Key; pv.Value = c.Value; if (field != null) pv.Field = field.Id; pv.SortOrder = sort; pvs.Add(pv); sort++; } return pvs; } } // prepopulate sources in umbraco [PrevalueSource("countries")] public class PrevalueSourceCountries : PrevalueSourceBase { public override FieldPreValueSourceType Type { get { FieldPreValueSourceType pvs = new Countries(); return pvs; } } }And the form with the attribute to bind the pre-value
//Change of address form [Form("Member forms/Change of address", ShowValidationSummary = false, DisableDefaultStylesheet = true, Id = "d73be165-4fbb-45fe-9614-4e06b1576b0e")] public class ChangeOfAddress : FormBase { [Field("Change of address", "", Mandatory = true, InvalidErrorMessage = "This field is required", Caption = "Address 1")] public string AddressLine1 { get; set; } [Field("Change of address", "", Mandatory = false, Caption = "Address 2")] public string AddressLine2 { get; set; } [Field("Change of address", "", Mandatory = false, Caption = "Address 3")] public string AddressLine3 { get; set; } [Field("Change of address", "", Mandatory = false, Caption = "Address 4")] public string AddressLine4 { get; set; } [Field("Change of address", "", Mandatory = false, Caption = "Country", Type = typeof(DropDownList), PrevalueSource = "countries", DefaultValue = "United Kingdom")] public string Country { get; set; } [Field("Change of address", "", Mandatory = false, Caption = "Postcode", AdditionalSettings = new string[] { "maxLength: 9" }, Type = typeof(TextFieldExtended))] public string PostCode { get; set; } public override IEnumerable<Exception> Validate() { var e = new List<Exception>(); return e; } public override void Submit() { var memberDetails = FormsHelpers.GetPeriodsOfService(); var memberId = 0; if (memberDetails.Length > 0) { memberId = memberDetails[0].MemberId; } Node currentNode = Node.GetCurrent(); var allNodes = currentNode.GetAncestorOrSelfNodes(); var rootNode = allNodes.First(x => x.Level == 1); var email = String.Empty; if (rootNode.HasProperty("siteEmail") && rootNode.GetProperty("siteEmail") != null) { email = rootNode.GetProperty("siteEmail").Value; } var user = Membership.GetUser(); var memberEmail = user.Email; var memberUserName = user.UserName; StringBuilder builder = new StringBuilder(); builder.Append("<style>p, strong, h1, h2 { font-family: arial; } </style>"); builder.Append(String.Format("<p><strong>Member Id:</strong> {0}</p>", memberId)); builder.Append(String.Format("<p><strong>Address Line 1:</strong> {0}</p>", AddressLine1)); builder.Append(String.Format("<p><strong>Address Line 2:</strong> {0}</p>", AddressLine2)); builder.Append(String.Format("<p><strong>Address Line 3:</strong> {0}</p>", AddressLine3)); builder.Append(String.Format("<p><strong>Address Line 4:</strong> {0}</p>", AddressLine4)); builder.Append(String.Format("<p><strong>Country:</strong> {0}</p>", Country)); builder.Append(String.Format("<p><strong>Postcode:</strong> {0}</p>", PostCode)); library.SendMail(memberEmail, email, "Change of Address Form", String.Format("<h1>New message from {0}</h1>{1}", memberUserName, builder.ToString()), true); FormsHelpers.LogActivity(String.Format("Submitted '{0}'", Node.GetCurrent().Name)); } }is working on a reply...
This forum is in read-only mode while we transition to the new forum.
You can continue this topic on the new forum by tapping the "Continue discussion" link below.