你看看你的那个接口申明了 IsOneWay ,但是却申明了输出参数、引用参数或返回。
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; } }
这个代码没有输出参数、引用参数或返回,还有为什么在本地测试的时候上传正常的呢?
@浪潮之巅: 看契约没什特别之处,你的 binding 设置了 transferMode="Streamed" 吗?出错的异常堆栈能打印出来吗?
@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>
@浪潮之巅: 客户端配置没啥问题。服务器的异常堆栈呢?在服务上启用trace功能,然后用 wcftraceview 找到错误的方法堆栈。
@Launcher: 才学着用 wcf 不知道怎么用wcftraceview
@Launcher: 我配置加上后出现:{"success":false,"message":"上传出错:无法加载操作“UploadFileAsync”,因为它具有类型为 System.ServiceModel.Channels.Message 的参数或返回类型,或具有一个带有 MessageContractAttribute 及其他不同类型参数的类型。当使用 System.ServiceModel.Channels.Message 或具有 MessageContractAttribute 的类型时,方法不应使用任何其他参数类型。"}
@浪潮之巅: UploadFileAsync 这是你编写的服务方法吗?
@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); } } } }
@浪潮之巅: 那你能把你的客户端代理类的代码贴一下吗?
<?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:
@浪潮之巅:
UpLoadServiceClient client = new UpLoadServiceClient();
client.UploadFile(FileName, true, savePath, 100, 100, file.InputStream);
@浪潮之巅: UpLoadServiceClient 你这个客户端没有生成正确,你选择服务引用的时候,在“添加服务引用”上点击“高级”,然后确保:“生成异步操作”没有被选中,“始终生成消息协定” 被选中。
最终你的 UpLoadServiceClient 的调用应该是这样:
UpLoadServiceClient client = new UpLoadServiceClient();
client.UploadFile(new FileUploadMessage(){FileName, true, savePath, 100, 100, file.InputStream});
@Launcher: 谢谢啊,终于可以了,但为什么在本地调用的时候没有这样的问题呢?
@浪潮之巅: 你本地调用的时候,你仔细看一下你的vs的输出窗口,应该有first chance exception。