2010-04-06 84 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