Have to double submit when using Remote attribute based validation - validation

We have a field on our model which has a [Remote] attribute. When we store that field on a Hidden form element and then try to submit that form we have to click the submit button twice. Also interesting is that the 2nd time we click it no remote validation is occurring (so says Fiddler).
Thoughts?

Unable to repro. If the hidden field is decorated with the Remote attribute you won't be able to submit the form no matter how many times you click on the submit button if the remote function sends false.
For example:
Model:
public class MyViewModel
{
[HiddenInput(DisplayValue = false)]
[Remote("Check", "Home")]
public string Id { get; set; }
[Required]
public string Name { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel
{
Id = "1"
});
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
public ActionResult Check(string Id)
{
return Json(Id == "2", JsonRequestBehavior.AllowGet);
}
}
View:
#model AppName.Models.MyViewModel
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.EditorForModel()
<input type="submit" value="OK" />
}
Because the remote function will always return false this form cannot be submitted. If the remote function returns true a single click would be enough to submit it assuming of course that the other validation passed.

Related

Validation in mvc4 not taking place

MODEL
public class SearchTerm
{
[Required(ErrorMessage="please enter")]
public string SearchTrm { get; set; }
}
View
#using (#Html.BeginForm())
{
#Html.ValidationSummary();
#Html.AntiForgeryToken();
....
#Html.TextBoxFor(m=>m.SearchTrm)</span>
<input type="submit" value="Search"/>
#Html.ValidationMessageFor(m=>m.SearchTrm)
#using (Html.BeginForm("Search","Home"))
{
#Html.DropDownList("SelectedFieldId", new SelectList(Model.Fields, "FieldID", "NiceName", Model.SelectedFieldId));
}
}
controller
[HttpPost]
public ActionResult Search(SearchTerm Model)
{
// some code here....
}
When i click a empty search I want the validation message to take place but instead page is getting postback and i am having NullReferenceException
Mention the script name, #section scripts { ...} and check whether jqueryval has 2 files - ~/scripts/jquery.validate.min.js","~/scripts/jquery.validate.unobtrusive.min.js","~/scripts

How can I save the data when I return to my action and retrieve it?

I have a class and create an instance and fill a property in my index but when I push the submit button in my view and return again to my index action the property of my class is null.
How can I save the data when I return to my action and retrieve it? Is it possible?
I used viewbag and viewdata in my index and fill theme but when returned to index action again all of theme were null :(
public class myclass
{
public string tp { get; set; }
}
public class HomeController : Controller
{
//
// GET: /Home/
myclass myc = new myclass();
public ActionResult Index()
{
myc.tp = "abc";
return View(myc);
}
}
View:
#model MvcApplication2.Controllers.myclass
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
#using (Html.BeginForm())
{
<input id="Submit1" type="submit" value="submit" />
}
</body>
</html>
simply use either GET or POST method in your Controller according to your form method like,
[HttpGet]
public ActionResult Index(string id)
{
myc.tp = id;
return View(myc);
}
In your HttpPost you can get the model and see it's properties if you provided input fields for the properties in your view.
[HttpPost]
public ActionResult Index(myclass myc)
{
//check the myc properties here
return View(myc);
}
Then in your View:
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.tp)

MVC3 Empty model on post

I have model which has data.
The i create form with only on button, i don't use the model's data in there.
When i press the button it goes correctly to the HTTPPOST method but the model is completely empty.
HTML:
#model ViewModels.RequestDeletionViewObject
#using (Html.BeginForm())
{
<input type="submit" value="submit"/>
}
The RequestDeletionViewObject:
public class RequestDeletionViewObject : ViewModelBase
{
public TreeGridData NodeFilespacesData { get; set; }
public Dictionary<long, string> EmailList{ get; set; }
}
Controller:
public ActionResult RequestDel()
{
return View(_businessLogic.GetData());
}
[HttpPost]
public ActionResult RequestDel(RequestDeletionViewObject model)
{
return View(_businessLogic.GetData());
}
Please help me, I have done similar thing in many other places and it worked there, but not here, i don't know what am i missing?
Thanks
You don't have any form controls in your form. A form will only post data that is in a form control (textbox, hidden field, checkbox, etc..)
It doesn't matter what data you send to the view, it will only post back data in form controls within the form.

How to Implement MVC3 Model URL Validation?

I've successfully implemented client side validation to require input in my textbox. However, I want to evaluate the contents of the textbox to see if it is a well formed URL. Here's what I have thus far:
Index.cshtml:
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery-1.5.1.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery.validate.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")"></script>
#model Ticket911.Models.ValidationModel
#{
ViewBag.Title = "Home Page";
}
<h2>#ViewBag.Message</h2>
#using (Ajax.BeginForm("Form", new AjaxOptions() { UpdateTargetId = "FormContainer" , OnSuccess = "$.validator.unobtrusive.parse('form');" }))
{
<p>
Error Message: #Html.ValidationMessageFor(m => m.URL)
</p>
<p>
#Html.LabelFor(m =>m.URL):
#Html.EditorFor(m => m.URL)
</p>
<input type="submit" value="Submit" />
ValidationModel:
public class ValidURLAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
return (value != null);
}
}
public class ValidationModel
{
[Required]
public string URL {get; set;}
}
How do I ensure that the model URL validation occurs? When the Submit button is clicked, what must be done to navigate to the URL entered into the textbox?
Thanks much:)
good way is to implement your attribute for next use in mvc projects. like this:
public class UrlAttribute : RegularExpressionAttribute
{
public UrlAttribute() : base(#"^http(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$")
{}
}
so on the model:
[Url(ErrorMessage = "URL format is wrong!")]
public string BlogAddress { get; set; }
You can do it wtih DataAnnotations
public class ValidationModel
{
[Required]
[RegularExpression(#"^http(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$", ErrorMessage = "URL format is wrong")]
public string URL {get; set;}
}
And in your HTTPPost Action method, You can call the ModelState.IsValid property which will check the Validations for you.
[HttpPost]
public ActionResult Save(ValidationModel model)
{
if(ModelState.IsValid)
{
//Save or whatever
}
return View(model);
}

jquery client side validation only works at certain field (doesnt work at Required field)

I am implementing client side validation in mvc3.
I got my form showing via jquery dialog, and submit via ajax post
I am not sure is it necessary, but i created a partial class in my Model to customize the validation:
[MetadataType(typeof (FoodMetaData))]
public partial class FOOD
{
[Bind(Exclude="FoodID")]
public class FoodMetaData
{
[ScaffoldColumn(false)]
public object FoodID { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Please enter a name")]
public object FoodName { get; set; }
[Range(1, 200, ErrorMessage = "Please enter a valid amount")]
public object FoodAmount { get; set; }
public object StorageDate { get; set; }
public object ExpiryDate { get; set; }
Currently I only get the validation shown at the amount field if i enter a string or a number out of the range. However, If i empty the Name field, nothing happen.
This is my first try on client side validation and got no idea what is happening. Can anyone please give me some advice??
Appreciate any help, thanks...
Here's an example of how you could implement a partial form with jQuery dialog.
As always start with a view model:
public class MyViewModel
{
[Required]
public string SomeProperty { get; set; }
}
then a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Edit()
{
return PartialView(new MyViewModel());
}
[HttpPost]
public ActionResult Edit(MyViewModel model)
{
if (!ModelState.IsValid)
{
return PartialView(model);
}
// TODO: validation passed => process the model and return a JSON success
return Json(true);
}
}
and then a ~/Views/Home/Index.cshtml view which will contain only a link to the dialog:
#Html.ActionLink("click me for dialog", "edit", null, new { id = "showDialog" })
<div id="dialog"></div>
and a ~/Views/Home/Edit.cstml partial which will contain the form that we want to be shown in the dialog:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.LabelFor(x => x.SomeProperty)
#Html.EditorFor(x => x.SomeProperty)
#Html.ValidationMessageFor(x => x.SomeProperty)
<button type="submit">Save</button>
}
All that is left now is to wire up. So we import the necessary scripts:
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
and then write our own to make the dialog live:
$(function () {
$('#showDialog').click(function () {
$('#dialog').dialog().load(this.href, function (result) {
ajaxify(this);
});
return false;
});
});
function ajaxify(dialog) {
// we need to parse client validation rules
// because the form was injected into the DOM later as
// part of the dialog. It was not present initially
// See here for more info: http://weblogs.asp.net/imranbaloch/archive/2011/03/05/unobtrusive-client-side-validation-with-dynamic-contents-in-asp-net-mvc.aspx
$.validator.unobtrusive.parse($(dialog));
// AJAXify the form
$('form', dialog).submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result === true) {
// The controller action returned a JSON result
// inidicating the success
alert('thank you for submitting');
$(dialog).dialog('close');
} else {
// there was a validation error => we refresh the dialog
// and reajaxify it as we have now modified the DOM
dialog.html(result);
ajaxify(dialog);
}
}
});
return false;
});
}
Now you could adapt this to any view model you want with any editor templates and validation rules.
I just found out that jquery client side validation is only triggered after 1st form submission after i gone through the example here: http://weblogs.asp.net/imranbaloch/archive/2011/04/30/eagerly-performing-asp-net-mvc-3-unobtrusive-client-side-validation.aspx
A great one! It helps to solve my weird problem by editing the jquery.validate.unobtrusive(.min).js file by this:
options: { // options structure passed to jQuery Validate's validate() method
errorClass: "input-validation-error",
errorElement: "span",
errorPlacement: $.proxy(onError, form),
invalidHandler: $.proxy(onErrors, form),
messages: {},
rules: {},
success: $.proxy(onSuccess, form),
onfocusout: function (element) { $(element).valid(); }
}
Thanks for every help!

Resources