首页 新闻 会员 周边 捐助

上传出错:使用 IsOneWay=true 标记的操作不得声明输出参数、引用参数或返回

0
悬赏园豆:10 [已解决问题] 解决于 2013-08-07 16:10

WCF上传图片出错如题,但在本地测试的时候我上传没有问题,网站发布放到服务器上就出现这样的错误,请问是怎么回事?

WCF
浪潮之巅的主页 浪潮之巅 | 初学一级 | 园豆:83
提问于:2013-08-07 14:16
< >
分享
最佳答案
0

你看看你的那个接口申明了 IsOneWay ,但是却申明了输出参数、引用参数或返回。

收获园豆:10
Launcher | 高人七级 |园豆:45050 | 2013-08-07 14:20
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace UUCMS.UpFileWCFService
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IUpLoadService”。
    [ServiceContract]
    public interface IUpLoadService
    {
        [OperationContract(Action = "UploadFile", IsOneWay = true)]
        //jquery调用所需要
        //[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        //[OperationContract]
        void UploadFile(FileUploadMessage request);
    }


    [MessageContract]
    public class FileUploadMessage
    {
        [MessageHeader(MustUnderstand = true)]
        public string SavePath;

        [MessageHeader(MustUnderstand = true)]
        public string FileName;

        [MessageHeader(MustUnderstand = true)]
        public bool IsThumb;

        [MessageHeader(MustUnderstand = true)]
        public int ThumbWidth;

        [MessageHeader(MustUnderstand = true)]
        public int ThumbHeight;

        [MessageBodyMember(Order = 1)]
        public Stream FileData;

    }
}

这个代码没有输出参数、引用参数或返回,还有为什么在本地测试的时候上传正常的呢?

浪潮之巅 | 园豆:83 (初学一级) | 2013-08-07 14:23

@浪潮之巅: 看契约没什特别之处,你的 binding 设置了 transferMode="Streamed" 吗?出错的异常堆栈能打印出来吗?

Launcher | 园豆:45050 (高人七级) | 2013-08-07 14:34

@Launcher: 

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IUpLoadService"   receiveTimeout="10:10:10"  transferMode="Streamed" maxReceivedMessageSize="200000" messageEncoding="Mtom" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://image.51252.com/UpLoadService.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IUpLoadService"
                contract="UpFileWCFService.IUpLoadService" name="BasicHttpBinding_IUpLoadService" />
        </client>
    </system.serviceModel>
浪潮之巅 | 园豆:83 (初学一级) | 2013-08-07 14:42

@浪潮之巅: 客户端配置没啥问题。服务器的异常堆栈呢?在服务上启用trace功能,然后用 wcftraceview 找到错误的方法堆栈。

Launcher | 园豆:45050 (高人七级) | 2013-08-07 14:46

@Launcher: 才学着用 wcf 不知道怎么用wcftraceview 

浪潮之巅 | 园豆:83 (初学一级) | 2013-08-07 14:50

@Launcher: 我配置加上后出现:{"success":false,"message":"上传出错:无法加载操作“UploadFileAsync”,因为它具有类型为 System.ServiceModel.Channels.Message 的参数或返回类型,或具有一个带有 MessageContractAttribute 及其他不同类型参数的类型。当使用 System.ServiceModel.Channels.Message 或具有 MessageContractAttribute 的类型时,方法不应使用任何其他参数类型。"}

浪潮之巅 | 园豆:83 (初学一级) | 2013-08-07 15:13

@浪潮之巅: UploadFileAsync 这是你编写的服务方法吗?

Launcher | 园豆:45050 (高人七级) | 2013-08-07 15:15

@Launcher: 没有写啊

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace UUCMS.UpFileWCFService
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“UpLoadService”。
    // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 UpLoadService.svc 或 UpLoadService.svc.cs,然后开始调试。
    //[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class UpLoadService : IUpLoadService
    {
        public void UploadFile(FileUploadMessage request)
        {
            string savaPath = request.SavePath;
            string fileName = request.FileName;
            Stream sourceStream = request.FileData;
            FileStream targetStream = null;

            if (!sourceStream.CanRead)
            {
                throw new Exception("数据流不可读!");
            }
            if (savaPath == null) savaPath = @"/public/";
            if (!savaPath.StartsWith("/")) savaPath = "/" + savaPath;
            if (!savaPath.EndsWith("/")) savaPath += "/";

            string fileFolder = System.Web.Hosting.HostingEnvironment.MapPath(savaPath);
            if (!Directory.Exists(fileFolder))
            {
                Directory.CreateDirectory(fileFolder);
            }

            string filePath = Path.Combine(fileFolder, fileName);
            using (targetStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                //read from the input stream in 4K chunks
                //and save to output stream
                const int bufferLen = 4096;
                byte[] buffer = new byte[bufferLen];
                int count = 0;
                while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0)
                {
                    targetStream.Write(buffer, 0, count);
                }
                targetStream.Close();
                sourceStream.Close();
            }

            if (request.IsThumb)
            {
                ImageHelper.MakeThumbnail(filePath,
                        filePath.Replace(fileName, string.Format("{0}_{1}_{2}", request.ThumbWidth, request.ThumbHeight, fileName)),
                        request.ThumbWidth, request.ThumbHeight);
            }
        }
    }
}
浪潮之巅 | 园豆:83 (初学一级) | 2013-08-07 15:18

@浪潮之巅: 那你能把你的客户端代理类的代码贴一下吗?

Launcher | 园豆:45050 (高人七级) | 2013-08-07 15:19
<?xml version="1.0" encoding="utf-8"?>
<configuration>

    <system.web>
        <compilation debug="true" targetFramework="4.0" />
        <httpRuntime maxRequestLength="2097151"/>
    </system.web>
    <system.serviceModel>
        <diagnostics wmiProviderEnabled="true">
            <messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" />
        </diagnostics>
        <bindings>
            <basicHttpBinding>
                <binding name="FileTransferServicesBinding" maxReceivedMessageSize="9223372036854775807"
                          messageEncoding="Mtom" transferMode="Streamed" sendTimeout="10:10:00" ></binding>
            </basicHttpBinding>
        </bindings>
        <services>
            <service behaviorConfiguration="UUCMS.UpFileWCFService.UpLoadServiceBehavior" name="UUCMS.UpFileWCFService.UpLoadService">
                <endpoint address="" binding="basicHttpBinding" bindingConfiguration="FileTransferServicesBinding" contract="UUCMS.UpFileWCFService.IUpLoadService">
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            </service>
        </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="UUCMS.UpFileWCFService.UpLoadServiceBehavior">
                    <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false -->
                    <serviceMetadata httpGetEnabled="true"/>
                    <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
                    <serviceDebug includeExceptionDetailInFaults="false"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
    <system.webServer>
        <security>
            <requestFiltering >
                <!-- 设置上传最大数据为2G 此处设置最大只能是4G(4294967295)-->
                <requestLimits maxAllowedContentLength="2147483647" ></requestLimits>
            </requestFiltering>
        </security>
        <modules runAllManagedModulesForAllRequests="true"/>
        <!--
            若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。
            在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。
          -->
        <directoryBrowse enabled="true"/>
    </system.webServer>
    <!--跟踪节点配置-->
    <system.diagnostics>
        <sources>
            <source name="System.ServiceModel.MessageLogging" switchValue="警告,ActivityTracing">
                <listeners>
                    <add type="System.Diagnostics.DefaultTraceListener" name="Default">
                        <filter type="" />
                    </add>
                    <add name="ServiceModelMessageLoggingListener">
                        <filter type="" />
                    </add>
                </listeners>
            </source>
            <source propagateActivity="true" name="System.ServiceModel" switchValue="警告,ActivityTracing">
                <listeners>
                    <add type="System.Diagnostics.DefaultTraceListener" name="Default">
                        <filter type="" />
                    </add>
                    <add name="ServiceModelTraceListener">
                        <filter type="" />
                    </add>
                </listeners>
            </source>
        </sources>
        <sharedListeners>
            <add initializeData="D:\IDE\App_13882af0-5594-4989-bf95-d17c2f077ae1_messages.svclog"
                type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
                <filter type="" />
            </add>
            <add initializeData="D:\IDE\App_13882af0-5594-4989-bf95-d17c2f077ae1_tracelog.svclog"
                type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                name="ServiceModelTraceListener" traceOutputOptions="Timestamp">
                <filter type="" />
            </add>
        </sharedListeners>
        <trace autoflush="true" />
    </system.diagnostics>
</configuration>

这个webconfig配置有没有问题?怎么不能生成记录

@Launcher: 

浪潮之巅 | 园豆:83 (初学一级) | 2013-08-07 15:30

@浪潮之巅: 

UpLoadServiceClient client = new UpLoadServiceClient();
client.UploadFile(FileName, true, savePath, 100, 100, file.InputStream);

浪潮之巅 | 园豆:83 (初学一级) | 2013-08-07 15:32

@浪潮之巅: UpLoadServiceClient 你这个客户端没有生成正确,你选择服务引用的时候,在“添加服务引用”上点击“高级”,然后确保:“生成异步操作”没有被选中,“始终生成消息协定” 被选中。

最终你的 UpLoadServiceClient 的调用应该是这样:

UpLoadServiceClient client = new UpLoadServiceClient();

client.UploadFile(new FileUploadMessage(){FileName, true, savePath, 100, 100, file.InputStream});

Launcher | 园豆:45050 (高人七级) | 2013-08-07 15:39

@Launcher: 谢谢啊,终于可以了,但为什么在本地调用的时候没有这样的问题呢?

浪潮之巅 | 园豆:83 (初学一级) | 2013-08-07 15:48

@浪潮之巅: 你本地调用的时候,你仔细看一下你的vs的输出窗口,应该有first chance exception。

Launcher | 园豆:45050 (高人七级) | 2013-08-07 15:53
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册