问题描述
在MVC3,是有可能,如果模型嵌套对象的JavaScript对象自动绑定到款?我的模型是这样的:
公共类分享Tweet
{
公开资料Tweet()
{
坐标=新的地缘();
}
公共字符串ID {搞定;组; }
公共字符串用户{搞定;组; }
公众的DateTime创建{搞定;组; }
公共字符串文本{搞定;组; }
公共地理坐标{搞定;组; }}公共类地理{ 公共地理位置(){} 公共地理(双?纬度,双?LNG)
{
this.Latitude =纬度;
this.Longitude = LNG;
} 公共双?纬度{搞定;组; }
公共双?经度{搞定;组; } 公共BOOL的HasValue
{
得到
{
回报(纬度= NULL ||经度!= NULL!);
}
}
}
当我发布以下JSON到我的控制器一切,除了坐标成功绑定:
<$p$p><$c$c>{\"Text\":\"test\",\"Id\":\"testid\",\"User\":\"testuser\",\"Created\":\"\",\"Coordinates\":{\"Latitude\":57.69679752892457,\"Longitude\":11.982091465576104}}这是我的控制器操作如下:
[HttpPost]
公共JsonResult锐推(唧啾)
{
//做一些东西
}
我失去了一些东西在这里还是新的自动绑定功能只支持原始的对象?
是的,你可以绑定ASP.NET MVC3复杂的JSON对象。
菲尔哈克写了一篇关于它的.
你在这里得到了与你的地理类的问题。结果
不要使用可空属性:
公共类地理
{ 公共地理位置(){} 公共地理(双纬度,双LNG)
{
this.Latitude =纬度;
this.Longitude = LNG;
} 公共双纬度{搞定;组; }
公共双经度{搞定;组; } 公共BOOL的HasValue
{
得到
{
回报(纬度= NULL ||经度!= NULL!);
}
}
}
这是JavaScript code我已经使用来测试它:
VAR jsonData = {文:测试,ID:testid,用户:testuser的,创建:,坐标 :{纵横:57.69679752892457,经度:11.982091465576104}};
VAR鸣叫= JSON.stringify(jsonData);
$阿贾克斯({
输入:POST,
网址:家庭/索引,
数据:鸣叫,
成功:函数(){
警报(OK);
},
数据类型:JSON,
的contentType:应用/ JSON的;字符集= UTF-8
});
更新
我试着做一些实验与模型粘结剂和我来到了这个解决方案,这似乎与空类型正常工作。
我创建了一个自定义的模型绑定:
使用系统;
使用System.Web.Mvc;
使用System.IO;
使用System.Web.Script.Serialization;公共类TweetModelBinder:IModelBinder
{
公共对象BindModel(ControllerContext controllerContext,ModelBindingContext的BindingContext)
{
VAR的contentType = controllerContext.HttpContext.Request.ContentType;
如果(!contentType.StartsWith(应用/ JSON,StringComparison.OrdinalIgnoreCase))
回报(NULL); 串bodyText的; 使用(VAR流= controllerContext.HttpContext.Request.InputStream)
{
stream.Seek(0,SeekOrigin.Begin);
使用(VAR读者=新的StreamReader(流))
bodyText的= reader.ReadToEnd();
} 如果(string.IsNullOrEmpty(bodyText的))回报(NULL); 。VAR鸣叫=新的JavaScriptSerializer()反序列化&LT; Models.Tweet&GT;(bodyText的); 返回(鸣叫);
}
}
和我已经把它注册为各类鸣叫:
保护无效的Application_Start()
{
AreaRegistration.RegisterAllAreas(); ModelBinders.Binders.Add(typeof运算(Models.Tweet),新TweetModelBinder()); RegisterGlobalFilters(GlobalFilters.Filters);
的RegisterRoutes(RouteTable.Routes);
}
In MVC3, is it possible to automatically bind javascript objects to models if the model has nested objects? My model looks like this:
public class Tweet
{
public Tweet()
{
Coordinates = new Geo();
}
public string Id { get; set; }
public string User { get; set; }
public DateTime Created { get; set; }
public string Text { get; set; }
public Geo Coordinates { get; set; }
}
public class Geo {
public Geo(){}
public Geo(double? lat, double? lng)
{
this.Latitude = lat;
this.Longitude = lng;
}
public double? Latitude { get; set; }
public double? Longitude { get; set; }
public bool HasValue
{
get
{
return (Latitude != null || Longitude != null);
}
}
}
When I post the following JSON to my controller everything except "Coordinates" binds successfully:
{"Text":"test","Id":"testid","User":"testuser","Created":"","Coordinates":{"Latitude":57.69679752892457,"Longitude":11.982091465576104}}
This is what my controller action looks like:
[HttpPost]
public JsonResult ReTweet(Tweet tweet)
{
//do some stuff
}
Am I missing something here or does the new auto-binding feature only support primitive objects?
Yes, you can bind complex json objects with ASP.NET MVC3.
Phil Haack wrote about it recently.
You've got a problem with your Geo class here.
Don't use nullable properties:
public class Geo
{
public Geo() { }
public Geo(double lat, double lng)
{
this.Latitude = lat;
this.Longitude = lng;
}
public double Latitude { get; set; }
public double Longitude { get; set; }
public bool HasValue
{
get
{
return (Latitude != null || Longitude != null);
}
}
}
This is the javascript code I've use to test it:
var jsonData = { "Text": "test", "Id": "testid", "User": "testuser", "Created": "", "Coordinates": { "Latitude": 57.69679752892457, "Longitude": 11.982091465576104} };
var tweet = JSON.stringify(jsonData);
$.ajax({
type: 'POST',
url: 'Home/Index',
data: tweet,
success: function () {
alert("Ok");
},
dataType: 'json',
contentType: 'application/json; charset=utf-8'
});
UPDATE
I've tried to do some experiments with model binders and I came out with this solutions which seems to work properly with nullable types.
I've created a custom model binder:
using System;
using System.Web.Mvc;
using System.IO;
using System.Web.Script.Serialization;
public class TweetModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var contentType = controllerContext.HttpContext.Request.ContentType;
if (!contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
return (null);
string bodyText;
using (var stream = controllerContext.HttpContext.Request.InputStream)
{
stream.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(stream))
bodyText = reader.ReadToEnd();
}
if (string.IsNullOrEmpty(bodyText)) return (null);
var tweet = new JavaScriptSerializer().Deserialize<Models.Tweet>(bodyText);
return (tweet);
}
}
and I've registered it for all types tweet:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.Add(typeof(Models.Tweet), new TweetModelBinder());
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
这篇关于与嵌套类ASP.NET MVC3 JSON模式结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!