WCF Webservice 将 messagecontract 与 Stream 和 return 字符串传递给 Client

WCF Webservice pass messagecontract with Stream and return a string to Client

我想创建 WCF web 服务来重新计算 .xlsx 和 .xls 文件的公式(想确定服务中的扩展类型和 return 将处理后的文件 ID 返回给客户端,然后另一个服务方法来从 returned fileID

获取文件

但是我没能实现我的第一个方法。

我创建的服务如下

对象/消息合约

[MessageContract]
    public class UploadStreamMessage
    {
        [MessageHeader]
        public string fileName;
        [MessageBodyMember]
        public Stream fileContents;
    }

界面

[OperationContract]
[WebInvoke(UriTemplate = "/UploadFile")]
string UploadFile(UploadStreamMessage message);

[OperationContract]
Stream ReturnFile(string GUID);

服务方式

public string UploadFile(UploadStreamMessage message)
{
   string FileId = Guid.NewGuid().ToString();
   //Get fie stream and determin the extension type and save in server and return Saved file Id
   return FileId;
}
public Stream ReturnFile(string GUID)
{
   Stream generatedFileStream = null;
   //Get fie using Id and create stream and send back
   return generatedFileStream;
}

Web.Config

<bindings>
        <webHttpBinding>
            <binding name="webHttpBinding" transferMode="Streamed"/>
        </webHttpBinding>
    </bindings>
    <behaviors>
        <endpointBehaviors>
            <behavior name="webHttpBehavior">
                <webHttp/>
            </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior>
                <!--<behavior name="ServiceBehavior">-->
                <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <serviceThrottling maxConcurrentCalls="2147483647"  maxConcurrentSessions="2147483647"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

期望: ReturnFile:工作正常,结果符合预期 UploadFile : 当我尝试 运行 下面的 UploadFile 方法时发生异常。

The operation 'UploadFile' could not be loaded because it has a parameter or return type of type System.ServiceModel.Channels.Message or a type that has MessageContractAttribute and other parameters of different types. When using System.ServiceModel.Channels.Message or types with MessageContractAttribute, the method must not use any other types of parameters. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

所以我浏览了 Whosebug 并找到了以下线程 How to return value using WCF's MessageContract? , WCF - Return Object With Stream Data , Use of MessageContract crashes WCF service on startup 发现我在发送消息合同时无法 return 返回字符串值,但可以 return 另一个 MessageContract.through 网络服务方法。

所以我更改了我的代码如下 向消息合约添加了一个新参数(returnFileName),我需要return给客户端:

[MessageContract]
    public class UploadStreamMessage
    {
        [MessageHeader]
        public string fileName;
        [MessageBodyMember]
        public Stream fileContents;
        [MessageHeader]
        public string returnFileName;
    }

接口和方法如下: 接口:

[OperationContract]
        [WebInvoke(UriTemplate = "/UploadFile")]
        UploadStreamMessage UploadFile(UploadStreamMessage message);

服务方式:

public UploadStreamMessage UploadFile(UploadStreamMessage message)
        {
            message.returnFileName = Guid.NewGuid().ToString();
            string FileId = Guid.NewGuid().ToString();
            //Get fie stream and determin the extension type and save in server and return Saved file Id
            return message;
        }

客户端应用:

static void Main(string[] args)
        {
            ServiceReferenceFile.FileServiceClient Client = new ServiceReferenceFile.FileServiceClient();
            ServiceReferenceFile.UploadStreamMessage message = new ServiceReferenceFile.UploadStreamMessage();
            string fileName = "FileName", outputFile ="";
            Stream str = File.OpenRead("DummyDataFile.xlsx");
            message = Client.UploadFile(ref fileName, ref outputFile, ref str);
        }

但它仍然给我错误,它不允许获取 return 对象:

Cannot implicitly convert type 'void' to 'ConsoleAppFileAction.ServiceReferenceFile.UploadStreamMessage'

请有人告诉我我在做什么错误?

我能够根据@Steeeve 的说明管理代码,并且得到了预期的结果。 对象/消息合约

[MessageContract]
//It is same as UploadStreamMessage
public class UploadFileRequest
{
  [MessageHeader]
  public string fileName;

  [MessageBodyMember]
  public Stream fileContents;
}

[MessageContract]
public class UploadFileResponse
{
  [MessageBodyMember]
  public string ProcessedFileName;

  [MessageBodyMember]
  public string ProcessedFileNameDetails;
}

接口:

[OperationContract]
UploadFileResponse UploadFile(UploadFileRequest message);

服务方式

public UploadFileResponse UploadFile(UploadFileRequest fileRequest)
{
  UploadFileResponse resp = new UploadFileResponse();
  LogicClass logics = new LogicClass();
  resp.ProcessedFileNameDetails = logics.GetExcelFileMain(fileRequest);
  return resp;
}

客户端应用程序: Webservice 返回的文件名可以作为输出参数获取。

ServiceReferenceExcelRefersh.FileServiceClient fileServiceClient = new ServiceReferenceExcelRefersh.FileServiceClient();
    
fileServiceClient.UploadFile(fileName, fileStream, out string ProcessedFileNameDetails);