在我当前的MVC应用程序中,我对控制器执行AJAX调用。控制器从数据库中获取一个对象,并以JSON响应的形式返回它。我的困惑在于使用Controller.Json方法与JavaScriptSerializer.Serialize(对象)之间的混淆。我转换的对象是一个名为PhoneSerializable
的简单类,其中包含一些类型为string
和int
的公共属性。
我有以下内容:
var serializedPhone = jsSerializer.Serialize(new PhoneSerializable(phone));
return new ContentResult {Content = serializedPhone, ContentType = "application/json"};
这可以正常工作,我得到一个我的AJAX调用者可以解析的JSON响应。 然而,我见过的一些在线示例使用了这个:
return Json(new PhoneSerializable(phone));
此响应主要有null
个属性和DenyGet
标头,这意味着它无法解析或其他内容。 Json(object)
方法的文档声明它为对象使用相同的javascript序列化程序,但它无法将我的简单对象转换为JSON。
我错过了什么?我想使用Json(object)
因为它更干净但我似乎无法让它工作。
用答案编辑:
Json()
方法默认为" DenyGet"添加更多参数修复了问题,现在可以正常工作:
return Json(new PhoneSerializable(phone),
"application/json",
JsonRequestBehavior.AllowGet);
答案 0 :(得分:2)
使用Json
基类中的Controller
方法只返回类型为JsonResult
的新对象,使用以下重载:
protected internal JsonResult Json(object data)
{
return this.Json(data, null, null, JsonRequestBehavior.DenyGet);
}
protected internal virtual JsonResult Json(
object data,
string contentType,
Encoding contentEncoding,
JsonRequestBehavior behavior)
{
return new JsonResult
{
Data = data,
ContentType = contentType,
ContentEncoding = contentEncoding,
JsonRequestBehavior = behavior
};
}
在return Json(new PhoneSerialize(phone));
之后,控制器最终调用一个名为ExecuteResult(ControllerContext context)
的方法,该方法在内部对JsonSerializer
执行相同的序列化:
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
string.Equals(context.HttpContext.Request.HttpMethod,
"GET",
StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed);
}
HttpResponseBase response = context.HttpContext.Response;
if (!string.IsNullOrEmpty(this.ContentType))
{
response.ContentType = this.ContentType;
}
else
{
response.ContentType = "application/json";
}
if (this.ContentEncoding != null)
{
response.ContentEncoding = this.ContentEncoding;
}
if (this.Data != null)
{
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
if (this.MaxJsonLength.HasValue)
{
javaScriptSerializer.MaxJsonLength = this.MaxJsonLength.Value;
}
if (this.RecursionLimit.HasValue)
{
javaScriptSerializer.RecursionLimit = this.RecursionLimit.Value;
}
response.Write(javaScriptSerializer.Serialize(this.Data));
}
}
这基本上意味着您将DenyGet
作为默认参数传递,但您的方法是“GET”,最终会抛出InvalidOperationException
。您应该明确指定“AllowGet”以避免这种情况:
return Json(new PhoneSerializable(phone),
"application/json",
JsonRequestBehavior.AllowGet);