2015-04-30 33 views
2

我想在ASP.NET MVC中創建一個字段對象並將其存儲到數據庫中。該字段應包含其用戶可以使用Google Maps API選擇的座標。 現在,我如何將存儲在JavaScript數組中的標記的座標傳遞給模型列表?如何將JavaScript數組傳遞給ASP.NET MVC模型?

這是我對這個控制器:

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Data.Entity; 
using System.Linq; 
using System.Net; 
using System.Web; 
using System.Web.Mvc; 
using BL; 
using MvcAgrarTest.Models; 

namespace MvcAgrarTest.Controllers 
{ 
    public class FieldsController : Controller 
    { 
     private MvcAgrarContext db = new MvcAgrarContext(); 

     // GET: Fields 
     public ActionResult Index() 
     { 
      var field = db.CreateFieldViewModel.Include(f => f.FieldType); 
      return View(field.ToList()); 
     } 

     // GET: Fields/Create 
     public ActionResult Create() 
     { 
      var model = new CreateFieldViewModel(); 
      ViewBag.FieldTypeId = new SelectList(db.FieldType, "FieldTypeId", "Name"); 
      return View(model); 
     } 

     // POST: Fields/Create 
     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public ActionResult Create(CreateFieldViewModel model, CreateFieldViewModel field, string[] markers) 
     { 

      if (ModelState.IsValid) 
      { 
       PostCoordinates(markers); 
       db.CreateFieldViewModel.Add(field); 
       db.SaveChanges(); 
       return RedirectToAction("Index"); 
      } 

      ViewBag.FieldTypeId = new SelectList(db.FieldType, "FieldTypeId", "Name", field.FieldTypeId); 
      return Json(true); 
     }  
     protected override void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       db.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 


    } 
} 

在這裏,我創建視圖與谷歌地圖腳本:

@model MvcAgrarTest.Models.CreateFieldViewModel 

@{ 
    ViewBag.Title = "Create"; 
} 

<h2>Feld anlegen</h2> 


@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     <div class="form-group"> 
      @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @placeholder = "Feldname", @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.FieldTypeId, "Feldtyp", htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.DropDownList("FieldTypeId", null, "--Feldart auswählen--", htmlAttributes: new { @class = "form-control" }) 
       @Html.ValidationMessageFor(model => model.FieldTypeId, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Size, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Size, new { htmlAttributes = new { @placeholder = "In Hektar", @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Size, "", new { @class = "text-danger" }) 
      </div> 
     </div>   
      <div id="google"> 
       <script src="https://maps.googleapis.com/maps/api/js?sensor=false" type="text/javascript"></script> 
       <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js" type="text/javascript"></script> 
       <script src="http://ajax.microsoft.com/ajax/jquery.validate/1.5.5/jquery.validate.min.js" type="text/javascript"></script> 
       <script type="text/javascript"> 

       var map; 

       function initialize() { 
        var myLatLng = new google.maps.LatLng(50.617109, 8.065738); 
        var myOptions = { 
         zoom: 5, 
         center: myLatLng, 
         mapTypeId: google.maps.MapTypeId.ROADMAP 
        }; 

        map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 

        // array to store markers that has been drawn 
        var markers = []; 

        // event listener draw a marker 
        google.maps.event.addListener(map, 'click', function (e) { 

         var marker = new google.maps.Marker(); 

         marker.setPosition(e.latLng); 
         marker.setMap(map); 
         marker.setVisible(true); 

         markers.push(marker); 

         // draw polygon on marker click 
         // once user clicks on on of the markers 
         google.maps.event.addListener(marker, 'click', function (e) { 
          document.getElementById("label").innerHTML = ""; 
          drawPoints(markers); 
          label.style.borderStyle = "dotted" 
          for (i = 0; i < markers.length; ++i) { 
           document.getElementById("label").innerHTML += markers[i].position; 

          } 

          // empty the markers array 
          markers = []; 
         }); 

        }); 

       } 

       function drawPoints(markers) { 
        var poly = new google.maps.Polygon; 

        var points = []; 

        for (var i = 0; i < markers.length; i++) { 
         points.push(markers[i].getPosition()); 
        } 
        poly.setMap(map); 
        poly.setPath(points); 
        poly.setVisible(true); 
       } 
      </script> 
      <body onload="initialize()"> 
       <div id="map_canvas" style="width: 500px; height: 300px"></div> 
      </body> 
     </div> 


     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Erstellen" class="btn btn-default" /> 
      </div> 
     </div> 
    </div>  

} 

,最後我的視圖模型來創建字段:

public class CreateFieldViewModel 
    { 
     [Key] 
     [Display(Name="ID")] 
     public int FieldId { get; set; } 

     [Required] 
     [Display(Name="Fieldname")] 
     public string Name { get; set; } 

     [Required] 
     [Display(Name="Fieldtype")] 
     public int FieldTypeId { get; set; } 

     [Required] 
     [Range(0.01, int.MaxValue, ErrorMessage = "The Size can´t be 0 or less")] 
     [Display(Name="Fieldsize")] 
     public float Size { get; set; } 

     [Display(Name="Coordinates")] 
     public List<string> Coordinates { get; set; } 

     public virtual FieldType FieldType { get; set; }   
    } 

/編輯:我現在這樣做,但它仍然沒有工作

變化的部分從谷歌地圖API:

var passdata = []; 
google.maps.event.addListener(marker, "click", function(e){ 
    for (y=0; y<markers.length; ++y){ 
     passdata[y] = markers[y].position 
    } 
    drawpoints(markers); 
    $.ajax({ 
     url: "@Url.Action("Create","Fields")", 
     typ: "POST", 
     datatype: "json", 
     data: JSON.stringify({coordinates: passdata}), 
     contentType: "application/json; charset=utf-8", 
     traditional: true, 
     success: function (data) { 
      alert(data); 
     }, 
    }); 

和控制器功能:

// GET: Fields/Create 
     public ActionResult Create() 
     { 
      var model = new CreateFieldViewModel(); 
      ViewBag.FieldTypeId = new SelectList(db.FieldType, "FieldTypeId", "Name"); 
      return View(model); 
     } 

// POST: Fields/Create   
[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Create(CreateFieldViewModel field, string[] coordinates) 
{ 

    if (ModelState.IsValid) 
    { 
     field.Coordinates = coordinates; 
     db.CreateFieldViewModel.Add(field); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    ViewBag.FieldTypeId = new SelectList(db.FieldType, "FieldTypeId", "Name", field.FieldTypeId); 
    return View(field); 
} 
+1

爲什麼在POST方法中有2個'CreateFieldViewModel'參數(是一個錯字?)。你是指你添加到'var markers = [];'的值嗎? –

+0

這兩個ViewModels只是我自己犯的一個錯誤。 –

回答

1

你可以通過你的Javascript數組使用Ajax調用你的控制器:

$.ajax({ 
     url   : "@Url.Action("MethodName", "ControllerName")", 
     contentType : "application/json; charset=utf-8", 
     dataType : "json", 
     type  : "POST", 
     data  : JSON.stringify({coordinates: markers}) 
}) 

(其中標記是喲烏爾JS數組傳遞給控制器​​,我猜)

而且你的控制器看起來就像

public ActionResult MethodName(Single[] coordinates) 
{ 
    // ... 
} 
+0

當我在調試模式下使用Createbutton中的斷點運行它時,Visual Studio顯示座標數組只包含一個值爲0的項目。 –

+0

什麼是內容你的JS數組發送到ajax調用之前? – AlexB

+0

就在ajax調用之前,數組包含一個標記對象列表(數量依賴於已設置了多少標記)。座標可以通過標記[i] .position和我想保存在模型座標列表中的這些座標進行訪問。 –

1

我明白了,(用你的代碼看),你想要去的提交形式,而不是阿賈克斯?

如果是這樣,你有兩個選擇(知道我):

  1. 創建HTML隱藏輸入,粘貼有作爲標記陣列的價值序列化JSON - 但你必須在以後反序列化該值。在這個例子中,您需要將模型中的座標類型更改爲字符串。

的JavaScript

// some sample coordinates, you need to extract them from markers 
var coordinates = ["12,21","213,231"]; 
var dataToSend = JSON.stringify(coordinates); 
$("#coordinatesInput").val(dataToSend); 

HTML

<input hidden id="coordinatesInput" name="model.Coordinates" value=""/> 
  • 動態創建,使用JavaScript(例如附加功能)與姓名模型許多隱藏的HTML輸入。座標[i]和單個座標的值(使用某個循環)。
  • 的JavaScript

    var coordinates = ["231,2132","312,231","231,321"]; 
    
    var container = $("#container"); 
    //container, where you will be adding inputs, in you example it could be form-horizontal class 
    coordinates.forEach(function(val, i){ 
        container.append('<input hidden name="model.Coordinates['+i+']" value="'+val+'">'); 
    }); 
    

    使用AJAX當然是更好的方法,並AlexB答案是的路要走,但它的機制是有一點不同。只使用AJAX(不是表單提交)是很好的,因爲在你的例子中你需要使用兩個Action,一個用於AJAX,一個用於表單提交。

    +0

    代碼示例非常棒:) –

    相關問題