DataContractJsonSerializer ReadObject异常

时间:2010-04-06 18:04:19

标签: asp.net-mvc json

我正在按照ASP.NET MVC How to pass JSON object from View to Controller as Parameter的接受答案。像原始问题一样,我有一个简单的POCO。

直到DataContractJsonSerializer.ReadObject方法,Everthing才能正常工作。我得到以下例外:

  

期待元素'root'来自   namespace''..遇到'无'   名称为'',名称空间''。

 Public Overrides Sub OnActionExecuting(ByVal filterContext As ActionExecutingContext)
    If filterContext.HttpContext.Request.ContentType.Contains("application/json") Then
        Dim s As System.IO.Stream = filterContext.HttpContext.Request.InputStream

        Dim o = New DataContractJsonSerializer(RootType).ReadObject(s)

        filterContext.ActionParameters(Param) = o
    Else
        Dim xmlRoot = XElement.Load(New StreamReader(filterContext.HttpContext.Request.InputStream, filterContext.HttpContext.Request.ContentEncoding))
        Dim o As Object = New XmlSerializer(RootType).Deserialize(xmlRoot.CreateReader)
        filterContext.ActionParameters(Param) = o
    End If
End Sub

有什么想法吗?

2 个答案:

答案 0 :(得分:7)

您可能需要确保在poco上应用[DataContract][DataMember]属性。

作为一个单独的选项,您可能需要考虑我为mvc ControllerContext编写的扩展方法:

using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;

public static class MvcExtensions
{
    public static T DeserializeJson<T>(this ControllerContext context)
    {
        var serializer = new JavaScriptSerializer();
        var form = context.RequestContext.HttpContext.Request.Form.ToString();
        return serializer.Deserialize<T>(HttpUtility.UrlDecode(form));
    }
}

它允许您使用JavaScriptSerializer轻松反序列化json,如下所示:

var myInstance = controllerContext.DeserializeJson<MyClass>();

或者,甚至更简单,您可以制作通用模型装订器:

public class JsonBinder<T> : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        return controllerContext.DeserializeJson<T>();
    }
}

然后通过将此属性应用于poco类来强烈键入您的mvc操作方法:

[ModelBinder(typeof(JsonBinder<MyClass>))]

答案 1 :(得分:5)

可能不适合这个问题,但这有助于我并可能帮助其他人解决此异常 - 尝试在阅读之前重置您的信息流。

s.Position = 0