I am trying to pass back a json object back to my action in my device controller, this is then inserted into the database, however when I click the submit button on my form it seems to fire twice. Another problem is that my location field within the json object and pfID does not get sent back to the controller, the other fields get sent back properly. Here is my code:
$('#getDevice').unbind('click').bind('click', function (e) {
e.stopPropagation();
//anti forgery token
//get the form
var form = $('#addDeviceForm');
//from the form get the antiforgerytoken
var token = $('input[name="__RequestVerificationToken"]', form).val();
var URL = 'Devices/PushIPForCollection';
//Before this we need to build the model from the input the user has given us
var device = {
deviceID: ' ',
ipAddress: $('#dIPAddress').val(),
deviceName: $('#dDeviceName').val(),
CreatedDate: ' ',
UpdatedDate: ' ',
CreatedBy: ' ',
UpdatedBy: ' ',
deviceSubGroupID: $('#dSubgroup option:selected').val(),
subgroup: " ",
companyID: ' ',
hidden: ' ',
pfID: $('#dpfID option:selected').val(),
pf: ' ',
location: JSON.stringify({
'region': $('#dRegion').val() == null ? ' ' : $('#dRegion').val(),
'country': $('#dCountry').val() == null ? ' ' : $('#dCountry').val(),
'city': $('#dCity').val() == null ? ' ' : $('#dCity').val(),
'building': $('#dBuilding').val() == null ? ' ' : $('#dBuilding').val(),
'room': $('#dRoom').val() == null ? ' ' : $('#dRoom').val(),
'rack': $('#dRack').val() == null ? ' ' : $('#dRack').val()
})
};
alert(device.pfID);
alert(device.location);
$.ajax({
url: URL,
data: {
__RequestVerificationToken: token,
device: device
},
type: 'POST',
success: function (result) {
},
error: function (jqXHR, textStatus, errorThrown) {
alert("An error has occurred please contact us");
}
})
$('#add-device').modal('hide');
return false;
});
Where I alert my pfID it returns a string of "ba4475ef-0eed-441a-a77e-d733c288bf8e"
Here is my model:
public class Devices
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int deviceID { get; set; }
[Display(Name="IP Address:"), StringLength(50)]
public string ipAddress { get; set; }
[Display(Name = "DeviceName:"), StringLength(50)]
public string deviceName { get; set; }
public DateTime? CreatedDate { get; set; }
public DateTime? UpdatedDate { get; set; }
public string CreatedBy { get; set; }
public string UpdatedBy { get; set; }
[Display(Name="Add to subgroup:")]
public long? deviceSubGroupID { get; set; }
[ForeignKey("deviceSubGroupID")]
public DeviceSubGroup subgroup { get; set; }
public string companyID { get; set; }
public string hidden { get; set; }
public string pfID { get; set; }
[ForeignKey("pfID")]
public PfHealth.Pf pf { get; set; }
public string location { get; set; }
}
and here is my post method:
public ActionResult PushIPForCollection(Devices device)
{
//Before committing to the database we need to check if the device already exists
var checkIfDeviceExists = db.devices.Any(check => check.ipAddress == device.ipAddress);
if (!checkIfDeviceExists)
{
if (ModelState.IsValid)
{
var userID = User.Identity.GetUserId();
device.CreatedDate = DateTime.Now;
device.UpdatedDate = DateTime.Now;
device.CreatedBy = userID;
device.UpdatedBy = userID;
var subgroup = db.deviceSubGroups.Where(sub => sub.deviceSubID == device.deviceSubGroupID).FirstOrDefault();
device.communityString = subgroup.snmpCommunityString;
device.companyID = subgroup.companyID;
db.devices.Add(device);
db.SaveChanges();
}
}
//Can change this to get json in order to let to view know what message to display to the user.
return RedirectToAction("index");
}
and here is my form in the view:
<div class="modal fade" id="add-device" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="add-device-Label"><strong>ADD DEVICE</strong></h4><!--add depending on which panel you have clicked-->
</div>
<div class="modal-body" id="add-device-body">
<!--Depending on which panel insert content-->
@using (Html.BeginForm("PushIPForCollection", "Devices", FormMethod.Post, new { id = "addDeviceForm" }))
{
@Html.AntiForgeryToken()
<hr />
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-3">
@Html.LabelFor(m => m.device.ipAddress, new { @class = "col-md-2 control-label"})
</div>
<div class="col-md-9">
@Html.TextBoxFor(m => m.device.ipAddress, new { @class = "form-control", @id = "dIPAddress" })
</div>
</div>
<div class="form-group">
<div class="col-md-3">
@Html.LabelFor(m => m.device.deviceName, new { @class = "col-md-2 control-label" })
</div>
<div class="col-md-9">
@Html.TextBoxFor(m => m.device.deviceName, new { @class = "form-control", @id = "dDeviceName" })
</div>
</div>
<div class="form-group">
<div class="col-md-3">
@Html.LabelFor(m => m.device.deviceSubGroupID, new { @class = "col-md-2 control-label" })
</div>
<div class="col-md-9">
@Html.DropDownListFor(m => m.device.deviceSubGroupID, (IEnumerable<SelectListItem>)ViewBag.subGroups, "None", new { @id = "dSubgroup" })
@Html.ValidationMessageFor(m => m.device.deviceSubGroupID, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-3">
@Html.Label("Region:")
</div>
<div class="col-md-9">
@Html.TextBox("Region", "", new { @class = "form-control", @id = "dRegion" })
</div>
</div>
<div class="form-group">
<div class="col-md-3">
@Html.Label("Country:")
</div>
<div class="col-md-9">
@Html.TextBox("Country", "", new { @class = "form-control", @id = "dCountry" })
</div>
</div>
<div class="form-group">
<div class="col-md-3">
@Html.Label("City:")
</div>
<div class="col-md-9">
@Html.TextBox("City", "", new { @class = "form-control", @id = "dCity" })
</div>
</div>
<div class="form-group">
<div class="col-md-3">
@Html.Label("Building:")
</div>
<div class="col-md-9">
@Html.TextBox("Building", "", new { @class = "form-control", @id = "dBuilding" })
</div>
</div>
<div class="form-group">
<div class="col-md-3">
@Html.Label("Room:")
</div>
<div class="col-md-9">
@Html.TextBox("Room", "", new { @class = "form-control", @id = "dRoom" })
</div>
</div>
<div class="form-group">
<div class="col-md-3">
@Html.Label("Rack:")
</div>
<div class="col-md-9">
@Html.TextBox("Rack", "", new { @class = "form-control", @id = "dRack" })
</div>
</div>
<div class="form-group">
<div class="col-md-3">
@Html.LabelFor(model=>model.device.pfID)
</div>
<div class="col-md-9">
@Html.DropDownListFor(m => m.device.pfID, (IEnumerable<SelectListItem>)ViewBag.pathfinders, "None", new { @id = "dpfID" })
@Html.ValidationMessageFor(m => m.device.pfID, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="getDevice" type="submit" value="CreateGroups" data-loading-text="Loading..." class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
}
</div>
</div>
</div>
You do not need to create the javascript object manually, You may use jQuery
serializemethod to serialize the entire form and send it via ajax as long as the form field names matches with the param names/model property names in the HttpPost action method.You may create a view model specific to the view.
In your GET action, create an object of this view model, assign the DeviceSubGroups property and send to the view.
And in your view, which is strongly typed to the view model, @model CreateDeviceVm
Now you can add some javascript to listen to the click event on the submit button, get a reference to the form, serialize it and send to the server using jQuery ajax.
And in your HttpPost action method,