-1

I am trying to send form data to a mvc controller and when the user click the submit form they are asked for input in a prompt box. The these answers need to be submitted with the form to the controller. When submitted at the moment, the JSON data is not being sent to the controller.

Form:

@using (Html.BeginForm("BottomRowData", "Tanks", FormMethod.Post, new { @id = "formBottom"}))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(p => p.TankSerNo)
@Html.HiddenFor(p => p.AnnularPlateRingWidth)
@Html.HiddenFor(p => p.connectedtank)
@Html.HiddenFor(p => p.NumberofAnnularPlates)
@Html.HiddenFor(p => p.LengthofEachAnnularPlate)
<div class="row">
    <div class="col-md-1 col-xs-4">
        <div class="form-group">
            <button type="submit" name="action:Save" class="btn btn-primary">
                <span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span> Save
            </button>
        </div>
    </div>

    <div class="col-md-4 col-xs-8">
        <div class="form-horizontal">
            <div class="form-group">
                @Html.LabelFor(p => p.TankOwner, "Tank Owner", htmlAttributes: new { @class = "control-label col-md-4" })
                <div class="col-md-8">
                    @Html.DropDownList("TankOwner", null, new { @class = "form-control" })
                </div>
            </div>
        </div>
    </div>

    <div class="col-md-4 col-xs-6">
        <div class="form-horizontal">
            <div class="form-group">
                @Html.LabelFor(model => model.connectedtank.SiteID, "Site (Tank Location)", htmlAttributes: new { @class = "control-label col-md-4" })
                <div class="col-md-8">
                    @Html.HiddenFor(m => m.connectedtank.SiteID)
                    @Html.EditorFor(model => model.connectedtank.Site.SiteName, new { htmlAttributes = new { @class = "form-control", @readonly = true } })
                </div>
            </div>
        </div>
    </div>

    <div class="col-md-3 col-xs-6">
        <div class="form-horizontal">
            <div class="form-group">
                @Html.LabelFor(model => model.TankNumber, "Tank Number", htmlAttributes: new { @class = "control-label col-md-5" })
                <div class="col-md-7">
                    @Html.EditorFor(m => m.TankNumber, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.TankNumber, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>
    </div>
</div>

<hr style="margin-top:0px" />

<fieldset class="fi-border">
<legend class="fi-border">Bottom Row Data</legend>
<div class="row">
    <div class="col-sm-3 com-xs-12">
        <div class="form-horizontal">
            <div class="form-group">
                @Html.LabelFor(model => model.NumberofRowsBottom, "Number of Bottom Rows:", htmlAttributes: new { @class = "control-label col-md-6", @style = "padding-top:0px" })
                <div class="col-md-6">
                    @Html.EditorFor(model => model.NumberofRowsBottom, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.NumberofRowsBottom, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>
    </div>

    <div class="col-sm-6 com-xs-12">
        <div class="form-horizontal">
            <div class="form-group">
                @Html.LabelFor(model => model.WeldRowSpacing, "Weld Row Spacing or Plate Width (Comma Seperated):", htmlAttributes: new { @class = "control-label col-md-5", @style = "padding-top:0px" })
                <div class="col-md-7">
                    @Html.EditorFor(model => model.WeldRowSpacing, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.WeldRowSpacing, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>
    </div>

    <div class="col-xs-12 col-sm-3">
        <button class="btn btn-default btn-block" type="submit" onclick="JavascriptFunction1()" id="BottomButton">
            <strong>1.</strong> Calculate Bottom Row Data
        </button>
    </div>

    <div class="col-sm-12">
        @Html.CollectionEditorFor(model => model.BottomRows, "BottomLayout/_AddRow", "/Tanks/GetRowEditor",
                "Add Rows", new { @style = "display:none" })
    </div>
</div>

}

Script:

<script type="text/javascript" language="javascript">
function JavascriptFunction1() {
    var url = '@Url.Action("BottomRowData", "Tanks")';
    var NumberofRows = parseFloat($('#NumberofRowsBottom').val());
    var numberofPlates = [];
    $("#divLoading").show();
    var i = 1;
    while (i <= NumberofRows) {
        numberofPlates.push(prompt("Please enter the number of plates on row " + i));
        i++; 
    }
    $.ajax({
        type: "POST",
        url: url,
        traditional: true,
        datatype: "json",
        data: JSON.stringify(numberofPlates),
        success: function(data){
            $("#PID")[0].innerHTML = data;
            $("#divLoading").hide();
        }

    });
}

Controller:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> BottomRowData(BottomLayoutViewModel data, string[] postdata)
    {
        var tank = db.Tanks.Find(data.TankSerNo);
        tank.NumberofRowsBottom = data.NumberofRowsBottom;
        string[] cRowData = new string[1000];
        string BottomWeldData = (tank.Diameter / data.NumberofRowsBottom).ToString();
        for (var i = 1; i <= data.NumberofRowsBottom; i++)
        {
            if(i == 1)
            {
                cRowData[i] = BottomWeldData;
            }
            else
            {
                cRowData[i] = cRowData[1];
                BottomWeldData = BottomWeldData + ", " + cRowData[i];
            }
        }
        tank.WeldRowSpacing = BottomWeldData;
        db.Entry(tank).State = EntityState.Modified;
        await db.SaveChangesAsync();
        var Radius = float.Parse((tank.Diameter / 2).ToString());
        float sumRowData = 0;
        double[] rowLength = new double[1000];
        for (var counter = 1; counter <= data.NumberofRowsBottom; counter++)
        {
            var row = new TankBottomLayout();
            if (data.BottomRows != null)
            {
                row = data.BottomRows.ElementAt(counter - 1);
            }
            sumRowData += float.Parse(cRowData[counter]);
            row.TankSerNo = tank.TankSerNo;
            row.Tank = tank;
            row.BLORowNumber = counter;
            row.BLONumberofPlatesRow = int.Parse(postdata.ElementAt(counter - 1));
            rowLength[counter] = 2 * Math.Pow((Math.Pow(Radius, 2) - Math.Pow((sumRowData - Radius), 2)), 0.5);
            if(counter == 1)
            {
                row.BLOWeldRowLength = rowLength[counter];
            }
            else if(counter < data.NumberofRowsBottom / 2 + 1)
            {
                row.BLOWeldRowLength = rowLength[counter - 1];
            }
            else if(counter == data.NumberofRowsBottom)
            {
                row.BLOWeldRowLength = rowLength[counter - 1];
            }
            else
            {
                row.BLOWeldRowLength = rowLength[counter];
            }

            if(row.ID <= 0)
            {
                db.TankBottomLayouts.Add(row);
            }
            else
            {
                db.Entry(row).State = EntityState.Modified;
            }
        }
        await db.SaveChangesAsync();
        return RedirectToAction("BottomLayout", new { TankSerNo = data.TankSerNo });
    }

My main problem is that I need a way to ask the user for the number of plates on each row and send that data to the controller in order to calculate the weld spacing on each row. Thanks.

N. Brown
  • 3
  • 1
  • 4
  • 1
    Could you paste request body from developer tools? – sam Mar 29 '16 at 16:12
  • One probably unrelated issue is that while you are including the AntiForgeryToken on the form and your POST method is checking for the token, you are not including the token along with the AJAX call. – Andy T Mar 29 '16 at 16:32
  • What do you mean _the JSON data is not being sent to the controller_? The code you have shown will send an array or numbers to the controller, but the controller method does not even accept an array - it has parameters `BottomLayoutViewModel data` and `string[] postdata` which have no relationship to what your sending (and as noted previously, you will get a `500 Internal Server Error` anyway since your not including the `AntiForgeryToken`) –  Mar 29 '16 at 23:21

1 Answers1

0

This behaviour is due to Asynchronosity of the Ajax function, Read this post on getting values from Asynchronous functions

Community
  • 1
  • 1
Kiran Maroju
  • 174
  • 1
  • 2
  • 15