DataContractJsonSerializer ReadObject Exception - PullRequest
3 голосов
/ 06 апреля 2010

Я следую принятому ответу ASP.NET MVC Как передать объект JSON из View в Controller в качестве параметра .Как и в первоначальном вопросе, у меня есть простой POCO.

Все работает хорошо до меня, вплоть до метода DataContractJsonSerializer.ReadObject.Я получаю следующее исключение:

Ожидается элемент 'root' из пространства имен '' .. Обнаружен 'Нет' с именем '', пространство имен ''.

 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 ]

7 голосов
/ 06 апреля 2010

вам может потребоваться применить атрибуты [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));
    }
}

Позволяет легко десериализовать JSON с помощью JavaScriptSerializer следующим образом:

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

Или, что еще проще, вы можете сделать общее связующее для модели:

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

А затем строго введите свой метод действия mvc, применив этот атрибут к классу poco:

[ModelBinder(typeof(JsonBinder<MyClass>))]
5 голосов
/ 02 мая 2013

Может не подойти к этому вопросу, но это помогло мне и могло бы помочь другим с этим исключением - попробуйте сбросить ваш поток перед его чтением.

s.Position = 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...