I am using .NET4.5
, MVC5
, C#
and Visual Studio 2013
. I have ViewModel that has collection of UserInformation
.
public class UserInformation
{
[Required(ErrorMessage = "Please enter your first name"), Display(Name = "First name")]
[DataMember(IsRequired = true)]
[RegularExpression(@"^ *?[a-zA-Z]+[ a-zA-Z-_']*$", ErrorMessage = "Please enter First name with letters only")]
[StringLength(20, ErrorMessage = "Please enter a firstname with no more than 20 characters")]
public string Firstname { get; set; }
[Required(ErrorMessage = "Please enter your surname"), Display(Name = "Surname")]
[DataMember(IsRequired = true)]
[RegularExpression(@"^ *?[a-zA-Z]+[ a-zA-Z-_']*$", ErrorMessage = "Please enter Surname with letters only")]
[StringLength(20, ErrorMessage = "Please enter a surname with no more than 20 characters")]
public string Surname { get; set; }
}
When rendering users on page Customer0 gets data annotations added while Customer1 does not.
Customer 0:
<input name="Customers[0].Firstname" class="tooltip form-control input valid" data-val="true" data-val-length="Please enter a firstname with no more than 20 characters" data-val-length-max="20" data-val-regex="Please enter First name with letters only" data-val-regex-pattern="^ *?[a-zA-Z]+[ a-zA-Z-_']*$" data-val-required="Please enter your first name" id="Customers[0].Firstname" maxlength="20" placeholder="Name" tabindex="" type="text" value="Matas">
Customer 1:
<input name="Customers[1].Firstname" class="tooltip form-control input valid" id="Customers[1].Firstname" maxlength="20" placeholder="Name" tabindex="" type="text" value="sss">
I have managed to trace to the point where it get's rendered on the page that anotations are still there
From immediate window:
var attr3 = Model.Item1.GetType().GetProperties()[1].GetCustomAttributes(true);
{object[5]}
[0]: {System.ComponentModel.DataAnnotations.RequiredAttribute}
[1]: {System.Runtime.Serialization.DataMemberAttribute}
[2]: {System.ComponentModel.DataAnnotations.StringLengthAttribute}
[3]: {System.ComponentModel.DataAnnotations.RegularExpressionAttribute}
[4]: {System.ComponentModel.DataAnnotations.DisplayAttribute}
To investigate further (following the string) next step is to render both controls immediately to see what I am getting.
When I try to render controls in Immediate Window
var s = Html.TextEditor(o => o.Item1.Firstname, new TextEditParameters { Id = string.Format("Customers[{0}].Firstname", Model.Item2), Name = string.Format("Customers[{0}].Firstname", Model.Item2), CssClasses = "input", Placeholder = "Firstname", Type = HtmlExtensions.TextEditorType.OnlyTextBox });
I obviously get
Expression cannot contain lambda expressions
Edit: Mechanism that generates control
In main partial:
Customer 0:
@Html.Partial("Unit/_Customer", new Tuple<UserInformation, int>(Model.Customers[0], 0))
Customer 1:
@if (Model.Customers.Count > 1)
{
<li>
<h1 class="h1--blue">Your partners details</h1>
</li>
Html.RenderPartial("Unit/_Customer", new Tuple<UserInformation, int>(Model.Customers[1], 1));
}
In _Customer partial:
<div class="split-input--left">
@Html.TextEditor(o => o.Item1.Firstname, new TextEditParameters { Name = string.Format("Customers[{0}].Firstname", Model.Item2), Id = string.Format("Customers[{0}].Firstname", Model.Item2), CssClasses = "input ", Placeholder = "Name", Type = HtmlExtensions.TextEditorType.OnlyTextBox })
</div>
Then in html extensions:
public static MvcHtmlString TextEditor<TModel, TValue>(this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression, TextEditParameters textEditParameters)
{
string editor;
switch (textEditParameters.Type)
{
case TextEditorType.Currency:
editor = "Inputs/CurrencyPrefixTextInput";
break;
case TextEditorType.Autocomplete:
editor = "Inputs/AutocompleteTextInput";
break;
case TextEditorType.Email:
editor = "Inputs/EmailTextInput";
break;
case TextEditorType.Tel:
editor = "Inputs/TelTextInput";
break;
case TextEditorType.OnlyTextBox:
editor = "Inputs/TextInputOnly";
break;
case TextEditorType.OnlyTextBoxCurrency:
editor = "Inputs/TextInputOnlyCurrency";
break;
default:
editor = "Inputs/TextInput";
break;
}
var member = expression.Body as MemberExpression;
var maxLength = 4096;
if (member != null)
{
var stringLengthAttr =
(member.Member.GetCustomAttributes(typeof (StringLengthAttribute), false).FirstOrDefault() as StringLengthAttribute);
if (stringLengthAttr != null)
maxLength = stringLengthAttr.MaximumLength;
}
var model = new
{
InputFormat = textEditParameters.Format,
HasHelp = textEditParameters.HasHelpText,
UniqueId = textEditParameters.Id ?? GetHtmlifiedId(html.IdFor(expression).ToString()),
PlaceHolder = textEditParameters.Placeholder,
MaxLength = maxLength,
textEditParameters.Annotation,
textEditParameters.HasTick,
textEditParameters.TabIndex,
textEditParameters.CssClasses,
textEditParameters.Name,
RangeErrorMessage = textEditParameters is CurrencyTextEditParameters ? ((CurrencyTextEditParameters) textEditParameters).RangeErrorMessage : null,
RangeValidation = textEditParameters is CurrencyTextEditParameters ? ((CurrencyTextEditParameters)textEditParameters).RangeValidation : null,
RegexValidation = textEditParameters is CurrencyTextEditParameters ? ((CurrencyTextEditParameters)textEditParameters).RegexValidation : null,
RegexErrorMessage = textEditParameters is CurrencyTextEditParameters ? ((CurrencyTextEditParameters)textEditParameters).RegexErrorMessage : null,
IsRequired = textEditParameters is CurrencyTextEditParameters && ((CurrencyTextEditParameters)textEditParameters).IsRequired,
RequiredErrorMessage = textEditParameters is CurrencyTextEditParameters ? ((CurrencyTextEditParameters)textEditParameters).RequiredErrorMessage : null,
};
return html.EditorFor(expression, editor, model);
}
Then it gets passed into TextInputOnly.cshtml partial:
@Html.TextBoxFor(m => m, @ViewData["InputFormat"].ToString(), new { Name = ViewData["Name"], @class = string.Format("tooltip form-control {0}", ViewData["CssClasses"]), id = ViewData["UniqueId"].ToString(), @placeholder = ViewData["PlaceHolder"].ToString(), maxlength = ViewData["MaxLength"].ToString(), tabindex = ViewData["TabIndex"] })
@Html.ValidationMessageFor(m => m, null, new {@class = "field-validation-error", data_valmsg_for = ViewData["Name"]})
This is where I am doing debugging of attributes still being there.
How would I go around rendering control whilst debugging in Visual Studio 2013?