c# - WCF 服务应用程序 : The operation must have a single parameter whose type is Stream

标签 c# visual-studio-2010 wcf web-services rest

<分区>

Possible Duplicate:
WCF Rest Webservice with stream

我正在使用 C# 开发 WCF .NET Framework 4.0。

我使用这个 Visual Studio 模板创建了这个 WCF:

enter image description here

我需要发送带有两个或三个参数的图像。这是我所有的OperationContract(我要的是最后一个):

[ServiceContract]
public interface IRestServiceImpl
{
    [OperationContract]
    [WebInvoke(Method = "GET",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare,
        UriTemplate = "orders/")]
    OrderContract[] allOrders();

    [OperationContract]
    [WebInvoke(Method = "POST",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare,
        UriTemplate = "filteredOrders/")]
    OrderContract[] GetOrders(IdsMessage msg);

    [OperationContract]
    [WebInvoke(Method = "POST",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare,
        UriTemplate = "completeFilteredOrders/")]
    OrderContract[] LoadCompleteFilteredOrders(IdsMessage msg);

    [OperationContract]
    [WebInvoke(Method = "POST",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare,
        UriTemplate = "saveEReports/")]
    Boolean SaveEReports(EReportContract[] eReports);

    [OperationContract]
    [WebInvoke(Method = "POST",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare,
        UriTemplate = "saveEReport/")]
    long SaveEReport(EReportContract eReport);

    [OperationContract]
    [WebInvoke(Method = "POST",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare,
        UriTemplate = "UploadPhoto/{eReportId}/{imageType}")]
    Boolean UploadPhoto(string eReportId, string imageType, Stream fileContents);
}

这是Web.config:

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="EReportService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour">
        <endpoint address="" binding="webHttpBinding" contract="EReportService.IRestServiceImpl" behaviorConfiguration="web">
        </endpoint>
      </service>
    </services>
    <bindings>
      <webHttpBinding>
        <binding maxReceivedMessageSize="2097152" maxBufferSize="2097152" transferMode="Streamed"/>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviour">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  <connectionStrings>

  </connectionStrings>
</configuration>

当我运行服务时,出现以下异常:

The operation must have a single parameter whose type is Stream

如果我这样做:

[OperationContract]
[WebInvoke(Method = "POST",
    ResponseFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.Bare,
    UriTemplate = "UploadPhoto")]
Boolean UploadPhoto(Stream fileContents);

它工作得很好,但我需要发送更多带有图像的数据。

此服务针对 Android 平板电脑应用程序公开。以下代码显示了我现在如何将图像发送到服务器:

public static Boolean sendImage(String url, String filePath)
{
    try
    {
        MultiValueMap<String, Object> formData;

        Resource resource = new FileSystemResource(filePath);

        // populate the data to post
        formData = new LinkedMultiValueMap<String, Object>();
        formData.add(OrderSpringController.FILE, resource);

        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setAccept(Collections.singletonList(new MediaType("application","json")));

        // Sending multipart/form-data
        requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

        // Populate the MultiValueMap being serialized and headers in an HttpEntity object to use for the request
        HttpEntity<MultiValueMap<String, Object>> requestEntity = 
                new HttpEntity<MultiValueMap<String, Object>>(formData, requestHeaders);

        GsonHttpMessageConverter messageConverter = new GsonHttpMessageConverter();
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
        messageConverters.add(messageConverter);

        // Create a new RestTemplate instance
        RestTemplate restTemplate = new RestTemplate(true);
        restTemplate.getMessageConverters().add(messageConverter);

        // Make the network request, posting the message, expecting a String in response from the server
        ResponseEntity<Boolean> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity,
                Boolean.class);

        // Return the response body to display to the user
        return response.getBody();
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
    return null;
}

浏览到元数据端点 (http://localhost:2351/RestServiceImpl.svc) 时发生错误。

如何发送图像和参数?

最佳答案

如果您切换到(BasicHttp 或 WSHttp)绑定(bind),那么您可以通过组合一个数据类型来实现您的目标,包括通过属性和 Stream 对象本身的所有自定义参数。那么您正在使用消息传递样式 而不是 RPC 对话。请注意 WCF DTO 装饰器的 [MessageContract] 系列。

[ServiceContract]
public interface ITransferService
{
    [OperationContract]
    RemoteFileInfo DownloadFile(DownloadRequest request);

    [OperationContract]
    void UploadFile(RemoteFileInfo request); 
}
[MessageContract]
public class DownloadRequest
{
    [MessageBodyMember]
    public string FileName;
}

[MessageContract]
public class RemoteFileInfo : IDisposable
{
    [MessageHeader(MustUnderstand = true)]
    public string FileName;

[MessageHeader(MustUnderstand = true)]
public long Length;

[MessageBodyMember]
public System.IO.Stream FileByteStream;

public void Dispose()
{ 
    if (FileByteStream != null)
    {
        FileByteStream.Close();
        FileByteStream = null;
    }
}   

这有必要的代码 http://www.codeproject.com/Articles/166763/WCF-Streaming-Upload-Download-Files-Over-HTTP

但我强烈建议WCF: using streaming with Message Contractshttp://blogs.msdn.com/b/carlosfigueira/archive/2011/03/25/wcf-streaming-inside-data-contracts.aspx

This也是必须的:)

关于c# - WCF 服务应用程序 : The operation must have a single parameter whose type is Stream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13601238/

相关文章:

c# - Web 配置中的连接字符串被忽略

C# 与 Java?

c# - 如何使乘法运算符(*)表现为短路?

c# - 如何将 Markdown (WMD)文本转换为纯文本

c++ - 将 vtkImageData 复制到 cv::Mat

visual-studio-2010 - C# 通过代码而不是 app.config 配置 LoadFromRemoteSources?

c# - DotNetOpenAuth 中 "ICryptoKeyStore"实现的具体职责是什么?

c# - 无法从其他类更改表单中的 textBox.text - C# - VS 2010

c# - 从 WCF FaultException 响应中提取详细信息

wcf - 使用 Svcutil 生成的类名出现问题