Контроллер ASP.NET MVC 3. Сериализация метода .Json не рассматривает атрибут имени DataMember - PullRequest
4 голосов
/ 16 мая 2011

В моем классе у меня есть:

[DataMember(Name = "jsonMemberName", EmitDefaultValue = false, 
    IsRequired = false)]
public List<string> Member { get; set; }

После прохождения объекта через Json (obj) контроллера, который перезапускает System.Web.Mvc.JsonResult: у меня есть сериализованный json: {Member:...} но не {jsonMemberName: ...}, поэтому он не смотрит на DataMember (Name = "jsonMemberName").

Если я использую сериализацию из работ System.Runtime.Serialization.Json everithingв порядке, как и ожидалось.

Что может быть не так?

Ответы [ 2 ]

12 голосов
/ 16 мая 2011

Действие JsonResult , которое вы возвращаете из действия контроллера (используя return Json(...)), внутренне опирается на класс JavaScriptSerializer .Этот класс не учитывает атрибуты DataMember в вашей модели.

Вы можете написать собственный ActionResult, который использует сериализатор в пространстве имен System.Runtime.Serialization.Json.

Например:

public class MyJsonResult : JsonResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        if (!string.IsNullOrEmpty(ContentType))
        {
            response.ContentType = ContentType;
        }
        else
        {
            response.ContentType = "application/json";
        }
        if (ContentEncoding != null)
        {
            response.ContentEncoding = this.ContentEncoding;
        }
        if (Data != null)
        {
            var serializer = new DataContractJsonSerializer(Data.GetType());
            serializer.WriteObject(response.OutputStream, Data);
        }
    }
}

и затем в действии вашего контроллера:

public ActionResult Foo()
{
    var model = ...
    return new MyJsonResult { Data = model };
}
2 голосов
/ 16 мая 2011

System.Web.Mvc.JsonResult использует старый класс JavaScriptSerializer, который ничего не знает о сборке DataAnnotiations. Вам нужно использовать DataContractJsonSerializer .

Вы можете использовать это вместо этого в JsonResult, если хотите:

public class DataContractJsonResult : JsonResult
{
    public DataContractJsonResult(object data)
    {
        Data = data;
    }

    public DataContractJsonResult()
    {
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
            String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
        }

        HttpResponseBase response = context.HttpContext.Response;

        if (!string.IsNullOrEmpty(ContentType))
        {
            response.ContentType = ContentType;
        }
        else
        {
            response.ContentType = "application/json";
        }
        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }
        if (Data != null)
        {
            var serializer = new DataContractJsonSerializer(Data.GetType());
            var ms = new MemoryStream();
            serializer.WriteObject(ms, Data);
            string json = Encoding.UTF8.GetString(ms.ToArray());
            response.Write(json);
        }
    }
}

(Я ссылался на исходный код ASP.NET MVC, чтобы создать это. Не уверен, если мне придется каким-то образом поверить в это. Что ж, больше, чем это в стороне, то есть.

Вы также можете добавить это к базовому классу, от которого наследуются ваши контроллеры:

protected JsonResult DataContractJson(object data)
{
    return new DataContractJsonResult(data);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...