【问题标题】:WCF Webservice pass messagecontract with Stream and return a string to ClientWCF Webservice 使用 Stream 传递消息合同并将字符串返回给客户端
【发布时间】:2021-11-07 13:56:57
【问题描述】:

我想创建 WCF Web 服务来重新计算 .xlsx 和 .xls 文件的公式(想确定服务中的扩展类型并将处理后的 fileID 返回给客户端,然后使用另一个服务方法从返回的 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 方法时,出现以下异常。

无法加载操作“UploadFile”,因为它有一个 System.ServiceModel.Channels.Message 类型的参数或返回类型 或具有 MessageContractAttribute 和其他参数的类型 不同种类。当使用 System.ServiceModel.Channels.Message 或 具有 MessageContractAttribute 的类型,该方法不得使用任何其他 参数类型。描述:发生未处理的异常 在当前 Web 请求执行期间。请查看 堆栈跟踪以获取有关错误及其位置的更多信息 源于代码。

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

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

[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);
        }

但它仍然给我提供了错误并且它不允许获取返回对象:

无法将类型“void”隐式转换为 'ConsoleAppFileAction.ServiceReferenceFile.UploadStreamMessage'

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

【问题讨论】:

  • UploadStreamMessage2的定义是什么?只需创建两个类,一个UploadFileRequest(您原来的UploadStreamMessage)和UploadFileResponse(作为您的UploadFile 方法的返回值)。只分别添加相关属性,不要混用参数和返回值。将 MessageContract 属性应用于它们,不要忘记更新您的服务参考。
  • 亲爱的@Steeeve:它(UploadStreamMessage2)被错误地添加到这里。我编辑了原始问题。感谢您的回答,我将尝试为请求和响应创建两个 MessageContract。谢谢
  • 添加属性并将 MessageContract 分配给它们。
  • 谢谢@Jiayao 我能做到。非常感谢您的贡献
  • @Steeeve 在您的评论的帮助下,我得到了结果。非常感谢

标签: c# wcf stream messagecontract wcf-streaming


【解决方案1】:

我能够根据@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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-19
    • 2013-03-17
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 2017-04-02
    相关资源
    最近更新 更多