在MVC3中,如果模型具有嵌套对象,是否可以自动将javascript对象绑定到模型?我的模型看起来像这样:
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);
}
}
}
当我将以下JSON发布到我的控制器时,除“Coordinates”之外的所有内容都成功绑定:
{"Text":"test","Id":"testid","User":"testuser","Created":"","Coordinates":{"Latitude":57.69679752892457,"Longitude":11.982091465576104}}
这就是我的控制器操作:
[HttpPost]
public JsonResult ReTweet(Tweet tweet)
{
//do some stuff
}
我在这里遗漏了什么,或者新的自动绑定功能是否仅支持原始对象?
答案 0 :(得分:19)
是的,您可以使用ASP.NET MVC3绑定复杂的json对象。
Phil Haack写了recently 你在这里遇到了Geo课的问题 不要使用可空属性:
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);
}
}
}
这是我用来测试它的javascript代码:
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'
});
<强>更新强>
我尝试过使用模型绑定器进行一些实验,然后我推出了这种解决方案,它似乎可以使用可空类型。
我创建了一个自定义模型绑定器:
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);
}
}
我已经为所有类型的推文注册了它:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.Add(typeof(Models.Tweet), new TweetModelBinder());
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
答案 1 :(得分:0)
我遇到了同样的问题,但在我的情况下,这与数据从客户端传输的方式有关。确保AJAX请求使用正确的标头和格式。例如:
dataType: 'json',
contentType: 'application/json; charset=UTF-8',
data: JSON.stringify({
MemberId : '123',
UserName: '456',
Parameters: [
{ Value : 'testing' },
{ Value : 'test2' }
]
}),