情景:
该服务接受GET请求,例如:
GET /endpoint/{resourcename}/?arg1=a&arg2=b&...
查询字符串参数可以根据resourcename而变化。我不想在具有特定UriTemplate
设置的界面中创建多个方法。
GET /SomeResource/?a=1&a=2&a=3
是有效请求。示例:
[WebGet(UriTemplate="/{resourcename}/???")]
[OperationContract]
Whatever DoTheThing(string resourcename, Dictionary<string, string> queryStringArgs)
答案 0 :(得分:3)
如果您可以接受这样的事实,即在调用方法时未填充tableView
,而是作为实施的第一步,这将有效:
queryStringArgs
这是界面注释的方式:
public string GetData(string value)
{
var utm = WebOperationContext.Current.IncomingRequest.UriTemplateMatch;
var queryStringArgs = new Dictionary<string, string>();
foreach(var query in utm.QueryParameters.AllKeys)
{
queryStringArgs.Add(query, utm.QueryParameters[query]);
}
return string.Format("You entered: {0} {1}", value, queryStringArgs);
}
当您抓住当前WebOperationContext
时,您可以访问[OperationContract]
[WebGet(UriTemplate = "/GetData/{value}")]
string GetData(string value);
上的UrlTemplateMatch
媒体资源。
通过迭代IncomingRequest
(NameValueCollection)的原始内容,您可以以自定义方式处理每个内容,其中一个可以将它们添加到字典中。
答案 1 :(得分:1)
您可以编写一个自定义QueryStringConverter
来接收所有查询字符串参数,并可以根据需要对其进行处理。这是最灵活的方式,但需要一些工作。
1。首先创建自定义QueryStringConverter
课程,如下所示:
public class CustomQueryStringConverter : System.ServiceModel.Dispatcher.QueryStringConverter
{
public override bool CanConvert(Type type)
{
if (type == typeof(Dictionary<string, string>))
return true;
// ELSE:
return base.CanConvert(type);
}
public override object ConvertStringToValue(string parameter, Type parameterType)
{
if (parameterType != typeof(Dictionary<string, string>))
return base.ConvertStringToValue(parameter, parameterType);
// ELSE (the type is Dictionary<string, string>)
if (parameter == null)
return new Dictionary<string, string>();
return JsonConvert.DeserializeObject<Dictionary<string, string>>(parameter);
}
}
2。其次,要在您的终端中使用此查询字符串转换器,您需要创建自定义WebHttpBehavior
并覆盖GetQueryStringConverter
以返回自定义查询字符串转换器,如下:
public sealed class CustomWebHttpBehavior : WebHttpBehavior
{
public CustomWebHttpBehavior()
{
// you can set default values for these properties here if you need to:
DefaultOutgoingResponseFormat = WebMessageFormat.Json;
AutomaticFormatSelectionEnabled = true;
DefaultBodyStyle = WebMessageBodyStyle.Bare;
HelpEnabled = true;
}
protected override System.ServiceModel.Dispatcher.QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
{
return new CustomQueryStringConverter();
}
}
3. 第三步是创建BehaviorExtensionElement
类,以便能够在wcf配置文件中注册自定义行为,如下所示:
public class CustomWebHttpBehaviorElement : BehaviorExtensionElement
{
public override System.Type BehaviorType
{
get { return typeof(CustomWebHttpBehavior); }
}
protected override object CreateBehavior()
{
return new CustomWebHttpBehavior();
}
}
4. 作为最后一步,您应该在wcf项目的web.config文件中注册自定义行为,如下所示:
<system.serviceModel>
...
<extensions>
<behaviorExtensions>
<add name="customWebHttpBehaviorElement" type="Your.Namespace.CustomWebHttpBehaviorElement, Your.Assembly" />
</behaviorExtensions>
</extensions>
...
<behaviors>
<endpointBehaviors>
<behavior name="RestServiceEndpointBehavior">
<customWebHttpBehaviorElement />
</behavior>
</endpointBehaviors>
</behaviors>
...
</system.serviceModel>
执行这些(不容易)步骤后,如果您使用RestServiceEndpointBehavior
作为端点的行为配置,则自定义查询字符串转换器将适用于该端点的所有请求。
编辑:我忘记提到的一点是你需要将你的查询字符串作为json对象传递:/SomeResource/?args={"a":1,"b"=2,"c"=3}
这意味着你的查询字符串只有1个参数(args)包含您的实际参数(a,b,c)。
编辑2: 您的服务方法如下所示:
public string DoTheThing(Dictionary<string, string> args)
{
var resourceName = "";
if(args.ContainsKey("resourceName"))
resourceName = args["resourceName"];
return string.Format("You entered: {0}", args);
}
合同就是这样的:
[WebInvoke(Method = "GET")]
[OperationContract]
string DoTheThing(Dictionary<string, string> args);
请注意,查询字符串中的参数名称"args"
应与服务方法中的参数名称匹配,否则无法正常工作。
此解决方案的好处是您不需要为每种服务方法使用UriTemplate,缺点是您应该将查询字符串转换为json格式,当然您也会丢失重复参数选项。
希望这有帮助。