Удалите внутренние теги __type в ASP.NET Restful WCF - PullRequest
2 голосов
/ 01 октября 2011

Я разрабатываю RESTful WCF, и в настоящее время у меня возникают проблемы с получением хороших, чистых возвращаемых в JSON-последовательностей возвращаемых значений.

Некоторое время назад я избавился от тегов «Ключ» и «Значение» вокруг каждого из моих ключей и значений (вызванных сериализацией объекта Dictionary<string, object>) с помощью оболочки.

Но когда я это сделал, начали появляться теги "__type". Мне удалось избавиться от тега "d" вместе с первым тегом "__type", заменив WebScriptServiceHostFactory на WebServiceHostFactory в теге ServiceHost моего файла SVC.

Итак, мой результат выглядит так:

{"Status":"Success","Data":{"__type":"SerializableDictionaryOfstringanyType:#MyNamespace.MyFolder","Key1":"Value1","Key2":"Value2","Key3":"Value3"}}

Но я хочу, чтобы это выглядело так:

{"Status":"Success","Data":{"Key1":"Value1","Key2":"Value2","Key3":"Value3"}}

Мой тестовый код веб-сервиса выглядит так:

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public SerializableDictionary<string, object> Test1(String Token, String Id)
{
    DataTable testTable = new DataTable();
    testTable.Columns.Add("Key1", typeof(System.String));
    testTable.Columns.Add("Key2", typeof(System.String));
    testTable.Columns.Add("Key3", typeof(System.String));

    DataRow testRow = testTable.NewRow();
    testRow["Key1"] = "Value1";
    testRow["Key2"] = "Value2";
    testRow["Key3"] = "Value3";

    testTable.Rows.Add(testRow);

    return SuccessfulResult(testTable);
}

РЕДАКТИРОВАТЬ: И функция SuccessfulResult выглядит так (извините, что забыл об этом):

private SerializableDictionary<string, object> SuccessfulResult(DataTable dt = null)
{
    SerializableDictionary<string, object> result = new SerializableDictionary<string, object>();
    result.Add("Status", "Success");

    if (dt == null || dt.Rows.Count != 1)
        return result;

    SerializableDictionary<string, object> dct = new SerializableDictionary<string, object>();
    foreach (DataColumn currCol in dt.Rows[0].Table.Columns)
        dct.Add(currCol.ColumnName, dt.Rows[0][currCol.ColumnName].ToString());

    result.Add("Data", dct);

    return result;
}

Если у кого-нибудь есть идеи, как мне избавиться от этого последнего маленького тега "__type", я бы с удовольствием их услышал! Большое спасибо, и дайте мне знать, если я могу опубликовать что-нибудь еще, что может быть полезным.

Ответы [ 3 ]

1 голос
/ 05 октября 2011

Ладно, починили - но в итоге все делали немного по-другому.Кажется, WCF настаивает на добавлении этих внутренних тегов «__type», когда сериализует словари, но по какой-то причине он не делает то же самое с Streams.

Вот новый код метода веб-сервиса (изменился только тип возвращаемого значения):

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public Stream Test1(String Token, String StreamId)
{
    DataTable testTable = new DataTable();
    testTable.Columns.Add("Key1", typeof(System.String));
    testTable.Columns.Add("Key2", typeof(System.String));
    testTable.Columns.Add("Key3", typeof(System.String));

    DataRow testRow = testTable.NewRow();
    testRow["Key1"] = "Value1";
    testRow["Key2"] = "Value2";
    testRow["Key3"] = "Value3";

    testTable.Rows.Add(testRow);

    return SuccessfulResult(testTable);
}

А вот и новая функция SuccessfulResult (в этом и заключается разница):

private Stream SuccessfulResult(DataTable dt = null)
{
    Dictionary<string, object> returnDict = new Dictionary<string, object>();
    returnDict.Add("Status", "Success");

    Dictionary<string,object> dct = new Dictionary<string,object>();
    foreach (DataColumn currCol in dt.Rows[0].Table.Columns)
        dct.Add(currCol.ColumnName, dt.Rows[0][currCol.ColumnName].ToString());

    returnDict.Add("Data", dct);

    string sResponse = json.Serialize(returnDict);
    byte[] byResponse = Encoding.UTF8.GetBytes(sResponse);

    return new MemoryStream(byResponse);
}

Теперь вывод выглядит именно так, как я хочу:

{"Status":"Success","Data":{"Key1":"Value1","Key2":"Value2","Key3":"Value3"}}

В любом случае, я надеюсь, что этот пример поможет кому-то еще:)

0 голосов
/ 29 мая 2014

Я знаю, что это было давно, но я нашел действительно простой способ сделать это возможным.

В файле Web.Config вы должны изменить строку.

Используйте <webHttp/> вместо <enableWebScript/>

  <endpointBehaviors>
        <behavior>
          <webHttp />
        </behavior>
0 голосов
/ 25 июня 2012

В некоторых случаях браузер будет обрабатывать поток ответов как двоичный файл, поэтому он покажет всплывающее окно загрузки файла.Тогда вы должны использовать:

string result = "Hello world";
byte[] resultBytes = Encoding.UTF8.GetBytes(result);
WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
return new MemoryStream(resultBytes);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...