Как заставить WebMethods сериализовать ExpandoObject - PullRequest
5 голосов
/ 22 февраля 2012

У меня есть WebMethod, похожий на этот, который используется для заполнения jqGrid

[System.Web.Script.Services.ScriptService]
public class MyWebService: System.Web.Services.WebService
{
    [WebMethod]
    [Authorize(Roles = "Admin")]
    public object GetPeople(bool _search, double nd, int rows, int page, string sidx, string sord)
    {
        var tbl = new DynamicModel("ConnStr", tableName: "Person", primaryKeyField: "ID");
        var results = tbl.Paged(orderBy: sidx + " " + sord, currentPage: page, pageSize: rows);
        return results;
    }

}

«результатами» является System.Dynamic.ExpandoObject со свойствами Items, TotalPages, TotalRecords

Json, от которого я получаю ответ от веб-сервиса, выглядит следующим образом

{
"d": [{
    "Key": "TotalRecords",
    "Value": 1
}, {
    "Key": "TotalPages",
    "Value": 1
}, {
    "Key": "Items",
    "Value": [
        [{
            "Key": "Row",
            "Value": 1
        }, {
            "Key": "ID",
            "Value": 1
        }, {
            "Key": "Name",
            "Value": "Test Template"
        }]
    ]
}]
}
} // Don't know why firebug put this extra bracket

В идеале я бы предпочел, чтобы он возвращался без всего бизнеса «Ключ и значение», так как он излишне раздувает json и нехорошо играть с jqGrid.

Есть ли способ изменить способ, которым ASP.NET обрабатывает сериализацию ExpandoObject?

1 Ответ

4 голосов
/ 22 февраля 2012

Похоже, вы уже поняли это, но вот то, что я недавно бросил вместе , чтобы сделать именно это:

public class ExpandoObjectConverter : JavaScriptConverter {
  public override IEnumerable<Type> SupportedTypes {
    get { return new ReadOnlyCollection<Type>(new List<Type>(new Type[] { typeof(ExpandoObject) })); }
  }

  public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) {
    ExpandoObject expando = (ExpandoObject)obj;

    if (expando != null) {
      // Create the representation.
      Dictionary<string, object> result = new Dictionary<string, object>();

      foreach (KeyValuePair<string, object> item in expando) {
        if (item.Value.GetType() == typeof(DateTime))
          result.Add(item.Key, ((DateTime)item.Value).ToShortDateString());
        else
          result.Add(item.Key, item.Value.ToString());
      }

      return result;
    }
    return new Dictionary<string, object>();
  }

  public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
    return null;
  }
}

Затем вам просто нужно добавить его в раздел <converters> вашего web.config, как показано в статье MSDN, на которую вы ссылаетесь:

<configuration>
  <system.web.extensions>
    <scripting>
      <webServices>
        <jsonSerialization>
          <converters>
            <add name="ExpandoObjectConverter" type="ExpandoObjectConverter"/>
          </converters>
        </jsonSerialization>
      </webServices>
    </scripting>
  </system.web.extensions>
</configuration>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...