Blazor EditForm missing Email and Phone? - blazor-server-side

Is there a validator for Emails and Phone # in EditForm like there is in Form (e.g.) "tel" for phone and "email" for emails.
Even though they test for formatting not existence of phone and email.

Hy,
What i did was ; create a public class and link this to the editform.
Using Regex expressions you can create your own validation.
public class RegisterAccountModel
{
[Required(AllowEmptyStrings = false, ErrorMessage = "Email adres Missing")]
[EmailAddress(ErrorMessage = "Unvalid Email Address")]
public string Email { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Paswoord Missing")]
[DataType(DataType.Password)]
[StringLength(100)] //, ErrorMessage = "Paswoord dient minstens {2} characters te bevatten waaronder minstens één nummer.", MinimumLength = 6)]
[Display(Name = "Paswoord")]
[RegularExpression("^()(?=.*[\\d])(?=.*[a-z])(?=.*[a-zA-Z]).{6,}$", ErrorMessage = "Min 6 characters and 1 capital letter.")]
public string Password { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Paswoord not Matching")]
[Compare(nameof(Password), ErrorMessage = "Paswoord not Matching")]
public string ConfirmPassword { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Company Is Empty")]
public string Bedrijfsnaam { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Name is empty)]
public string Naam { get; set; }
}
When you want to use this class in your edit form you can do :
<EditForm Context="NewUser" OnSubmit="FormSubmitted" Model="registerAccountModel">
<div class="DataValidationRemark">#RegisterRemarks</div>
<DataAnnotationsValidator />
<ValidationSummary />
<table>
<tr>
<td><p class="label">Email:</p></td>
<td><p><InputText #bind-Value="registerAccountModel.Email" /></p></td>
</tr>
<tr>
<td><p class="label">#lblPassword :</p></td>
<td><p><input type="password" #bind-value="registerAccountModel.Password" /</p></td>
</tr>
</EditForm>
Regarding the submit : This needs to be on your razor page. or code behind file.
#code {
private RegisterAccountModel registerAccountModel = new RegisterAccountModel();
public void FormSubmitted(EditContext editContext)
{
isValidated = editContext.Validate();
if (isValidated)
{
Task.Run(() => RegisterUser());
}
}
Regarding the register user : still on the same razor page
private async Task RegisterUser()
{
//If the form validation is done
if (isValidated)
{
var result = await userManager.CreateAsync(new IdentityUser { UserName = registerAccountModel.Email, Email = registerAccountModel.Email, EmailConfirmed = false }, registerAccountModel.Password);
if (result.Succeeded)
{
//DO STUFF
}
}
}
}
Let me know if it worked for you, or if you got stuck.
Regards,
Mathias

Related

Required message is displayed even if the field is provided C#

Using ASP.Net Core, I am developing a simple form to reset the password using email address.
My model is as follow:
public class EmailViewModel
{
[Required(ErrorMessageResourceName = "Model_RequireEmail", ErrorMessageResourceType = typeof(Resources.Identity))]
[Display(Name = "Models_Account_Email", ResourceType = typeof(Resources.Identity))]
[DataType(DataType.EmailAddress)]
[EmailAddress(ErrorMessage = "Models.EmailFormat")]
[MaxLength(100, ErrorMessage = "Models.MaxLength")]
public string? Email { get; set; }
}
And my view:
<form method="post">
<div class="uk-text-danger">
#Html.ValidationSummary()
</div>
<div class="uk-margin">
<div class="uk-inline">
<span class="uk-form-icon" uk-icon="icon: mail"></span>
#Html.TextBoxFor(m => m.Data.EmailViewModel.Email, new
{
#class = "validate uk-input",
placeholder = Html.DisplayNameFor(m => m.Data.EmailViewModel.Email)
})
#Html.HiddenFor(m => m.Data.ResetPasswordAction)
#Html.HiddenFor(m => m.Data.ResetPasswordController)
</div>
</div>
<button class="uk-button uk-button-default">#Html.LocalizedIdentity("Views.Account.PassReset")</button>
</form>
My issue is that even if I provide a correct email address, I keep getting the message of the "required" data annotation. What did I miss?
EDIT 13/12/2021
The issue occurs when I used a nested ViewModel. For example, the viewModel associated with my form is
public class ForgotPasswordViewModel
{
public EmailViewModel EmailViewModel => new EmailViewModel();
[HiddenInput]
public string? ResetPasswordAction { get; set; }
[HiddenInput]
public string? ResetPasswordController { get; set; }
}
using the EmailViewModel above. This give a ModelState.IsValid= false because the email is null even if provided.
If I bypass the EmailViewModel and use for my ForgotPasswordViewMode, the following:
public class ForgotPasswordViewModel
{
[Display(Name = "Models_Account_Email", ResourceType = typeof(Resources.Identity))]
[Required]
[DataType(DataType.EmailAddress)]
[EmailAddress(ErrorMessage = "Models.EmailFormat")]
[MaxLength(100, ErrorMessage = "Models.MaxLength")]
public string? Email { get; set; }
[HiddenInput]
public string? ResetPasswordAction { get; set; }
[HiddenInput]
public string? ResetPasswordController { get; set; }
}
It works nicely.
The problem is that I want to use the nested ViewModel to avoid repeating it.
Why doesn't it work with the nested EmailViewModel?
This is my model and my test view, it will lead to ModelState.IsValid == false because the input form should have a property of emailVM.Email but not EmailViewModel.
public class EmailViewModel
{
//[Required(ErrorMessageResourceName = "Model_RequireEmail", ErrorMessageResourceType = typeof(Resources.Identity))]
//[Display(Name = "Models_Account_Email", ResourceType = typeof(Resources.Identity))]
[Display(Name = "Models_Account_Email")]
[Required]
[DataType(DataType.EmailAddress)]
[EmailAddress(ErrorMessage = "Models.EmailFormat")]
[MaxLength(100, ErrorMessage = "Models.MaxLength")]
public string? Email { get; set; }
}
public class ForgotPasswordViewModel
{
//public EmailViewModel emailVM => new EmailViewModel();
public EmailViewModel emailVM { get; set; }
[HiddenInput]
public string? ResetPasswordAction { get; set; }
[HiddenInput]
public string? ResetPasswordController { get; set; }
}
<form method="POST" asp-action="Edit">
<div class="uk-text-danger">
#Html.ValidationSummary()
</div>
<div class="uk-inline">
<span class="uk-form-icon" uk-icon="icon: mail"></span>
#Html.TextBoxFor(m => m.emailVM.Email, new
{
placeholder = Html.DisplayNameFor(m => m.emailVM.Email)
})
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>

How to set input box value to a string in Blazor WebAssembly?

I am using Blazor WebAssmebly. I have an input box and I simply want to reset it to no text after the user types in text and hits the Enter key:
<input id="txtWord" name="txtWord" placeholder="Enter your text" #onchange="#onChange" #onkeyup="#Enter" />
private void onChange(Microsoft.AspNetCore.Components.ChangeEventArgs args)
{
value = (string)args.Value;
}
public void Enter(KeyboardEventArgs e)
{
if (e.Code == "Enter" || e.Code == "NumpadEnter")
{
if (value.Trim() != "")
{
doSomething();
}
}
}
So I set the variable 'value' to the input text, but then I want to clear the text box. How do I do that?
It looks like as if you're not binding your input to the value variable. Your code should be something like this:
<input id="txtWord" name="txtWord" placeholder="Enter your text"
value ="#value" #onchange="onChange" #onkeyup="Enter" />
#code
{
private string value;
}
Note that by adding the value attribute to the input element I create a two-way databinding, from the variable to the control, and from the control to the variable. When you use the #onchange directive, you create a one-way data binding.
In order to reset the input element, you can do the following:
if (value.Trim() != "")
{
// I guess it is here that you want to reset the input
// element. Assigning empty string to the `value` variable
// will cause the control to re-render with the new value;
// that is empty string...
value = "";
doSomething();
}
This will handle "enter" and "Submit" button press. I use this in a SignalR library I am developing. The default css classes are for Bootstrap.
SendBox.razor
<EditForm Model="#SendBoxViewModel" OnSubmit="#Send">
<div class="#DivClass">
<input #ref="#inputBox"
#bind-value="SendBoxViewModel.InputMessage"
#bind-value:event="oninput"
type="text"
aria-label="#Placeholder"
placeholder="#Placeholder"
class="#InputClass"
aria-describedby="button-send"
disabled=#Disabled>
<button class="#ButtonClass"
type="submit"
id="button-send"
disabled=#Disabled>
#Label
</button>
</div>
</EditForm>
SendBox.razor.cs
public partial class SendBox : ComponentBase
{
private ElementReference inputBox;
[Parameter]
public string Label { get; set; } = "Send";
[Parameter]
public string Placeholder { get; set; } = "Type a new message here.";
[Parameter]
public string DivClass { get; set; } = "input-group";
[Parameter]
public string InputClass { get; set; } = "form-control";
[Parameter]
public string ButtonClass { get; set; } = "btn btn-outline-primary";
[Parameter]
public bool Disabled { get; set; }
[Parameter]
public EventCallback<string> OnSend { get; set; }
public SendBoxViewModel SendBoxViewModel { get; set; } = new SendBoxViewModel();
private bool MessageInputInvalid => string.IsNullOrWhiteSpace(SendBoxViewModel.InputMessage);
private async Task Send()
{
if (!MessageInputInvalid)
{
await OnSend.InvokeAsync(SendBoxViewModel.InputMessage);
SendBoxViewModel.InputMessage = string.Empty;
await inputBox.FocusAsync();
}
}
}
SendBoxViewModel.cs
public class SendBoxViewModel
{
[MinLength(length: 1)]
[MaxLength(length: 1024)]
[Required(AllowEmptyStrings = false)]
public string? InputMessage { get; set; }
}

How to upload and save muliple images to database

I have this action method:
[HttpPost]
public ActionResult UploadMorePhotos(UserProfile userProfile, IEnumerable<HttpPostedFileBase>files)
{
foreach (var file in files)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
//ModelState.Clear();
}
if (ModelState.IsValid)
{
string username = User.Identity.Name;
// Get the userprofile
UserProfile user = db.userProfiles.FirstOrDefault(u => u.UserName.Equals(username));
// Update fields
user.Image = new byte[file.ContentLength];
file.InputStream.Read(user.Image, 0, file.ContentLength);
user.ImageMimeType = file.ContentType;
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
}
return Redirect(Url.Action("Edit", "Account") + "#tabs-3");
}
return View(userProfile);
}
This is my view:
<div id="tabs-3">
hallo
#using (Html.BeginForm("UploadMorePhotos", "Account", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<div class="form-field">
<p>Select pictures:</p>
<div class="upload-container">
<div class="upload">
<input type="file" name="files" id="file1" />
<img src="#Url.Content("~/images/deleteButton.png")" alt="Remove picture." />
</div>
</div>
</div>
<div class="form-field">
<input type="submit" value="Create" />
</div>
}
</div>
I want to store more Images to Database. A user can select one or more images and the images have to be saved to the database after uploading.
but on this line:
user.Image = new byte[files.ContentLength];
contentLength is not recognised.
Thank you
And this is my model:
public partial class UserProfile
{
public int Id { get; set; }
public string UserName { get; set; }
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
public string Email { get; set; }
[Display(Name = "Motto")]
public string Motto { get; set; }
[Display(Name = "Place of birth")]
public string PlaceOfBirth { get; set; }
[Display(Name = "How many bikes")]
public int HowManyBikes { get; set; }
[Display(Name = "Are they beside your bed")]
public string BesideYourBeth { get; set; }
[Display(Name = "Nicest ride")]
public string NicestRide { get; set; }
[Display(Name = "Worst ride")]
public string WorstRide { get; set; }
[Display(Name = "Amount of k's per year")]
public string AmountKmPerYear { get; set; }
[Display(Name = "Average speed")]
public string AverageSpeed { get; set; }
[Display(Name = "Able to chat while riding")]
public string AbleToChatWhileRiding { get; set; }
[Display(Name = "Phone number")]
public string PhoneNumber { get; set; }
public string Picture { get; set; }
[Column(TypeName = "image")]
[DisplayName("Image")]
[MaxLength]
public byte[] Image { get; set; }
[Display(Name = "Display profile Image")]
public bool DisplayItem { get; set; }
[DisplayName("ImageMimeType")]
public string ImageMimeType { get; set; }
public virtual ICollection<LolaBikePhoto> LolaBikePhotos { get; set; }
}
IF I select mulitiple images for example two I only see one photo in the map: \App_Data\Uploads.
Because A user can have 1 or more photos on his profile.
I add this:
if (user != null)
{
var lolaphoto = new LolaBikePhoto
{
UserProfileID = user.Id
};
// lolaphoto.UserProfileID = 47;
db.lolabikerPhotos.Add(lolaphoto);
}

How to get default selection into selectlist MVC

I need to use dropdownlist into razor and related object into model object.
I want to keep default selected value for the object but it did not work out.
Can any one suggest me what should be the best way to achieve this - what to keep into DTO property and controller action and razor syntax.
Below is my current stuff:
public class StateDTO
{
public int ID { get; set; }
public string Name { get; set; }
}
public class RegisterModel
{
[Required]
[Display(Name = "User name", Order = 2)]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password", Order = 3)]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password", Order = 4)]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Display(Name = "Email Address", Order = 1)]
[DataType(DataType.EmailAddress)]
[Required(AllowEmptyStrings = false, ErrorMessage = "Please enter value")]
public string Email { get; set; }
public IEnumerable<SelectListItem> States { get; set; }
public SelectListItem State { get; set; }
}
public ActionResult Register()
{
RegisterModel r = new RegisterModel();
IList<StateDTO> s = new List<StateDTO>();
s.Add(new StateDTO() { ID = 1, Name = "CA" });
s.Add(new StateDTO() { ID = 2, Name = "LA" });
s.Add(new StateDTO() { ID = 3, Name = "AR" });
r.State = new SelectListItem() { Text = s[2].Name, Value = s[2].ID.ToString(), Selected = true };
r.States = new SelectList(s, "ID", "Name",r.State);
return View(r);
}
View contains below related stuff:
<div class="editor-label">
#Html.LabelFor(model => model.State)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.State, Model.States)
#Html.ValidationMessageFor(model => model.State)
</div>
Please suggest me what should I change into Model object, controller and razor view to achieve default selection of dropdown list... any best way.
Thank You
I have modified the stuff as follow the below link and it worked out.
dropdownlist set selected value in MVC3 Razor
In model, changed the property type as follow:
public IEnumerable<SelectListItem> States { get; set; }
public int State { get; set; }
Controller action:
IList<StateDTO> s = new List<StateDTO>();
s.Add(new StateDTO() { ID = 1, Name = "CA" });
s.Add(new StateDTO() { ID = 2, Name = "LA" });
s.Add(new StateDTO() { ID = 3, Name = "AR" });
r.State = 3;
r.States = new SelectList(s, "ID", "Name",3);
View is as follow:
<div class="editor-label">
#Html.LabelFor(model => model.State)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.State, Model.States)
#Html.ValidationMessageFor(model => model.State)
</div>
It works...got default selection.
Thank you

How to save selected radio button value in MVC4

I am working in MVC4.In this I am using the following code for radio buttons :
Model :
public class PlatInspHistoryModels
{
public List<RadioButtonItem> RadioButtonList { get; set; }
public string SelectedRadioButton { get; set; }
}
public class RadioButtonItem
{
public string Name { get; set; }
public bool Selected { get; set; }
public string Value { get; set; }
public bool Visible { get; set; }
}
controller :
public ActionResult Index()
{
var viewModel = new PlatInspHistoryModels
{
RadioButtonList = new List<RadioButtonItem>
{
new RadioButtonItem
{
Name = "Topside", Value = "T",Selected = true,Visible = true
},
new RadioButtonItem
{
Name="Underwater", Value = "U",Selected = false,Visible = true
}
}
};
return View(viewModel);
}
View :
#using (Html.BeginForm("Index", "PlatInspHistory", FormMethod.Post, new { id = "form" }))
{
<table cellpadding="4" cellspacing="4">
<tr>
<td>
foreach (Cairs2.Models.RadioButtonItem item in Model.RadioButtonList)
{
#Html.DisplayFor(i => item.Name)
#Html.RadioButton("PlatInspHistoryModels.SelectedRadioButton", item.Value, item.Selected, new { #class = "formCheckbox", tabindex = "1" })
}
</td>
</tr>
</table>
}
Problem :
From the above code I am able to bind radio buttons as a list. But how I can get selected radio value on save event given below :
[HttpPost]
public ActionResult Index(PlatInspHistoryModels model)
{
}
Replace your foreach loop with this with a for loop and use strongly typed helpers:
for (var i = 0; i < Model.RadioButtonList.Count; i++)
{
#Html.DisplayFor(x => x.RadioButtonList[i].Name)
#Html.HiddenFor(x => x.RadioButtonList[i].Name)
#Html.RadioButtonFor(x => x.SelectedRadioButton, Model.RadioButtonList[i].Value, new { #class = "formCheckbox", tabindex = "1" })
}
I am working in MVC5, i have mcqs questions in the form of radio buttons that are randomly fetched from database here is my`[Table("Mcqs")]
public class MCQS
{ [Key]
public int Qid { get; set; }
[Required(ErrorMessage = "Please Enter Skill.")]
public string Skill { get; set; }
[Required(ErrorMessage = "Please Enter Question.")]
public string Question { get; set; }
[Required(ErrorMessage = "Please Enter Level.")]
public string Levels { get; set; }
[Required(ErrorMessage = "Please Enter Options.")]
public string AnsOpt1 { get; set; }
[Required(ErrorMessage = "Please Enter Options.")]
public string AnsOpt2 { get; set; }
[Required(ErrorMessage = "Please Enter Options.")]
public string AnsOpt3 { get; set; }
[Required(ErrorMessage = "Please Enter Options.")]
public string AnsOpt4 { get; set; }
[Required(ErrorMessage = "Please Set Weightage.")]
and controller
public ActionResult Index()
{ return View((from a in ne.Mcqs orderby Guid.NewGuid() select a).Take(2).ToList()); }
and view
#foreach (var item in Model)
{<tr>
<td>
#Html.DisplayFor(modelItem=>item.Qid)</td>
<td> #Html.DisplayFor(modelItem => item.Question)</td> <td>
#Html.RadioButton("skillsq1", new { id = "1"}).
#Html.DisplayFor(modelItem => item.AnsOpt1)</td><td>
#Html.RadioButton("skillsq1", new { id = "2"})
#Html.DisplayFor(modelItem => item.AnsOpt2) </td><td>
#Html.RadioButton("skillsq1", new { id = "3" })
#Html.DisplayFor(modelItem => item.AnsOpt3) </td> <td>
#Html.RadioButton("skillsq1", new { id = "4" })
#Html.DisplayFor(modelItem => item.AnsOpt4) </td> </tr>}
i want to ask that how i get the value of the checked radio button of the shuffled question