我正在开发一个需要接收图像和2个参数的WCF服务。一个是int类型,另一个是字符串数组。因此,如果只发送一个参数,那么这将很容易,以及图像:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "UploadImages/{imageID}")]
public void UploadImages(int imageID, Stream image)
{
}
现在,在这种情况下,图像位于帖子的正文中。如果服务的消费者需要传递第三条数据,那么它在WCF中的外观和工作方式会怎样?
<system.serviceModel>
<client>
</client>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingStreamed" transferMode="Streamed"></binding>
</webHttpBinding>
</bindings>
<services>
<service name="ImageService">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="MyWebHttpBehavior" name="ImageServiceWebBinding" contract=IImageService" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="MyWebHttpBehavior">
<customWebHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="customWebHttp" type="CustomHttpBehaviorExtensionElement, ImageUploader" />
</behaviorExtensions>
</extensions>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
答案 0 :(得分:2)
您也可以在URI中传递其他参数,如下例所示。或者您可以将它们作为HTTP标头传递,并使用WebOperationContext.Current.IncomingRequest.Headers
属性获取它们。
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "UploadImages/{fileName}?imageId={imageID}")]
public void UploadImages(int imageID, string fileName, Stream image)
{
}
<强>更新强>
即使参数类型是数组,您也可以在查询字符串中传递它 - 但是您需要提供可以解码该类型的QueryStringConverter
。以下示例显示了。
public class StackOverflow_6905108
{
[ServiceContract]
public class Service
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "UploadImages/{fileName}?array={array}")]
public void UploadImages(int[] array, string fileName, Stream image)
{
Console.WriteLine("Array:");
foreach (var item in array) Console.Write("{0} ", item);
Console.WriteLine();
}
}
public static void SendPost(string uri, string contentType, string body)
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
req.Method = "POST";
req.ContentType = contentType;
Stream reqStream = req.GetRequestStream();
byte[] reqBytes = Encoding.UTF8.GetBytes(body);
reqStream.Write(reqBytes, 0, reqBytes.Length);
reqStream.Close();
HttpWebResponse resp;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch (WebException e)
{
resp = (HttpWebResponse)e.Response;
}
Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
foreach (string headerName in resp.Headers.AllKeys)
{
Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
}
Console.WriteLine();
Stream respStream = resp.GetResponseStream();
Console.WriteLine(new StreamReader(respStream).ReadToEnd());
Console.WriteLine();
Console.WriteLine(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* ");
Console.WriteLine();
}
class MyQueryStringConverter : QueryStringConverter
{
QueryStringConverter originalConverter;
public MyQueryStringConverter(QueryStringConverter originalConverter)
{
this.originalConverter = originalConverter;
}
public override bool CanConvert(Type type)
{
return type == typeof(int[]) || base.CanConvert(type);
}
public override object ConvertStringToValue(string parameter, Type parameterType)
{
if (parameterType == typeof(int[]))
{
return parameter.Split(',').Select(x => int.Parse(x)).ToArray();
}
else
{
return base.ConvertStringToValue(parameter, parameterType);
}
}
}
public class MyWebHttpBehavior : WebHttpBehavior
{
protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
{
return new MyQueryStringConverter(base.GetQueryStringConverter(operationDescription));
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "").Behaviors.Add(new MyWebHttpBehavior());
host.Open();
Console.WriteLine("Host opened");
SendPost(baseAddress + "/UploadImages/a.txt?array=1,2,3,4", "application/octet-stream", "The file contents");
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}