The View I have added looks as below and I have used the Range Attribute for Model.
#Model System.ComponentModel.DataAnnotations.RangeAttribute
#{Layout = null;}
#Html.Hidden("IncludedValidators", "RangeAttribute")
<div class="page-header">
<h4>
MinMaxRangeValidator
</h4>
<div>
<span class="icon-remove pull-right"></span>
</div>
</div>
<div class="control-group">
#Html.LabelFor(p => p.Minimum, new { #class = "control-label" })
<div class="controls">
#Html.TextBoxFor(p => p.Minimum, new { #class = "input-medium" })
</div>
</div>
<div class="control-group">
#Html.LabelFor(p => p.Maximum, new { #class = "control-label" })
<div class="controls">
#Html.TextBoxFor(p => p.Maximum, new { #class = "input-medium" })
</div>
</div>
<div class="control-group">
#Html.LabelFor(p => p.ErrorMessage, new { #class = "control-label" })
<div class="controls">
#Html.TextBoxFor(p => p.ErrorMessage, new { #class = "input-medium" })
</div>
</div>
And My controller Looks like:
public ActionResult AddValidator(string validatorType)
{
ValidationAttribute validator = null;
switch (validatorType)
{
case "RequiredAttribute":
validator = new RequiredAttribute();
break;
case "RangeAttribute":
validator = new RangeAttribute(minimum,maximum);
break;
}
}
How do I get the minimum and maximum values here? I have not created a separate method under the controller for each type of validation.
Your inputs need to be wrapped in a form like:
#using (Html.BeginForm())
{
...
}
and your controller action should be receiving the View Model as a parameter:
public ActionResult AddValidator(RangeAttribute rangeAttribute)
{
rangeAttribute.Maximum;
rangeAttribute.Minimum;
}
Related
I have a Telerik UI for ASP.NET Upload control that when the file get uploaded, I also need to pass the selected values of two Telerik UI for ASP.NET DropDownListFor. Everything works except for getting the drop down values in the saveUpload action.
The selfEvaluationId comes across correctly, but the evaluationAreaId and evidenceTypeId both come across as 0. What is my mistake?
View:
#using Kendo.Mvc.UI
#model BE.USATLE.UI.MVC.Areas.Leader.Models.UploadViewModel
<h1>
Add Evidence
</h1>
#Html.HiddenFor(x => x.SelfEvaluationId)
<div class="container h-100">
<div class="row h-100 justify-content-center align-items-center">
<form class="col-3">
<div class="form-group">
#Html.LabelFor(m => m.EvaluationAreaId)
#(Html.Kendo().DropDownListFor(m => m.EvaluationAreas)
.HtmlAttributes(new { style = "width:100%" })
.OptionLabel("Select Evaluation Area...")
.DataTextField("Name")
.DataValueField("EvaluationAreaId")
.BindTo(Model.EvaluationAreas)
)
#Html.ValidationMessageFor(m => m.EvaluationAreaId)
</div>
<div class="form-group">
#Html.LabelFor(m => m.EvidenceTypeId)
#(Html.Kendo().DropDownListFor(m => m.EvidenceTypes)
.HtmlAttributes(new { style = "width:100%" })
.OptionLabel("Select Evidence Type...")
.DataTextField("Name")
.DataValueField("EvidenceTypeId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetEvidenceTypes", "SelfEvaluation")
.Data("filterEvidenceTypes");
})
.ServerFiltering(true);
})
.Enable(false)
.AutoBind(false)
.CascadeFrom("EvaluationAreas")
)
</div>
</form>
</div>
<div class="row h-100 justify-content-center align-items-center">
<form class="col-3">
<div class="form-group">
#(Html.Kendo().Upload()
.Name("files")
.Async(a => a
.Save("SaveUpload", "SelfEvaluation", new {selfEvaluationId = #Model.SelfEvaluationId, evaluationAreaId = #Model.EvaluationAreaId, evidenceTypeId = #Model.EvidenceTypeId})
.AutoUpload(false)
)
)
</div>
</form>
</div>
</div>
<script>
function filterEvidenceTypes() {
return {
evaluationAreaId: $("#EvaluationAreas").val()
};
}
</script>
Controller:
public async Task<ActionResult> SaveUpload(IEnumerable<IFormFile> files, int selfEvaluationId, int evaluationAreaId, int evidenceTypeId)
{
// The Name of the Upload component is "files"
if (files != null)
{
foreach (var file in files)
{
var fileContent = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
// Some browsers send file names with full path.
// We are only interested in the file name.
var fileName = Path.GetFileName(fileContent.FileName.ToString().Trim('"'));
var physicalPath = Path.Combine("D:\\Uploads", fileName);
// The files are not actually saved in this demo
await using (var fileStream = new FileStream(physicalPath, FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
_selfEvaluationAttachmentService.AddSelfEvaluationAttachment(new SelfEvaluationAttachment
{
DocumentName = fileName,
DocumentPath = physicalPath,
SelfEvaluationId = selfEvaluationId,
EvaluationAreaId = evaluationAreaId,
EvidenceTypeId = evidenceTypeId
});
}
}
// Return an empty string to signify success
return RedirectToAction("Edit", new {id = selfEvaluationId});
}
Found it searching Telerik Forums.
You have to pass it as metadata.
So the Upload in the view becomes
<div class="row h-100 justify-content-center align-items-center">
<form class="col-3">
<div class="form-group">
#(Html.Kendo().Upload()
.Name("files")
.Async(a => a
.Save("SaveUpload", "SelfEvaluation")
.AutoUpload(false)
)
.Events(e => e.Upload("onUpload"))
)
</div>
</form>
</div>
With a JS function
function onUpload(e) {
e.data = {
selfEvaluationId: $("#SelfEvaluationId").val(),
evaluationAreaId: $("#EvaluationAreas").val(),
evidenceTypeId: $("#EvidenceTypes").val()
};
}
The submit button doesn't go to the post method in the controller. Help please, I am new to programming in ASP.Net and I am trying to debug why the submit button doesn't go the the post method in the controller.
We also are trying to use web services
Here is the code for the Account/View/Login.cshtml
#using WebApplication3.Models
#model LoginViewModel
#{
ViewBag.Title = "Log in";
}
<h2>#ViewBag.Title.</h2>
<div class="row">
<div class="col-md-8">
<section id="loginForm">
#using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h4>Use a local account to log in.</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.Email, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Password, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.PasswordFor(m => m.Password, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Log in" class="btn btn-default" />
</div>
</div>
<p>
#Html.ActionLink("Register as a new user", "Register")
</p>
#* Enable this once you have account confirmation enabled for password reset functionality
<p>
#Html.ActionLink("Forgot your password?", "ForgotPassword")
</p>*#
}
</section>
</div>
<div class="col-md-4">
<section id="socialLoginForm">
#Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl })
</section>
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Here is the partial code for the controller
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
var RenewalClient = this.RenewalClient.ServiceClient;
bool isValidUser= RenewalClient.ValidateUser(model.Email,model.Password);
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
Your html seems to be fine. It is always good to pass any information using anonymous function as last argument in BeginForm("Login","Account",FormMethod.Post, new {}).
Check whether your controller action is decorated with [HttpPost] attribute because if this attribute is not present on the action method, it will serve only GET request.
First of all i have a register page like this
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<form role="form" action="" method="post" class="login-form">
<div class="form-group">
<div>
#Html.TextBoxFor(model => model.Name, new { #class = "form-username form-control", placeholder = "Name" })
</div>
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.UserName, new { #class = "form-username form-control", placeholder = "User Name" })
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.Email, new { #class = "form-username form-control", placeholder = "Email" })
</div>
<div class="form-group">
#Html.PasswordFor(model => model.Password, new { #class = "form-username form-control", placeholder = "Password" })
</div>
<input type="submit" value="Register" class="btn" />
</form>
}
and when i try register with that page,i register and add account to database.But i want to use this register page render at Main page and use like that but when i do that it doesn't work.
<div class="form-bottom">
#RenderPage("~/Views/User/Register.cshtml")
</div>
and this is the controller code.
public ActionResult Register()
{
return View(new RegisterModel());
}
[HttpPost]
public async Task<ActionResult> Register(RegisterModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var siteContext = new SiteContext();
var user = new User
{
Name = model.Name,
Email = model.Email,
Password=model.Password,
UserName=model.UserName
};
await siteContext.Users.InsertOneAsync(user);
return RedirectToAction("Profile", "MainPage");
}
To be honest the whole view is a bit of a mess when you use Html.BeginForm() you don't need another form inside that. Your view should look like:
#using (Html.BeginForm("{Action}", "{Controller}", FormMethod.Post, new { #class = "login-form"}))
{
#Html.AntiForgeryToken()
<div class="form-group">
<div>
#Html.TextBoxFor(model => model.Name, new { #class = "form-username form-control", placeholder = "Name" })
</div>
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.UserName, new { #class = "form-username form-control", placeholder = "User Name" })
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.Email, new { #class = "form-username form-control", placeholder = "Email" })
</div>
<div class="form-group">
#Html.PasswordFor(model => model.Password, new { #class = "form-username form-control", placeholder = "Password" })
</div>
<input type="submit" value="Register" class="btn" />
}
You need to replace {Action} with the name of the action, Register. Also replace {Controller} with the name of the controller.
Some useful documentation.
I have to make a ASP.NET MVC 4 Page which contains Customer details.
One form I have to create in which I have to perform Customer Create, Update and Delete.
The different fields are..
1) Customer ID
2) Customer Name
3) Customer Image
4) Customer Address
Now, I am confused with Customer Image. How to store Image in database and how to display it in Gridview from database. Please solve my problem as it's very important for me..
As #LajosArpad said save image as file and only save path of the image in database.
Here is view for creating customer
<div class="box box-primary">
#using (Html.BeginForm("Create", "Customer", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal box-body">
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Address, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Image</label>
<div class="col-md-10">
<input class="form-control" name="image" type="file" />
</div>
</div>
</div>
<div class="box-footer">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
}
</div>
And controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = "Id")] Customer customer, HttpPostedFileBase image)
{
if (ModelState.IsValid)
{
if (image != null && image.ContentLength > 0)
{
var filePath = GetFilePath(image.FileName);
image.SaveAs(filePath);
customer.ImageUrl = "~/images/upload/" + Path.GetFileName(filePath);
}
// Save customer to database
return RedirectToAction("Index");
}
return View(news);
}
// Get absolute path for saving image and check it does not exist
public static string GetFilePath(string fileName)
{
var targetFolder = System.Web.Hosting.HostingEnvironment.MapPath("~/images/upload/");
var targetPath = Path.Combine(targetFolder, fileName);
if (File.Exists(targetPath))
{
var name = Path.GetFileNameWithoutExtension(fileName);
name = name + "-" + (new Random()).Next();
var extension = Path.GetExtension(fileName);
name = name + extension;
GetFilePath(name);
}
return targetPath;
}
You store the image as a file and you store the path of the image in the database. If I were you I would generate the filenames instead of using the original filenames to make sure they are not duplicated. So you do not need to store the images in the database, you can store them as separate files.
I have the following PartialView
#model Token.Creator.Site.Models.Customer
#{
var cusModel = new Token.Creator.Site.Models.CustomerModel();
ViewContext.FormContext = new FormContext();
HtmlHelper.ClientValidationEnabled = true;
HtmlHelper.UnobtrusiveJavaScriptEnabled = true;
}
<div class="modal fade" id="customereditmodal" tabindex="-1" role="dialog" aria-hidden="true">
#using (Ajax.BeginForm("EditCustomer", "Customer", new AjaxOptions(), new {
#class = "modal-dialog form-horizontal",
id = "upload_s0pin"
})) {
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
#if (string.IsNullOrEmpty(Model.Companyname)) {
<h4 class="modal-title">#Model.Gender.Type #Model.Title #Model.Firstname #Model.Lastname</h4>
} else {
<h4 class="modal-title">#Model.Companyname</h4>
}
</div>
<div class="modal-body">
#Html.ValidationSummary()
<div class="form-group">
#Html.LabelFor(cus => cus.Companyname, "Firmenname", new { #class = "col-lg-3 control-label" })
<div class="col-lg-9">
#Html.TextBoxFor(cus => cus.Companyname, new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(cus => cus.Companyname);
</div>
<h4>Ansprechpartner</h4>
<div class="form-group">
#Html.LabelFor(cus => cus.Gender, "Anrede*", new { #class = "col-lg-3 control-label" })
<div class="col-lg-9">
#Html.DropDownListFor(cus => cus.Gender, new SelectList(cusModel.Gender.ToList(), cusModel.Gender), new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(cus => cus.Title, "Titel", new { #class = "col-lg-3 control-label" })
<div class="col-lg-9">
#Html.TextBoxFor(cus => cus.Title, new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(cus => cus.Title);
</div>
<div class="form-group">
#Html.LabelFor(cus => cus.Firstname, "Vorname*", new { #class = "col-lg-3 control-label" })
<div class="col-lg-9">
#Html.TextBoxFor(cus => cus.Firstname, new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(cus => cus.Firstname);
</div>
<div class="form-group">
#Html.LabelFor(cus => cus.Lastname, "Nachname*", new { #class = "col-lg-3 control-label" })
<div class="col-lg-9">
#Html.TextBoxFor(cus => cus.Lastname, new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(cus => cus.Lastname);
</div>
<div class="form-group">
#Html.LabelFor(cus => cus.Emailaddress, "Emailadresse*", new { #class = "col-lg-3 control-label" })
<div class="col-lg-9">
#Html.TextBoxFor(cus => cus.Emailaddress, new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(cus => cus.Emailaddress);
</div>
<h4>Adresse</h4>
<div class="form-group">
#Html.LabelFor(cus => cus.Street, "Straße und Hausnummer*", new { #class = "col-lg-3 control-label" })
<div class="col-lg-9">
#Html.TextBoxFor(cus => cus.Street, new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(cus => cus.Street);
</div>
<div class="form-group">
#Html.LabelFor(cus => cus.ZIPCode, "Postleitzahl*", new { #class = "col-lg-3 control-label" })
<div class="col-lg-9">
#Html.TextBoxFor(cus => cus.ZIPCode, new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(cus => cus.ZIPCode);
</div>
<div class="form-group">
#Html.LabelFor(cus => cus.Town, "Stadt*", new { #class = "col-lg-3 control-label" })
<div class="col-lg-9">
#Html.TextBoxFor(cus => cus.Town, new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(cus => cus.Town);
</div>
<div class="form-group">
#Html.LabelFor(cus => cus.Country, "Land*", new { #class = "col-lg-3 control-label" })
<div class="col-lg-9">
#Html.TextBoxFor(cus => cus.Country, new { #class = "form-control" })
</div>
#Html.ValidationMessageFor(cus => cus.Country);
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Schließen</button>
<input type="submit" class="btn btn-primary" value="Speichern" />
</div>
</div>
</div>
}
</div>
The modelclass is autogenerated by EF. And I extend it to apply validation attributes.
[MetadataType(typeof(CustomerMetadata))]
public partial class Customer {
private class CustomerMetadata {
[Required(ErrorMessage = "Geben Sie einen Vornamen ein")]
public object Firstname;
[Required(ErrorMessage = "Geben Sie einen Nachnamen ein")]
public object Lastname;
[Required(ErrorMessage = "Geben Sie eine Straße ein")]
public object Street;
[Required(ErrorMessage = "Geben Sie eine Postleitzahl ein")]
public object ZIPCode;
[Required(ErrorMessage = "Geben Sie eine Stadt ein")]
public object Town;
[Required(ErrorMessage = "Geben Sie ein Land ein")]
public object Country;
[Required]
[DataType(DataType.EmailAddress, ErrorMessage = "Bitte geben Sie eine gültige Emailadresse ein")]
public object Emailaddress;
}
}
But the validation doesn't work. What am I doing wrong?
EDIT: The partial view is loaded by AJAX
I finally found a solution, I just needed to add the following script in the partial view:
<script type="text/javascript">
$(document).ready(function () {
$.validator.unobtrusive.parse("#customereditmodal > form");
});
</script>
Where customereditmodal is the id of the div.
Here is the link to the solution http://forums.asp.net/post/4299121.aspx
If you want just validation, ensure that your EditCustomer action method has this structure:
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid)
{
// It's ok! do what you need
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
return View(model);
}
If you want unobtrusive validation - if something is wrong, form won't be posted - you need to enable it in web.config:
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
Install Jquery Validation and Microsoft JQuery Unobtrusive Validation nuget packages.
And finally, add the following scripts to your main layout (or register them by bundles):
<script src="~/Scripts/jquery.validate.min.js")></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js")></script>
Please note that the order of including above scripts are important and if add in the different order, unobtrusive validation doesn't work...