I want to create a field object in ASP.NET MVC and store it to a database. The field should contain its coordinates which the user can select with the google maps api. And now, how can I pass the coordinates of the markers, which are stored in a javascript array, to the Model´s List?
This is my Controller for this:
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);
}
}
}
Here my Create View with the Google Maps script:
@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="" type="text/javascript"></script>
<script src=".3.2.min.js" type="text/javascript"></script>
<script src=".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>
}
and finally my ViewModel to create the field:
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; }
}
/edit: Id did it like this now, but it still doesn´t work
changed part from the google maps 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);
},
});
And the Controller Function:
// 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);
}
I want to create a field object in ASP.NET MVC and store it to a database. The field should contain its coordinates which the user can select with the google maps api. And now, how can I pass the coordinates of the markers, which are stored in a javascript array, to the Model´s List?
This is my Controller for this:
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);
}
}
}
Here my Create View with the Google Maps script:
@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./maps/api/js?sensor=false" type="text/javascript"></script>
<script src="http://ajax.microsoft./ajax/jquery/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="http://ajax.microsoft./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>
}
and finally my ViewModel to create the field:
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; }
}
/edit: Id did it like this now, but it still doesn´t work
changed part from the google maps 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);
},
});
And the Controller Function:
// 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);
}
Share
Improve this question
edited Apr 30, 2015 at 11:43
Yannick Schneider
asked Apr 30, 2015 at 8:05
Yannick SchneiderYannick Schneider
313 silver badges6 bronze badges
2
-
1
Why do you have 2
CreateFieldViewModel
parameters in the POST method (is that a typo?). Are you referring to the values you add tovar markers = [];
? – user3559349 Commented Apr 30, 2015 at 8:13 - The two ViewModels are just a mistake by myself.. – Yannick Schneider Commented Apr 30, 2015 at 8:49
2 Answers
Reset to default 2I understood, (looking by you code) that you want to go with submitting form, and not ajax?
If so, you have two choices (known to me):
- Create html hidden input and paste there as value serialized JSON of your markers array - but you will have to deserialize this value later. In this example you need to change Coordinates type in your model to string.
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=""/>
- Create dynamically, using JavaScript (for example append function) many hidden html inputs with name model.Coordinates[i] and value of single coordinate (use some loop).
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+'">');
});
Of course using AJAX is much better way, and AlexB answer is way to go, but mechanism of it is a little different. It is good to use only AJAX (not form submitting), because in your example you need to use two Actions, one for AJAX and one for form submitting.
You can pass your Javascript array to your controller using an Ajax call :
$.ajax({
url : "@Url.Action("MethodName", "ControllerName")",
contentType : "application/json; charset=utf-8",
dataType : "json",
type : "POST",
data : JSON.stringify({coordinates: markers})
})
(where markers is your JS array to pass to the controller, I guess)
And your controller will look like
public ActionResult MethodName(Single[] coordinates)
{
// ...
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745156094a4614129.html
评论列表(0条)