我正在尝试编写符合OpenSearch规范的OpenSearch Suggestion服务。
http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions
此规范要求服务返回JSON数组,第一个元素是字符串,以下元素是字符串数组。我可以通过返回一个字符串数组(string [] [])并让WCF将其序列化为JSON来获得它。但是,为了符合规范,我试图返回一个对象数组(object []),第一个是字符串,其余的是字符串数组(string [])。
每当我尝试返回对象数组时,它都不起作用,例如:
来自服务:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SuggestionService : ISuggestionService
{
public object[] Search(string searchTerms)
{
SearchSuggestions = new object[4];
SearchText = searchTerms;
SearchSuggestions[0] = SearchText;
Text = new string[10];
Urls = new string[10];
Descriptions = new string[10];
// Removed irrelevant ADO.NET code
while (searchResultReader.Read() && index < 10)
{
Text[index] = searchResultReader["Company"].ToString();
Descriptions[index] = searchResultReader["Company"].ToString();
Urls[index] = "http://dev.localhost/Customers/EditCustomer.aspx?id=" +
searchResultReader["idCustomer"];
index++;
}
SearchSuggestions[1] = Text;
SearchSuggestions[2] = Descriptions;
SearchSuggestions[3] = Urls;
return SearchSuggestions;
}
[DataMember]
public string SearchText { get; set; }
[DataMember]
public string[] Text { get; set; }
[DataMember]
public string[] Descriptions { get; set; }
[DataMember]
public string[] Urls { get; set; }
[DataMember]
public object[] SearchSuggestions { get; set; }
}
这是整个界面:
[ServiceContract]
public interface ISuggestionService
{
[OperationContract]
[WebGet(UriTemplate = "/Search?q={searchTerms}",
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json)]
object[] Search(string searchTerms);
}
这会导致服务返回“错误324(net :: ERR_EMPTY_RESPONSE):未知错误。”这是我唯一能得到的错误。
我无法使用对象数组存储一个字符串和三个数组吗?为了使用WCF返回符合此规范的正确JSON,我还能做些什么?
编辑:添加了更多代码
答案 0 :(得分:5)
你发布了一堆[DataMember]的。请发布整个[DataContract]。同时向我们展示返回DataContract时返回的JSON。
数据合同不应包含行为。尝试以下(我没有机会测试它,并且需要假装数据来执行此操作):
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SuggestionService : ISuggestionService
{
public SearchResults Search(string searchTerms)
{
var results = new SearchResults
{
SearchText = searchTerms,
Text = new string[10],
Urls = new string[10],
Descriptions = new string[10]
};
// Removed irrelevant ADO.NET code
int index = 0;
while (searchResultReader.Read() && index < 10)
{
results.Text[index] = searchResultReader["Company"].ToString();
results.Descriptions[index] = searchResultReader["Company"].ToString();
results.Urls[index] = "http://dev.localhost/Customers/EditCustomer.aspx?id=" +
searchResultReader["idCustomer"];
index++;
}
return results;
}
}
[DataContract]
public class SearchResults
{
[DataMember]
public string SearchText { get; set; }
[DataMember]
public string[] Text { get; set; }
[DataMember]
public string[] Descriptions { get; set; }
[DataMember]
public string[] Urls { get; set; }
}
好的,我已经阅读了足够的规范和JSON规范,以说服自己确实需要返回一个对象数组,而不是一个包含对象数组的类的实例。当然,这并不是很有效。这就是你需要的:
[ServiceContract]
[ServiceKnownType(typeof(string))]
[ServiceKnownType(typeof(string[]))]
public interface ISuggestionService
{
[OperationContract]
[WebGet(UriTemplate = "/Search?q={searchTerms}",
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json)]
object[] Search(string searchTerms);
}
我刚刚尝试过它,它有效。这是JSON(添加了缩进):
[
"abc",
["Company1","Company2","Company3",...],
["Company1 Description","Company2 Description","Company3 Description",...],
["http:\/\/dev.localhost\/Customers\/EditCustomer.aspx?id=1",
"http:\/\/dev.localhost\/Customers\/EditCustomer.aspx?id=2",
"http:\/\/dev.localhost\/Customers\/EditCustomer.aspx?id=3",...]
]
答案 1 :(得分:2)
这个问题让我感到困惑了一段时间 - 有一个完整的端到端演练如何执行此操作,包括如何支持JSON和XML opensearch(包括XML属性序列化),可下载代码,位于“Building Labs – Writing an OpenSearch Suggestions provider in C# with WCF”。