2010-04-06 62 views
3

我正在接受ASP.NET MVC How to pass JSON object from View to Controller as Parameter的接受答案。像原来的问题一样,我有一个简单的POCO。DataContractJsonSerializer读取对象异常

Everthing对我来说很好,直到DataContractJsonSerializer.ReadObject方法。我得到以下异常:

期待元素从 命名空间“根”“” ..遇到“无” 名为“”,命名空间'。

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 

任何想法?

回答

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>))] 
4

可能不适合这个问题,但是这帮助我,并可能帮助其他有此异常 - 尝试之前重置流阅读它。

s.Position = 0