I am rather new to MVC so please bear with me.
My goal at hand is to POST a checkboxfor html helper that contains the property called "Verified" to my controller using Ajax. I did mounds of research and yielded this post which is very similar, however it still does not reach the controller and instead I receive a 505 error. checkboxfor Ajax link. This post didn't show how the controller handled the data being passed to the and I am lead to believe that may be my issue but I am not certain. Or it may be something with the foreach block doing some weird stuff.(Side note on the table, we use datatables.net library for table formatting). Below is my code...
Model (comes directly from the EF entity class and is brought in via Meta Data)
namespace Entities
{
public class FPDrinkingWater : AccessibleRecord<FPDrinkingWater>
{
public FPDrinkingWater();
public bool Approved { get; set; }
public string ApprovedBy { get; set; }
public DateTime? ApprovedDate { get; set; }
public string Clorinated { get; set; }
public DateTime? CollectionDate { get; set; }
public TimeSpan? CollectionTime { get; set; }
public string Collectors { get; set; }
public string Comments { get; set; }
public override string CreatedBy { get; set; }
public override DateTime CreatedDate { get; set; }
public bool Deleted { get; set; }
public bool EC { get; set; }
public override int Id { get; set; }
public string Location { get; set; }
public bool RAG { get; set; }
//
// Summary:
// Drinking water record
public override string RecordName { get; }
public short? Replicate { get; set; }
public virtual SampleLog SampleLog { get; set; }
public int SID { get; set; }
public bool SWAT_LAB { get; set; }
public bool TIMS { get; set; }
public override string UpdatedBy { get; set; }
public override DateTime? UpdatedDate { get; set; }
public bool Verified { get; set; }
public string VerifiedBy { get; set; }
public DateTime? VerifiedDate { get; set; }
public override void UpdateTo(FPDrinkingWater entity);
protected override void ParameterChecks();
}
}
Controller action to populate view:
//unverified Drinking Water log
[OpenAction]
public async Task<ActionResult> UnverifiedDrinkingWaterLog(AlertModel alert)
{
//return partial Drinking water log view
return await UnverifiedDataTableAsync<FPDrinkingWater>(alert);
}
Definition of UnverifiedDataTableAsync
:
//Unverified data table
[OpenAction]
public async Task<ActionResult> UnverifiedDataTableAsync<TEntity>(AlertModel alert, string viewName = null) where TEntity : class
{
// get data
var data = (from a in await LimsManager.AllAsync<TEntity>()
select a).ToList();
//LimsManager.AllAsync returns the entire context contents of the Entity in a List then the view tests if `Verified` is not populated.
// create sample log model with alert
var response = new TableModel<TEntity>
{
Alert = alert,
Data = data
};
// return partial data view
return PartialView(viewName ?? $"_Unverified{typeof(TEntity).Name}Table", response);
}
Controller update action:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> VerifyDrinkingWater(FPDrinkingWater drinkingWater, string id )
{
//create alert model
var response = new AlertModel();
//check model state
if(ModelState.IsValid)
{
//add the verifier to the DrinkingWater record
drinkingWater.Verified = true;
drinkingWater.VerifiedBy = User.Identity.Name;
drinkingWater.VerifiedDate = DateTime.Now;
//update the drinking water with the new verified information
var result = await LimsManager.UpdateAsync(drinkingWater);
//check update result
if(result.Succeeded)
{
response.AddInfo($"All SID's successfully verified in the database.", BSContextualTypes.success);
}
else
{
//add failure to alert
response.AddInfo($"Unable to verify SID's in database.", BSContextualTypes.warning);
}
}
else
{
InvalidState(response);
}
return await UnverifiedDrinkingWaterLog(response);
}
The view should iterate over the context of the entity and building the table for each record it finds that is not verified:
@model MyProgram.Application.TableModel<Entities.FPDrinkingWater>
@{
Layout = null;
var insertionMode = InsertionMode.Replace;
var fail = "displayFailure";
var target = "UnverifiedDrinkingWaterContent";
var ajax = "UnverifiedDrinkingWaterLogLoader";
var verify = Html.UserHasClaim("FP/DrinkingWater/VerifyDrinkingWater");
}
<br />
@if (Model != null && Model.Alert != null && Model.Alert.Message != null)
{
@Html.Alert(Model.Alert)
}
@MyHelper.Loader(ajax)
<table id="UnverifiedDrinkingWaterTable" class="table table-hover">
<thead>
<tr>
<th>@Html.LabelFor(m => m.Data.FirstOrDefault().SID)</th>
<th>@Html.LabelFor(m => m.Data.FirstOrDefault().Location)</th>
<th>@Html.LabelFor(m => m.Data.FirstOrDefault().Replicate)</th>
<th>@Html.LabelFor(m => m.Data.FirstOrDefault().CollectionDate)</th>
<th>@Html.LabelFor(m => m.Data.FirstOrDefault().CollectionTime)</th>
<th>@Html.LabelFor(m => m.Data.FirstOrDefault().Collectors)</th>
<th>@Html.LabelFor(m => m.Data.FirstOrDefault().Clorinated)</th>
<th>@Html.LabelFor(m => m.Data.FirstOrDefault().Comments)</th>
<th>@Html.LabelFor(m => m.Data.FirstOrDefault().Verified)</th>
</tr>
</thead>
<tbody>
@if (Model.Data.Any(v => !v.Verified))
{
foreach (var log in Model.Data.Where(v => !v.Verified))
{
<tr data-record-id="@log.Id">
<td>@log.SID</td>
<td>@log.Location</td>
<td>@log.Replicate</td>
<td>@log.CollectionDate.Value.ToShortDateString()</td>
<td>@log.CollectionTime</td>
<td>@log.Collectors</td>
<td>@log.Clorinated</td>
<td>@log.Comments</td>
<td>@Html.CheckBoxFor(m => log.Verified, new { data_url = Url.Action("VerifyDrinkingWater", "DrinkingWater"), id = "mycheckbox", @class = "toggle" })</td>
</tr>
}
}
else
{
<tr>
<td colspan="@Html.ColumnCount(3)"><em>No Drinking Water data to verify.</em></td>
</tr>
}
</tbody>
</table>
<hr />
@if (Model.Data.Count > 0)
{
<script>
$(document).ready(function () {
makeDataTable('UnverifiedDrinkingWaterTable');
$(function () {
$('.toggle').change(function () {
var self = $(this);
var url = self.data('url');
var id = self.attr('id');
var value = self.prop(':checked');
$.ajax({
url: url,
data: { id: id },
type: 'POST',
success: function (result) {
alert(response)
}
});
});
});
});
</script>
}
Generated HTML:
<tr data-record-id="3" role="row" class="odd">
<td>5</td>
<td>Location</td>
<td>1</td>
<td>3/31/1997</td>
<td>18:00:00</td>
<td>YY</td>
<td>Y</td>
<td></td>
<td><input class="toggle" data-url="/FP/DrinkingWater/VerifyDrinkingWater" data-val="true" data-val-required="The Verified field is required." id="mycheckbox" name="log.Verified" type="checkbox" value="true"><input name="log.Verified" type="hidden" value="false"></td>
</tr>
And that data-record-id
matches the ones in the database.
See Question&Answers more detail:
os