MVC 3 + $.ajax - response seems to be caching output from partial view - asp.net-mvc-3

I must be missing something, silly, but here is the problem.
I have a Create action on the Transactions controller. The Create.cshtml uses jQuery to post the form to the server using a call to $.ajax. Debugging shows that everything arrives on the server as expected. I use the form data to update a record: this works fine too. I then return a partial view, passing a model to the view with default data. I can debug and verify that the model is passing nulls and 0s, ie, the default data for my model.
Problem is, what gets sent back to the browser in the response is the old data...!
I can see no reason why. Hopefully, you can...
Note: I am not using any form of output cache.
EDIT 1:
The caching is not happening in the browser. The reason I say that is that I can see in Firebug the response of the call to the AjaxCreate Action. I can also see this in Fiddler.
EDIT 2:
If you look at the code for the Partial View, you will see that each dropdownlist or textbox has the value of #Model.Transaction.[Property] printed out beside it. This, bizarrely, shows the correct value, ie, the defaults for my Transaction object, but the dropdownlists and text boxes stick with the values that were posted to the server rather than the default values for the property each one is supposed to render.
EDIT 3:
I have included the following image, so you can see the values printed to the right of each control that are being passed in. And yet the controls reflect the old data posted to the server in the previous $.ajax call. (The comment shows a date time at the moment of creating the view model, that way I could see things updating).
EDIT 4:
I have found that replacing #Html.EditorFor(...) (see view code below) with #Html.TextBox helpers removes the problem. So, what seems to be happening is that the EditorFor helpers are causing the problem. Why? I have no idea, but will post another, more specific question.
Code and markup as follows:
jQuery:
$(document).ready(function () {
$('input[name="nextRecord"]').live('click', function () {
var theForm = $(this).closest('form');
if ((theForm).valid()) {
var buttonText = $(this).val();
var action = "/input/Transactions/AjaxCreate/";
if (buttonText === "Reset") {
clearForm(theForm);
}
else {
var targetElement = $('#CreateDiv');
var _data = theForm.serialize() + '&nextRecord=' + $(this).val();
$.ajax({
url: action,
data: _data,
cache: 'false',
type: 'POST',
dataType: 'html',
success: function (html) {
$(targetElement).html(html);
createDatePickers(targetElement);
jQuery.validator.unobtrusive.parse(targetElement);
}
});
}
}
return false;
});
});
Partial View:
#model FlatAdmin.Domain.ViewModels.TransactionViewModel
#* This partial view defines form fields that will appear when creating and editing entities *#
<div class="editor-label">
Fecha
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Transaction.TransactionDate, new { #class = "date-picker" })
#Html.ValidationMessageFor(model => model.Transaction.TransactionDate) #Model.Transaction.TransactionDate.ToString()
</div>
<div class="editor-label">
Origen:
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Transaction.IdFrom, ((IEnumerable<FlatAdmin.Domain.Entities.Account>)Model.FromAccounts).Select(option => new SelectListItem
{
Text = (option == null ? "None" : option.AccountName),
Value = option.AccountId.ToString(),
Selected = (Model != null) && (option.AccountId == Model.Transaction.IdFrom)
}), "Choose...")
#Html.ValidationMessageFor(model => model.Transaction.IdFrom)#Model.Transaction.IdFrom
</div>
<div class="editor-label">
Destino:
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Transaction.IdTo, ((IEnumerable<FlatAdmin.Domain.Entities.Account>)Model.ToAccounts).Select(option => new SelectListItem
{
Text = (option == null ? "None" : option.AccountName),
Value = option.AccountId.ToString(),
Selected = (Model != null) && (option.AccountId == Model.Transaction.IdTo)
}), "Choose...")
#Html.ValidationMessageFor(model => model.Transaction.IdTo)#Model.Transaction.IdTo
</div>
<div class="editor-label">
Monto
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Transaction.IdCurrency, ((IEnumerable<FlatAdmin.Domain.Entities.Currency>)Model.AllCurrencies).Select(option => new SelectListItem
{
Text = (option == null ? "None" : option.CurrencyName),
Value = option.CurrencyId.ToString(),
Selected = (Model != null) && (option.CurrencyId == Model.Transaction.IdCurrency)
}))
#Html.EditorFor(model => model.Transaction.Amount)
#Html.ValidationMessageFor(model => model.Transaction.Amount) #Model.Transaction.Amount
</div>
<div class="editor-label">
Comentario
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Transaction.Comment)
#Html.ValidationMessageFor(model => model.Transaction.Comment)#Model.Transaction.Comment
</div>
View:
#model FlatAdmin.Domain.ViewModels.TransactionViewModel
#using FlatAdmin.Domain.Entities
#{
ViewBag.Title = "Nueva Transaccion";
}
<h2>#ViewBag.Title</h2>
<div>
#Html.ActionLink("<< Lista de Transacciones", "Index")
</div>
<br />
<div id="InputPanel">
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Elegir Actividad</legend>
<div class="editor-field">
#Html.DropDownListFor(model => model.Transaction.IdCostCentre, ((IEnumerable<FlatAdmin.Domain.Entities.CostCentre>)Model.AllCostCentres).Select(option => new SelectListItem
{
Text = (option == null ? "None" : option.Name),
Value = option.CostCentreId.ToString(),
Selected = (Model != null) && (option.CostCentreId == Model.Transaction.IdFrom)
}), "Actividades...")
</div>
</fieldset>
<fieldset>
<legend>Transaccion</legend>
<div id="CreateDiv">
#Html.Partial("_Create", Model)
</div>
<p>
<input type="submit" name="nextRecord" value="Proxima Transaccion >>" />
</p>
<p>
...o sino, para guardar y volver a la lista de transacciones:<br /><input type="submit" value="Guardar" />
</p>
</fieldset>
}
</div>
Controller Action:
[HttpPost]
public virtual ActionResult AjaxCreate(Transaction transaction)
{
if (ModelState.IsValid)
{
service.InsertOrUpdate(transaction);
service.Save();
}
service.ChosenCostCentreId = transaction.IdCostCentre;
TransactionViewModel viewModel = new TransactionViewModel();
viewModel.Transaction = new Transaction();
viewModel.CostCentre = service.ChosenCostCentre;
viewModel.AllCostCentres = service.AllCostCentres;
viewModel.AllCurrencies = service.AllCurrencies;
viewModel.FromAccounts = service.FromAccounts;
viewModel.ToAccounts = service.ToAccounts;
return PartialView("_Create", viewModel);
}

#Darin Dimitrov came up with the answer in a related thread.
Essentially, the HtmlHelpers such as Html.EditorFor, Html.TextBoxFor, etc, check first in the ModelState for existing values, and ONLY then in the Model.
As a result, I needed a call to:
ModelState.Clear();
Ignorance is so painful.

Try explicitly setting the outputcache duration to 0 on your controller action.
I think the browser isn't supposed to cache POSTs but it seems to still do that sometimes.

Related

MVC 4 Updating a partial view from another partial view using Ajax.BeginForm()

I have a comment section set up on one of my pages. The parent view has a partial view which shows the comments for that ID and gives the option to display another partial view to post a comment. When someone post a comment I want the first partial view within the parent to refresh displaying the new comment.
Currently when you click Post Comment, the AddComment method is called and added to the database. I get an error saying that I am passing the wrong type of model to the view. It seems to be trying to pass the return value to my AddComment partial view instead of injecting it into Partent View Div.
Parent View
#model QIEducationWebApp.Models.Course
#{
ViewBag.Title = "Course Details";
}
<h1 class="page-header">#ViewBag.Title</h1>
Javascript is here
.
.
.
<table class="table">
DETAILS HERE
</table>
<ul id="view-options">
<li>#Html.ActionLink("Back to Courses", "Index", "Course")</li>
</ul>
<input type="button" id="View" class="ShowComment" value="Show Comments"/>
<div id="CommentSection"/>
Partial View to view comments
Javascript is here
.
.
.
<div class="CommentSection">
#foreach (var item in Model)
{
<div class="Comment">
<div class="CommentText">
#Html.DisplayFor(modelItem => item.CommentText)
</div>
<div class="CommentSep">
<span class="Commenter">#Html.DisplayFor(modelItem => item.UserName)</span> - <span class="CommentDate">#Html.DisplayFor(modelItem => item.CommentDate)</span>
</div>
</div>
}
<input type="button" id="Post" class="AddComment" value="Add a Comment"/>
<br />
<br />
</div>
<div id="AddComment" />
<br />
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("ViewComments",
new { courseID = #ViewBag.courseID, page }),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(
new PagedListRenderOptions { MaximumPageNumbersToDisplay = 5, DisplayLinkToFirstPage = PagedListDisplayMode.IfNeeded,
DisplayLinkToLastPage = PagedListDisplayMode.IfNeeded },
new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "CommentSection" }))
Method behind the is partial view
public PartialViewResult ViewComments(int courseID, int? page = 1)
{
ViewBag.courseID = courseID;
var coursecomments = db.CourseComments.Where(cc => cc.CourseID == courseID);
int pageSize = 10;
int pageNumber = (page ?? 1);
return PartialView(coursecomments.OrderByDescending(cc => cc.CommentDate).ToPagedList(pageNumber, pageSize));
}
Partial to Post Comment
Javascript is here
.
.
.
#using (Ajax.BeginForm("AddComment", "CourseComment", new { courseID = #ViewBag.courseID, userName = #User.Identity.Name },
new AjaxOptions { UpdateTargetId = "CommentSection" }))
{
#Html.ValidationSummary(true)
<div class="NewComment">
<div class="editor-field">
#Html.TextAreaFor(model => model.CommentText, new { maxLength = 500 })
#Html.ValidationMessageFor(model => model.CommentText)
</div>
<input type="submit" class="PostComment" value="Post Comment" />
<div id="Counter" class="CommentCounter"/>
</div>
}
Controller method linked to the Post Comment Ajax.BeginForm()
public PartialViewResult AddComment(CourseComment coursecomment, int courseID, String userName)
{
coursecomment.CommentDate = System.DateTime.Now;
coursecomment.CourseID = courseID;
coursecomment.UserName = userName;
if (ModelState.IsValid)
{
db.CourseComments.AddObject(coursecomment);
db.SaveChanges();
}
ViewBag.courseID = courseID;
return ViewComments(courseID);
}
Adding pictures
Details
After selecting View Comments button
After selecting Add Comment
After Posting the the comment I want the list of Comments to refresh displaying the newly added Comment. Like So
For now I have it changed. I wanted to the comments section to be hidden until the show comments was clicked. Then after posting a comment on the comments section was refreshed, but I couldn't get that to work. So just reloading the whole page will refresh the comments section, but make it hidden at that time. I made it so that the comments section shows by default without the option to hide it. So unless anyone can figure out a way to get it to work how I wanted, this works for now.

Why does Unobtrusive Ajax require a layout page (returning a partial view doesn't work)?

While creating a custom plugin, that Ajaxifies any forms that are not already Ajaxified by unobtrusive Ajax, I noticed that my partial/layout code failed to display on post-back with a normal Unobtrusive Ajax form:
For my other partial-update plugins, I conditionally render pages as partial (for ajax requests) or full with layout (for normal requests) like this:
public ActionResult AjaxForm()
{
if (!Request.IsAjaxRequest())
{
ViewBag.Layout = "_Layout.cshtml";
}
return PartialView();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AjaxForm(AjaxFormModel model)
{
if (!Request.IsAjaxRequest())
{
ViewBag.Layout = "_Layout.cshtml";
}
if (ModelState.IsValid)
{
return PartialView("Success", model);
}
return PartialView(model);
}
When it came to testing a normal unobtrusive Ajax form, I used this test view, which updates just its own element UpdateTargetId="FormPanel":
#using (Ajax.BeginForm("AjaxForm", null, new AjaxOptions() { UpdateTargetId = "FormPanel" }, new { id = "FormPanel" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<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" } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.AddressLine, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.AddressLine, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
If I remove the test if (!Request.IsAjaxRequest()), and return the full page with master page/layout, it renders the result just fine where the form was.
Fiddler shows the "success" view is returned in either case, but it does not do anything without the layout present.
Q. What is it in a masterpage/layout that unobtrusive Ajax requires in order to extract content and replace the specified element
Update:
To make things worse it actually works correctly the first time, but not if I ajax load the same form again.
A: Forms must have unique IDs!
There are loads of issues about unique IDs on SO, which browsers generally cope with, but the one you cannot ever break is having two forms loaded with the same id. Only one is visible to JavaScript/jQuery!
My problem was caused by a duplicate form ID. You should not insert the result page back in to the form itself (leaving the form element intact).
When I reloaded the original form, dynamically in a slideshow-style control, I wound up with duplicate form ID's.
This meant Unobtrusive Ajax could only see the first form in the DOM!
Solution (do not set Ajax forms to update themselves):
Set UpdateTargetId to an element above the form, never the form itself if you load panels dynamically.
Fix to my example view (surround form with a target panel):
<div id="FormPanel">
#using (Ajax.BeginForm("AjaxForm", new AjaxOptions() { UpdateTargetId = "FormPanel" }))

Using Jquery to collect data, use data to get a Partial View from the controller, and append the passed information to the end of a page

I am attempting to append a partial view to the end of my 'currently displayed page' when a selection from a dropdown menu is chosen.
This is the dropdown from my view:
<div>
#Html.DropDownListFor(x => x.DropDownInfo, Model.Info, "DefaultSelection")
#Html.ValidationMessageFor(model => model.Courses)
</div>
I am in most need here in my Jquery. What do I need to do to append the PartialView that is returned by my controller (pasted below)? My current Jquery:
$(document).ready(function() {
$("#DropDownInfo").change(function() {
var strSelected = "";
$("#DropDownInfo option:selected").each(function() {
strSelected += $(this)[0].value;
});
var url = "/Controller/PreFillMethod/?MethodString=" + strSelected;
$.post(url, function(data) {
//*****
// Assuming everything else is correct,
// what do I do here to have my partial view returned
// at the end of the currently displayed page?
//*****
});
});
});
This is the part of my controller that replies with a PartialView (I want the string from the dropdown selection to be passed into this controller to ultimately be used to fill in a field in the PartialView's form) :
public PartialViewResult PreFillCourse(string selectedFromDropDown)
{
ViewBag.selectedString = selectedFromDropDown;
MyViewModel preFill = new MyViewModel
{
Title = selectedFromDropDown, // I am using this to pre-fill a field in a form
};
return PartialView("_PartialViewForm", preFill);
}
The Partial View (in the case that it matters):
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>CourseTemplates</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
I am open to suggestions if I am approaching the situation entirely incorrectly.
My goal is to have a user select a 'template' from the drop-down menu and have that template's data autopopulate into a form below the drop-down.
My Jquery is very rough - I am using this post as a guide
you should have a div in your view
<div id ="divToAppend">
</div>
then append the partial view to your div
$(document).ready(function() {
$("#DropDownInfo").change(function() {
var strSelected = "";
$("#DropDownInfo option:selected").each(function() {
strSelected += $(this)[0].value;
});
var url = "/Controller/PreFillMethod/?MethodString=" + strSelected;
$.post(url, function(data) {
$('#divToAppend').html(data);
//*****
// Assuming everything else is correct,
// what do I do here to have my partial view returned
// at the end of the currently displayed page?
//*****
});
});
});

Using #Html.HiddenFor in MVC3

I'm having lots of troubles.
I think that MVC just hates me.
1st. I'm using Linq and the model is automagically generated. I just completed the properties I need with the [Required] tag/directives.
2nd. I have a "Big Model" that joins two of the models.
Like is explained here -> Multiple models in a view
When I try to postback a view with a model that has those properties like nulls, is has the ModelState.isvalid == false. I think that is obvious because I set the [Required] to some of the properties that the model needs.
And here comes the thing that brought me here.
3rd. When I'm trying to use #Html.HiddenFor(...) my page won't postback.
If I use, let's say, 3 HiddenFor, the page does PostBack, but if I use 10 HiddenFor, the page just stand still. It does not go anywhere.
I've tried to do everything that is within my range of knowledge (very limited, I'm really new at MVC).
I've tried to bring to the view those properties and showing them up as if it were a "Detail View". Didn't succeed.
I've tried to set the #HiddenFor(model => model.Client). In the Action is passed as null.
I've tried to use these tons of HiddenFor.
I've tried to pass just an ID in the hidden (ClientID) and retrieve the object from the database, but the ModelState will not "update" its status once inside the action.
Why am I doing this?
I'm doing this because I need the pages to display the "Required Field Message" when a box isn't filled, hence, forbiding the page to postback without the data.
My database is fine, and those fields are "Not null", so, I can just remove the [Required] from the properties, but I would lose the "Required Field Message" (in addition to the PostBack that is the thing that I'm trying to avoid).
If anyone has the answer or an answer or whatever, please, post it... I'm about to shoot my head out xD
Thanks in advance...
PS: Sorry about my english... I know that it's not good (or even regular).
View
#model PruebaMVC.Models.OperacionModel
<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>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Operación de Venta</legend>
#Html.HiddenFor(model => model.INMUEBLE)
#*#Html.HiddenFor(model => model.INMUEBLE.Direccion)*#
#*#Html.HiddenFor(model => model.INMUEBLE.Localidad)*#
#*#Html.HiddenFor(model => model.INMUEBLE.Ciudad)*#
#*#Html.HiddenFor(model => model.INMUEBLE.Caracteristicas)*#
#*#Html.HiddenFor(model => model.INMUEBLE.PrecioVenta)*#
#*#Html.HiddenFor(model => model.INMUEBLE.CLIENTE.IDCliente)*#
<div class="editor-label">
#Html.LabelFor(model => model.OPERACION.CLIENTE1.Nombre, "Nombre del Comprador")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.OPERACION.CLIENTE1.Nombre)
#Html.ValidationMessageFor(model => model.OPERACION.CLIENTE1.Nombre)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.OPERACION.CLIENTE1.Apellido, "Apellido del Comprador")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.OPERACION.CLIENTE1.Apellido)
#Html.ValidationMessageFor(model => model.OPERACION.CLIENTE1.Apellido)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.OPERACION.CLIENTE1.FechaNacimiento, "Fecha de Nacimiento del Comprador")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.OPERACION.CLIENTE1.FechaNacimiento)
#Html.ValidationMessageFor(model => model.OPERACION.CLIENTE1.FechaNacimiento)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.OPERACION.CLIENTE1.DNI, "DNI del Comprador")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.OPERACION.CLIENTE1.DNI)
#Html.ValidationMessageFor(model => model.OPERACION.CLIENTE1.DNI)
</div>
<div class="editor-label">
#*#Html.LabelFor(model=>model.OPERACION.IDFormaPago, "Forma de Pago")*#
<label for="ComboFP">Forma de Pago</label>
</div>
<div class="editor-field">
<select id="ComboFP" name="SelectFP">
#{
foreach (PruebaMVC.Models.DatosLINQ.FORMA_PAGO item in PruebaMVC.Models.DatosLINQ.OperacionDatos.ListarFormaPago())
{
<option value="#(item.IDFormaDePago)">#(item.TipoPago)</option>
}
}
</select>
</div>
<div class="editor-label">
#Html.LabelFor(model => model.OPERACION.Comision, "Comisión de la Venta")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.OPERACION.Comision)
#Html.ValidationMessageFor(model => model.OPERACION.Comision)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.OPERACION.Legajo, "Número de Legajo")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.OPERACION.Legajo)
#Html.ValidationMessageFor(model => model.OPERACION.Legajo)
</div>
<p>
<input type="submit" class="formbutton" value="Cargar Venta" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Volver al listado de Inmuebles", "Index")
</div>
Controller
//
// GET: /Inmueble/Sale/5
public ActionResult VentaP(int id)
{
OperacionModel unModeloOperacionCompuesto = new OperacionModel();
unModeloOperacionCompuesto.INMUEBLE = InmuebleDatos.DetallesInmueble(id);
return View(unModeloOperacionCompuesto);
}
//
// POST: /Inmueble/Sale/5
[HttpPost]
public ActionResult VentaP(OperacionModel model, FormCollection collection)
{
try
{
// TODO: Add insert logic here
model.INMUEBLE = InmuebleDatos.DetallesInmueble(model.INMUEBLE.IDInmueble);
CLIENTE clienteComprador = new CLIENTE();
clienteComprador.Nombre = model.OPERACION.CLIENTE1.Nombre;
clienteComprador.Apellido = model.OPERACION.CLIENTE1.Apellido;
clienteComprador.DNI = model.OPERACION.CLIENTE1.DNI;
clienteComprador.FechaNacimiento = model.OPERACION.CLIENTE1.FechaNacimiento;
OPERACION nuevaOperacion = new OPERACION();
int unIDUsuario = UsuarioDatos.IDUsuario(User.Identity.Name);
int unIDFormaPago = Convert.ToInt32(collection["SelectFP"]);
decimal unaComision = model.OPERACION.Comision;
int unLegajo = model.OPERACION.Legajo;
if (ModelState.IsValid)
{
nuevaOperacion.INMUEBLE = model.INMUEBLE;
nuevaOperacion.FechaOperacion = DateTime.Now;
nuevaOperacion.IDUsuario = unIDUsuario;
nuevaOperacion.IDFormaPago = unIDFormaPago;
nuevaOperacion.INMUEBLE.IDEstado = 2;
nuevaOperacion.Monto = model.INMUEBLE.PrecioVenta;
nuevaOperacion.Comision = unaComision;
nuevaOperacion.Legajo = unLegajo;
nuevaOperacion.CLIENTE1 = clienteComprador;
nuevaOperacion.CLIENTE = model.INMUEBLE.CLIENTE;
OperacionDatos.CrearVenta(nuevaOperacion);
return RedirectToAction("Index");
}
else
{
//return View(nuevaOperacion);
return View(model);
}
}
catch
{
return View(model);
}
}
Edit 2:
I'm still touching the code, and when I comment the line of
#Html.HiddenFor(model => model.INMUEBLE.PrecioVenta)
Where "PrecioVenta" is a decimal(18,2), the page does post back... it is obviously still getting a ModelState.isValid == false because I'm having left that value.
What can I do?
Which are the primitive types for the "HiddenFor" will work?
Or is some stuff of the .Net Framework that can't "map" that datatype properly?
I think that the problem is the client side validations and decimals.
When you have a decimal value, it render it as "35,0" in your culture... but the javascript validator doesn't recognice the "," as a decimal coma.
This is a problem I'm having but I've found a post here in stackoverflow about modifying the javascript validator.
Here you can learn how to fix the javascript validator for decimals

How do I validate a model in a JQuery created dialog and Ajax

I am creating a JQuery dialog where I have use data from a Model I want to validate, but the box is just closed, if I then click to open the dialog again I can see the red text indication errors, but it just closed.
function createEditorDialog() {
$('#floatsam_editor').dialog({ bgiframe: true, autoOpen: false, modal: true, width: 512,
buttons: {
'Close': function () { $('#floatsam_editor').dialog('close'); },
'Create': function () {
$('#flotsam_form').submit();
$('#floatsam_editor').dialog('close');
}
}
});
};
So the red text comes at the submit, but is closed right after, even though the validation failed.
Here is part of the ajax beginform that is shown
<div id="floatsam_editor">
#using (Ajax.BeginForm("CreateFlotsam" , "Flotsam", new { }, new AjaxOptions { HttpMethod = "Post", OnSuccess = "systematic_flotsam.successRequest" }, new { Id = "flotsam_form" }))
{
<div>
<fieldset>
<legend>Create Log Entries</legend>
<div >
<span class="editor-label">
#Html.LabelFor(m => m.Received.Date)
</span>
<span class="editor-field">
#Html.TextBoxFor(m => m.Received.Date, new { id = "flotsam_date", #class="datepicker", maxlength="10"})
</span>
<span class="editor-field">
#Html.TextBoxFor(m => m.Received.Hour, new { id = "flotsam_hours", maxlength="2" })
</span>:<span class="editor-field">
#Html.TextBoxFor(m => m.Received.Minute, new { id = "flotsam_minutes", maxlength="2"})
</span>
<span>
#Html.ValidationMessageFor(m => m.Received.Date)
#Html.ValidationMessageFor(m => m.Received.Hour)
#Html.ValidationMessageFor(m => m.Received.Minute)
</span>
</div>
<div>
<div class="editor-label">
#Html.LabelFor(m =>m.Flotsam.Informant)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Flotsam.Informant, new { #class = "flotsam_dialog_editor_field" })
#Html.ValidationMessageFor(m =>m.Flotsam.Informant)
</div>
</div>
Part of my model is here
[DisplayName("Informant:")]
[Required]
public object Informant { get; set; }
[DisplayName("Flotsam Nature:")]
[Required]
public object FlotsamNature { get; set; }
[DisplayName("Position of Loss:")]
[Required]
public object Position { get; set; }
And as seen it has 3 propertys which are required, but again it still closes if I dont enter anything in my ajax form
So how do I make the dialog box not close when model validation fails?
A very important note is that all this is done on one site and on client side, I do not want to reload the page.
Only close the dialog if the form is valid.
if($("#flotsam_form").valid())
{
$('#flotsam_form').submit();
$('#floatsam_editor').dialog('close');
}
This way it dialog will stay open and validation errors will appear
Since this is dyamically HTML content, you'll need to register the HTML that you wanted validated. This blog post should help you out.

Resources