Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
284 views
in Technique[技术] by (71.8m points)

c# - ASP.NET MVC 5 POST checkboxfor to controller with onclick using Ajax

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...