【问题标题】:Remove internal "__type" tags in ASP.NET Restful WCF删除 ASP.NET Restful WCF 中的内部“__type”标签
【发布时间】:2011-09-30 20:39:14
【问题描述】:

我正在开发一个 RESTful WCF,但目前无法获得漂亮、干净的 JSON 序列化返回值。

A little while back, I got rid of "Key" and "Value" tags 使用包装器围绕我的每个键和值(由序列化 Dictionary<string, object> 对象引起)。

但是当我这样做时,“__type”标签开始出现。通过在我的 svc 文件的 ServiceHost 标记中将 WebScriptServiceHostFactory 替换为 WebServiceHostFactory,我设法摆脱了“d”标记以及第一个“__type”标记。

所以我的结果是这样的:

{"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);
}

编辑: SuccessResult 函数如下所示(抱歉忘记了):

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”标签有任何想法,我很想听听他们的意见!非常感谢,如果我可以发布任何其他可能对您有帮助的内容,请告诉我。

【问题讨论】:

    标签: asp.net json rest serialization


    【解决方案1】:

    好的,已解决 - 但最终做事略有不同。 WCF 似乎坚持在序列化字典时放入那些内部的“__type”标签,但由于某种原因,它对 Streams 没有做同样的事情。

    这是新的 webservice 方法代码(只是返回类型发生了变化):

    [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);
    }
    

    这是新的 SuccessResult 函数(这就是与众不同的地方):

    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"}}
    

    无论如何,我希望这个例子对其他人有帮助:)

    【讨论】:

    • 这是一个很好的技巧,但必须有一种更“内置”的方式来做到这一点。 :-/
    • 它绝对有效,一点点配置使它变得简单和即时功能。重点是 -> byte[] byResponse = Encoding.UTF8.GetBytes(string); return new MemoryStream(byResponse);
    【解决方案2】:

    在某些情况下,浏览器会将响应流视为二进制,因此,它会显示下载文件弹出窗口。 那么你应该使用:

    string result = "Hello world";
    byte[] resultBytes = Encoding.UTF8.GetBytes(result);
    WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
    return new MemoryStream(resultBytes);
    

    【讨论】:

      【解决方案3】:

      我知道这是很久以前的事了,但我找到了一种非常简单的方法来实现它。

      在 Web.Config 文件中,您应该更改一行。

      使用&lt;webHttp/&gt; 而不是&lt;enableWebScript/&gt;

        <endpointBehaviors>
              <behavior>
                <webHttp />
              </behavior>
      

      【讨论】:

      • 反之,应该使用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      相关资源
      最近更新 更多