我希望能够通过隐藏文本框中的 JSON 将信息从我的视图模型传递到我的控制器。我正在使用 Google 地图 API 中的多边形。当用户编辑多边形时,我通过 javascript 将顶点存储在隐藏的输入中。
var p = mypolygon.getPath().getArray();
var s = '';
for (var i = 0; i < p.length; i++)
s += ((i > 0) ? ', ' : '') + '{ lat: ' + p[i].lat() + ', lng: ' + p[i].lng() + ' }';
$('#@Html.IdFor(m => m.GeofencePoints)').val('[' + s + ']');
结果是:
<input id="GeofencePoints" name="GeofencePoints" type="hidden" value="[{ lat: 38.221276965853264, lng: -97.6892964859955 }, { lat: 38.21294239796929, lng: -97.68770861825868 }, { lat: 38.2122680083775, lng: -97.67782997884831 }, { lat: 38.220434074436966, lng: -97.67787289419255 }]">
我想将以下视图模型绑定到视图:
public class MyMapViewModel
{
public GoogleMapPoint[] GeofencePoints {get;set;}
public string OtherProperty {get;set;}
}
public class GoogleMapPoint
{
public double lat {get;set;}
public double lng {get;set;}
}
这与我看到的示例略有不同,因为我只想将我的一个属性发布为 Json。谁能指出我正确的方向?我知道我可以将它作为字符串传递并自行序列化/反序列化。但是,我希望有一个优雅的客户模型绑定器解决方案。
更新
我根据我发现的这篇文章想出了一个通用的解决方案:http: //mkramar.blogspot.com/2011/05/mvc-complex-model-postback-bind-field.html
public class JsonBindableAttribute : Attribute
{
}
public class MyModelBinder : DefaultModelBinder
{
protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
{
if (propertyDescriptor.Attributes.OfType<Attribute>().Any(x => (x is JsonBindableAttribute)))
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;
return JsonConvert.DeserializeObject(value, propertyDescriptor.PropertyType);
}
return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
}
}
在我的模型中:
[JsonBindable]
[UIHint("GoogleMapPoints")]
public GoogleMapPoint[] GeofencePoints { get; set; }
然后在 global.asax Application_Start()
ModelBinders.Binders.DefaultBinder = new MyModelBinder();
不幸的是,这只能让我到目前为止。这将表单值绑定到我的类就好了。但是,它不能解决将属性呈现为 Json 的问题。如您所见,我创建了一个自定义编辑器 GoogleMapPoints.cshtml,基本上我必须为每个我将拥有的 jsonbindable 类重新创建它。
@model IEnumerable<GoogleMapPoint>
@Html.Hidden("", Newtonsoft.Json.JsonConvert.SerializeObject(Model))
有没有人知道一种方法来拥有一个通用的自定义编辑器,它会关注属性而不是类型,以便使用我的 JsonBindable 属性着色的属性的 EditorFor 总是在隐藏字段中呈现为 Json,而不管类型/类如何?