Remove internal "__type" tags in ASP.NET Restful WCF
I'm developing a RESTful WCF, and am currently having trouble getting nice, clean JSON-serialized return values.
A little while back, I got rid of "Key" and "Value" tags around each of my keys and values (caused by serializing a Dictionary<string, object>
object) by using a wrapper.
But when I did that, "__type" tags started showing up. I managed to get rid of the "d" tag, along with the first "__type" tag by replacing WebScriptServiceHostFactory with WebServiceHostFactory in the ServiceHost tag of my svc file.
So my result looks like this:
{"Status":"Success","Data":{"__type":"SerializableDictionaryOfstringanyType:#MyNamespace.MyFolder","Key1":"Value1","Key2":"Value2","Key3":"Value3"}}
But I want it to look like this:
{"Status":"Success","Data":{"Key1":"Value1","Key2":"Value2","Key3":"Value3"}}
My test webservice code looks like this:
[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);
}
EDIT: And the SuccessfulResult function looks like this (sorry for forgetting it):
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].ToStr开发者_如何学Going());
result.Add("Data", dct);
return result;
}
If anybody has any ideas on how I might get rid of that last little "__type" tag, I would love to hear them! Thanks very much, and let me know if there's anything else I can post that might be helpful.
Okay, fixed it up - but ended up doing things a little differently. WCF seems to insist on putting in those internal "__type" tags when it serializes Dictionaries, but for some reason, it doesn't do the same thing with Streams.
Here's the new webservice method code (just the return type has changed):
[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);
}
And here's the new SuccessfulResult function (which is what made the difference):
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);
}
Now the output looks exactly how I want it to look:
{"Status":"Success","Data":{"Key1":"Value1","Key2":"Value2","Key3":"Value3"}}
Anyway, I hope this example helps somebody else :)
In some case, the browser will treat response stream as binary, so, it will show download file popup. Then you should using:
string result = "Hello world";
byte[] resultBytes = Encoding.UTF8.GetBytes(result);
WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
return new MemoryStream(resultBytes);
I know that this was a long time ago, but I found a really simple way to make that possible.
In the Web.Config file you should change a line.
Use <webHttp/>
instead of <enableWebScript/>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
精彩评论