我的WCF服务有问题。似乎代码以意想不到的顺序执行。我的服务接受一个参数,该参数是具有文件附件(字节数组)和其他文本字段的数组的类。我的服务负责将这些文件保存在磁盘上。此外,每个服务和响应请求都记录在数据库中(以xml格式)。出于这个原因,我希望:
当我在visual studio中本地测试服务时(不使用服务客户端代理,而是直接服务),一切正常。 问题是我正在测试IIS上托管的服务(v 7.5)。在我的服务中,在磁盘上保存文件后,我正在使用文件名更改字段,使用文件的二进制数据清除字段。问题是系统在磁盘上保存文件之前更新这些字段(结果是保存的文件为空或错误是错误/错误保存路径/)。当然,在我的服务中,代码中的第一个任务是将文件保存在磁盘上。 这就是我的例子:
我正在使用VS2013,.NET Framework 4.5,WCF
附件类
public class Attachment
{
public string FilePath { get; set; }
public byte[] FileBinary { get; set; }
}
服务代码(对问题有一些评论):
public bool AddAttachments(List<Attachment> attachments)
{
bool result = false;
string PathToSaveFile = String.Empty;
string FileNameGuid = String.Empty;
foreach (var a in attachments)
{
FileNameGuid = Guid.NewGuid().ToString();
// step 1. Set file path and name
PathToSaveFile = "C:\\FilesFromWCFService\\" + FileNameGuid + a.FilePath;
try
{
// step 2. saving file
// problem is here. Variable PathToSaveFile have value from step 1 and 3b (which i thing has not yet been executed)
// so value is i.e.: "C:\FilesFromWCFService\{Guid}{FilePath}File localization: {PathToSaveFile}"
// and a.FileBinary is equal to byte[0] step 3a.
// it seems like steps 3a and 3b is executed before step 2
File.WriteAllBytes(PathToSaveFile, a.FileBinary);
result = true;
}
catch (Exception ex)
{
throw new Exception("Error while saving file on disk");
}
// step 3a. clear file binary data (that data won't be saved in db log)
a.FileBinary = new byte[0];
// step 3b. update file localization on server
a.FilePath = String.Format("File localization: {0}", PathToSaveFile);
// reset variables
PathToSaveFile = String.Empty;
FileNameGuid = String.Empty;
}
Return result;
}
当我在iis上调试服务时(通过在VS中附加iis进程)并在第一行服务代码上设置断点,我可以看到字节文件内容(a.FileBinary)和文件路径(a.FilePath)是从步骤3a和3b设置(不是参数列表附件中的原始。
如果我评论更改文件路径并重置文件内容(步骤3a和步骤3b),那么一切正常(但当然在日志中以二进制格式保存文件 - 我想避免使用)。
服务配置:
<services>
<service name="AddAttachments">
<endpoint address="AddAttachmentsService" behaviorConfiguration="ServiceEndpointBehavior"
binding="basicHttpBinding" name="httpEndpoint" contract="PlayService.IAddAttachmentsService" />
<endpoint address="AddAttachmentsService" behaviorConfiguration="ServiceEndpointBehavior"
binding="netTcpBinding" name="tcpEndpoint" contract="PlayService.IAddAttachmentsService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:65045/" />
<add baseAddress="net.tcp://localhost:65055/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding messageEncoding="Mtom"
closeTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferPoolSize="524288"
maxReceivedMessageSize="2147483647">
</binding>
</basicHttpBinding>
<netTcpBinding>
<binding transferMode="Streamed"
closeTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferPoolSize="524288"
maxReceivedMessageSize="2147483647"></binding>
</netTcpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ServiceEndpointBehavior" >
<logMessage_2 />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
客户端配置:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="httpEndpoint" messageEncoding="Mtom"
closeTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferPoolSize="524288"
maxReceivedMessageSize="2147483647"></binding>
<!--<binding name="httpEndpoint" messageEncoding="Mtom" />-->
</basicHttpBinding>
<netTcpBinding>
<binding name="tcpEndpoint"
closeTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferPoolSize="524288"
maxReceivedMessageSize="2147483647"></binding>
<!--<binding name="tcpEndpoint" transferMode="Streamed" />-->
</netTcpBinding>
</bindings>
<client>
<endpoint address="http://localhost/MyService/MyService.svc/AddAttachmentsService"
binding="basicHttpBinding" bindingConfiguration="httpEndpoint"
contract="PService.IAddAttachmentsService" name="httpEndpoint" />
<endpoint address="net.tcp://myComp/MyService/PlayService.svc/AddAttachmentsService"
binding="netTcpBinding" bindingConfiguration="tcpEndpoint"
contract="PService.IAddAttachmentsService" name="tcpEndpoint">
<identity>
<servicePrincipalName value="host/MyComp" />
</identity>
</endpoint>
</client>
</system.serviceModel>
当我使用netTcpBinding或basicHttpBinding时,问题是一样的。
我是WCF的新手,我不知道我还能在网上搜索什么。我读过有关流媒体的信息(当我在Streamed上设置transferMode时没有区别),关于并发性和实例化(我设置了不同的选项 - 但我认为这与此问题无关)。
如果我收到的信息很少,请告诉我。
答案 0 :(得分:0)
好的,我发现了问题所在:
当我测试我的服务时,我将参数(对象)传递给第一次服务调用,然后传递给服务的第二次调用(但是第一次调用时对象被更改了) - 我忘记了对象是通过引用传递:)
我发现我无法在服务调用中更改消息(用于记录目的) - 我通过消息检查器(方法AfterReceiveRequest)记录消息,该消息检查器早于服务执行调用。