2015-12-20 46 views
-3

我想回传一个json对象回到我的设备控制器中的动作,然后插入到数据库中,但是当我单击我的窗体上的提交按钮时它似乎会触发两次。另一个问题是我的json对象和pfID中的位置字段没有被发送回控制器,其他字段被正确地发回。这里是我的代码:ajax POST不传回正确的数据

$('#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; 
}); 

在哪里我提醒我的PFID它返回的"ba4475ef-0eed-441a-a77e-d733c288bf8e"

这里的字符串是我的模型:

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; } 
} 

,这里是我的帖子方法:

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"); 
    } 

这里是我的表格:

<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">&times;</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> 

+0

只需使用'数据:$( '#addDeviceForm')序列化(),'后回到你的形式。如果您的视图通过强制绑定到模型而正确生成,那么它将正确绑定到您的模型。 'pfID'返回''ba4475ef-0eed-441a-a77e-d733c288bf8e“'有什么问题?你期待它成为什么? –

+0

\ @StephenMuecke对不起,我可能没有正确解释,它应该返回,但是当我在动作中设置断点时,它会作为一个空字符串与位置一起返回。我这样做的原因是因为我想将位置内的所有字段分组并将其存储在数据库中,如JSON – Johnathon64

+0

您需要向您展示模型,视图和POST方法。我们不可能猜到你有什么错误(如果你已经正确地生成了视图,你所有的脚本都可以用几行代码代替) –

回答

1

您不必手动创建JavaScript对象,你可以使用jQuery serialize方法序列化整个窗体,并通过AJAX只要把它作为表单字段名称与帕拉姆名称匹配/在HttpPost操作方法中模拟属性名称。

您可以创建特定于该视图的视图模型。

public class CreateDeviceVm 
{ 
    public string DeviceId {set;get;} 
    public string IPAddress {set;get;} 
    public int DeviceSubGroupId {set;get;} 
    public List<SelectListItem> DeviceSubGroups {set;get;} 
    public string City {set;get;} 
    public string Room {set;get;} 
    //Add properties NEEDED FOR THE VIEW. 
} 

在你的GET操作,创建这个视图模型的对象,分配DeviceSubGroups财产和发送到视图。

public ActionResult Create() 
{ 
    var vm = new CreateDeviceVm(); 
    vm.DeviceSubGroups = db.DeviceSubGroups 
        .Select(s=> new SelectLisItem { Value=s.Id.ToString(), 
                Text = s.Name }).ToList(); 

    return View(vm); 
} 

而且在你看来,这是强类型的视图模型, @model CreateDeviceVm

@using(Html.BeginForm()) 
{ 
    <label>DeviceId</label> 
    @Html.TextBoxFor(s=>s.DeviceId) 
    <label>IP Address</label> 
    @Html.TextBoxFor(s=>s.IPAddress) 
    <label>Sub group</label> 
    @Html.DropDownListFor(s=>s.DeviceSubGroups,Model.DeviceSubGroups,"Select") 
    <label>City</label> 
    @Html.TextBoxFor(s=>s.City) 
    <label>Room</label> 
    @Html.TextBoxFor(s=>s.Room) 
    <input type="submit" id="btnSave" /> 
} 

现在你可以添加一些JavaScript,听取他们对提交按钮的单击事件,得到对表单的引用,将其序列化并使用jQuery ajax发送到服务器。

$(function(){  
    $("#btnSave").click(function(e){  
    e.preventDefault(); 

    var _f=$(this).closest("form"); 
    $.post(_f.attr("action")._f.serialize(),function(res){ 
     //check res and do something 
    });  
    });  
}); 

而在你HttpPost操作方法,

[HttpPost] 
public ActionResult Create(CreateDeviceVm model) 
{ 
    var exists= db.devices.Any(x=> x.ipAddress == model.ipAddress); 
    if (!exists) 
    { 
     var d= new Device(); 
     d.IpAddress=model.IPAddress; 
     d.DeviceSubGroupId=model.DeviceSubGrouId; 
     //Map other properties as well. 

     db.Devices.Add(d); 
     db.SaveChanges(); 
     return Json(new { status="success"}); 
    } 
    return Json(new { status="failed"}); 
} 
+0

OP使用的代码例如'@ Html.TextBoxFor(m => m.device。 ipAddress)'表明视图中的主模型包含设备属性,因此主模型需要进行调整以包含'CreateDeviceVm'属性,但是后处理方法需要一个'[Bind(Prefix =“)。 ..“)]'属性,建议更好的方法是'[ChildActionOnly]'方法返回基于'CreateDeviceVm'的部分表单,并在主视图中使用'@ Html.Action()'来避免'BindAttribute' –

+0

我的答案是建议使用一个特定于视图的平面视图模型,我没有关注你的评论意味着什么 – Shyju

+0

这是为了OP,我猜测主视图是显示设备列表表单是添加一个新设备,在这种情况下,主视图可以是List '并且包含'@ Html.Action()'来渲染表单。 –