ASP.Net MVC模型在EditorFor中绑定到JSON



我希望能够通过隐藏文本框中的JSON将信息从视图模型传递到控制器。我在谷歌地图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,我基本上需要为每个类重新创建。

@model IEnumerable<GoogleMapPoint>
@Html.Hidden("", Newtonsoft.Json.JsonConvert.SerializeObject(Model))

有没有人知道一种方法,有一个通用的自定义编辑器,将注意属性,而不是类型,以便编辑器的属性颜色与我的JsonBindable属性总是呈现为Json在一个隐藏的字段,无论类型/类?

您可以为那个特定的模型创建一个模型绑定器。这将通过为保存映射点的属性添加一些特定的逻辑来扩展默认绑定器,从请求参数反序列化json。

[ModelBinder(typeof(MyMapModelBinder))]
public class MyMapViewModel
{
    public List<GoogleMapPoint> GeofencePoints { get; set; }
    public string OtherProperty { get; set; }
}
public class GoogleMapPoint
{
    public double lat { get; set; }
    public double lng { get; set; }
}
public class MyMapModelBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
    {
        if (propertyDescriptor.Name == "GeofencePoints")
        {
            var model = bindingContext.Model as MyMapViewModel;
            if (model != null)
            {
                var value = bindingContext.ValueProvider.GetValue(propertyDescriptor.Name);
                var jsonMapPoints = value.AttemptedValue;
                if (String.IsNullOrEmpty(jsonMapPoints))                    
                    return ;                    
                MyMapViewModel mapModel = model as MyMapViewModel;
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                mapModel.GeofencePoints = (List<GoogleMapPoint>)serializer.Deserialize(jsonMapPoints, typeof(List<GoogleMapPoint>));
                return;
            }
        }
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
    }
}

相关内容

  • 没有找到相关文章

最新更新