I am trying to display a summary error message on a form as well as property level errors.
The property errors get rendered using html.validationmessagefor(model =>...) which works fine.
But when there is one or more validation errors, I want html.ValidationSummary(true) to display the message "Your form is missing some details - see below".
There also might be some server side validation which will occur post submit and will be added with ModelState.AddError.
How can I get a class level dataattribute (presumably using [AttributeUsage(AttributeTargets.Class)]) to display in the summary validation using unobtrusive validation?
Is this what you are looking for:
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
#Html.ValidationSummary("Errors:")
<div>
#Html.EditorFor(model => model.PathToExcel)
#Html.ValidationMessageFor(model => model.PathToExcel)
</div>
<div>
<input type="submit" value="Load" />
</div>
}
this uses 2 ValidationSummary's, one to fill the ValidationMessageFor-fields and one to use a Summary. Summary only works after Submitting.
Related
In a form I have different fields (name, age, ...) and the possibility to upload an image. This I want to realize on a different view. The problem is that the data, that is made so far, are not passed to the controller when I want to change the controller. Here a small example of my code:
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Person</legend>
#Html.EditorFor(model => model.Name)
#Html.EditorFor(model => model.Age)
<img src="#Url.Content(Model.ImagePath)" alt="Image" class="imagePreview" />
<li>
#Html.ActionLink("Upload a pic from you!", "UploadImage", new { model = Model }, null)
#* This is the 'problematic' action *#
</li>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Here the method that is calling the upload controller:
public ActionResult UploadImage(Person model)
{
// properties in the passed model are not set
return RedirectToAction("UploadImage", "UploadImage");
}
How it is possible to get the entered information without using the submit button?
Check out this blog post by Bryan Sampica on asynchronus file uploads with MVC. We just used it for a smooth async file upload experience so we didn't have to leave the page. This solves your problem of how to persist the transient data. If your users are using a modern browser (IE 10+, Chrome, FF, etc...) the progress bars actually show file upload progress. It's fairly easy to setup, but, if you follow the instructions to the letter, does require that you add a webAPI controller to your project.
My Index method renders a Strongly Typed View of type (InitDetails), auto generated code looks like the following:
#ModelType BookingDeamon.InitDetails
#Using Html.BeginForm()
#Html.ValidationSummary(True)
#<fieldset>
<legend>Reservation</legend>
<div class="editor-label">
#Html.LabelFor(Function(model) model.Pickup)
</div>
<div class="editor-field">
#Html.EditorFor(Function(model) model.Pickup)
#Html.ValidationMessageFor(Function(model) model.Pickup)
</div>
<p>
<input type="submit" value="Create" onclick="SubmitMe()" />
</p>
</fieldset>
End Using
On the above form, I want to display a select list box, as i'll be controlling this select list via JQuery to load different contents depending on different things.
I want to be able to deliver the value of that select list box as Pickup value.
when I try to do the following:
#Html.DropDownListFor(Function(model) model.Pickup)
I receive the following error:
Overload resolution failed because no accessible 'DropDownListFor' accepts this number of argument
Is it possible when user clicks on the submit button, instead of taking Pickup (textbox) value to the controller; it takes the value from the dropdownlist box and submit it to the controller?
try like this
#Html.DropDownListFor(ModelType=>Model.Pickup, (IEnumerable<SelectListItem>)ViewData["Pickup"],"--Select--")
in your controller
var Pickup= GetPickupList();
var PickupList= new SelectList(Pickup, "value", "Text", Pickup.DefaultSelectedValueIfAnyNeeded);
ViewData["Pickup"] = PickupList
write a function GetPickupList()
that returns a list of Pickup values.
When I use the following code, I get a friendly error message (as friendly as YSCD's get) telling me I shouldn't use '#', yet when I don't use it, my form declaration renders as literal Razor code, not as the intended HTML elements. What am I doing wrong?
#if (Model.Step == Trocrates.Web.Models.PasswordResetModel.PasswordResetSteps.StartRequest)
{
#using (Html.BeginForm()) { Html.ValidationSummary(true);
<fieldset style="border: 0px;">
<div class="editor-label">
#Html.LabelFor(model => model.UserName);
</div>
<div class="editor-field">
Html.EditorFor(model => model.UserName) Html.ValidationMessageFor(model => model.UserName)'
<input type="submit" value="Log In" />
#Html.ActionLink("Send", "BeginResetPassword", "Account")
</div>
</fieldset>
}
}
Sorry readers, it was originally that less visible open brace glyph on the same line as BeginForm that caused confusion. When I close that things fell back into place.
Did you try removing the # symbol on the using statement? Since you're already in code mode because of the if block the # symbol doesn't mean anything there. That's the only thing off hand that looks out of place to me.
I am trying to implement remote validation using ASP.NET MVC3 unobtrusive javascript.
It seems to work, but I am able to submit my form even if it is not supposed to be valid.
It looks like the validation is not happening fast enough. I am using the ASP.NET development server with the VS 2010 debugger and the remote validation method is not always fired. When I wait a little, the validation happens and I cannot submit the form.
I am starting to think that client-side remote validation is not reliable enough and I maybe should consider using server-side validation just to be sure the correct validations are applied.
Is there a way to fix this?
EDIT:
Like you asked, here are the part of my code relative to the problem.
I will start by taking your advice and use server-side validation to avoid users bypassing my validations.
Model:
[Required(ErrorMessage = "*"), StringLength(50)]
[Remote("EventCategoryNameExists", "EventCategories",
AdditionalFields = "EventCategoryId",
ErrorMessageResourceType = typeof(Messages),
ErrorMessageResourceName = "EventCategoryNameAlreadyExists")]
[LocalizedDisplayName("Name")]
public string Name { get; set; }
View:
<div id="formMain">
#Html.HiddenFor(x => x.EventCategoryId)
<fieldset class="formFieldset">
<legend>#Labels.EventCategoryDetails</legend>
<div class="formFieldsetContent">
<table id="formTable" class="formTable">
<tr>
<td class="formLabelCell" style="width: 90px;">
#Html.LabelFor(x => x.Name) :
</td>
<td class="formInputCell">
#Html.EditorFor(x => x.Name)
#Html.ValidationMessageFor(x => x.Name)
</td>
</tr>
<tr>
<td class="formLabelCell" style="vertical-align: top;">
#Html.LabelFor(x => x.Color) :
</td>
<td class="formInputCell">
#Html.EditorFor(x => x.Color)
#Html.ValidationMessageFor(x => x.Color)
</td>
</tr>
</table>
</div>
</fieldset>
</div>
<div class="formButtons">
<input type="submit" id="btnSave" value="#Labels.Save" class="formButton" />
<input type="button" id="btnCancel" value="#Labels.Cancel" class="formButton" />
</div>
Controller:
public ActionResult EventCategoryNameExists(int eventCategoryId, string name)
{
return Json(!_eventService.EventCategoryNameExists(eventCategoryId, name), JsonRequestBehavior.AllowGet);
}
Client-side validation is never enough. Javascript cannot be counted on to be enabled or correct, plus it can be bypassed by a devious user. But is your client-side validation routine returning a boolean false? If not, the normal submit action will take place regardless.
Your dataannotations are processed on the server side as well - so you are OK as far as that is concerned. The remote validation attribute is not though. You need a custom validation attribute or need to also check this same routine on the server side. Extract out your validation call to a general method that you check in your HttpPost action (and if it fails use ModelState.AddError) and also have your remote validation method all this so and you should be good. Remote validation is still a decent client side feature so I wouldn't completely scrap it if you want that functionality.
As for your specific timing issue - I just did some testing on my remote validation page. I setup fiddler to have breakpoints before requests. I cannot submit my form until I return a response from the server. Try with fiddler and see if you can reproduce it that way. Im curious if something else on your page is stomping out your remote validation. I had an issue with a newer version of jQuery and remote validation. When I defaulted back to the basic MVC3 project it worked just fine - I didn't debug it further then but it was because of version differences.
I've got a custom Editor Template that is essentially:
<div id="control">
<%: Html.DropDownListFor(model => model.Day, Model.Days)%>
<%: Html.DropDownListFor(model => model.Month, Model.Months)%>
<%: Html.DropDownListFor(model => model.Year, Model.Years)%>
</div>
Whilst my validation is successful/fine with this control (ValidationMessageFor works) I have been unable to find how to highlight the control when validation fails (e.g. with a TextBoxFor the textbox border goes red if validation fails)
Does anyone know how I can add this behaviour with a custom editor template please?
Interesting question. If you can detect a validation error, then you should be able to apply the appropriate class. Something like this, substitute in your own field name:
<div id = "control" class="<%=ViewData.ModelState.IsValidField("DateField") ? "" : "validation-error" %>">