2015-12-20 44 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()'來渲染表單。 –