需要上传图像和多个参数的RESTful WCF服务

时间:2011-08-01 22:10:18

标签: .net wcf rest

我正在开发一个需要接收图像和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>

1 个答案:

答案 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();
    }
}