我必须开发一个能够发送带有附件的电子邮件的web服务,以及一个使用wcf和mtom进行序列化的客户端。我使用以下工具进行工作:
Windows 7 Professional x64Microsoft Visual Studio 2012Microsoft Development Server/IIS Express 8.0用户:管理员
每次我尝试在客户端中使用消息协定中自定义类的Web服务时,我都会收到错误"接收到对http://localhost:2364/Service1.svc
的HTTP响应时出错。这可能是由于服务端点绑定未使用HTTP协议。这也可能是由于服务器中止了HTTP请求上下文(可能是由于服务关闭)。有关详细信息,请参阅服务器日志。
现在,我只是尝试设置一个简单的测试服务和一个简单测试客户端。我尝试了以下事情,但总是得到相同的错误,而使用Web服务中只在请求和响应中使用简单字符串的方法工作得很好,没有任何错误。
-
Visual Studio 2012和IIS Express 8.0 中集成的Microsoft Development Server上出现相同错误
-
在客户端和服务的配置中使用basicHttpBinding或wsHttpBinding时出现相同错误
-
已尝试在两台服务器上生成日志文件。IIS Express Server会在其他文件夹中生成一些日志,而不是使用配置文件中的设置。Microsoft Development Server不会生成任何内容。
-
我使用svctraceviewer.exe查看了少数生成的日志文件,只看到了一些操作码为MODULE_SET_RESPONSE_ERROR_STATUS的警告。我无法理解这些信息。
-
我尝试为localService和networkService启用对指定文件夹的读/写权限,但没有结果。
-
我试图使用RawCap探查localhost并使用wireshark查看结果,但输出文件有0个字节(这肯定是另一个问题)。
如果您需要更多信息,请告诉我。
谢谢!
以下是我的服务和客户端代码和配置(仅用于测试):
服务:IService1.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.IO;
namespace WcfTestService
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
/*
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);*/
// TODO: Hier Dienstvorgänge hinzufügen
[OperationContract]
ServiceResponse TestCase(ServiceRequest testRequest);
}
/*
// Verwenden Sie einen Datenvertrag, wie im folgenden Beispiel dargestellt, um Dienstvorgängen zusammengesetzte Typen hinzuzufügen.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}*/
[MessageContract]
public class ServiceRequest
{
[MessageHeader]
public String Type { get; set; }
[MessageBodyMember]
public Stream Contents { get; set; }
}
[MessageContract]
public class ServiceResponse
{
[MessageHeader]
public String Type { get; set; }
[MessageBodyMember]
public Stream Contents { get; set; }
}
}
服务:web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Ausführlich,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="Ausführlich,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:logweb_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:logweb_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>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<!--httpRuntime targetFramework="4.5"/>-->
<httpRuntime targetFramework="4.5" maxRequestLength="102400" executionTimeout="7200"/>
</system.web>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logKnownPii="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
<endToEndTracing propagateActivity="true" activityTracing="true"
messageFlowTracing="true" />
</diagnostics>
<bindings>
<basicHttpBinding>
<binding name="basicHttpMtomBinding" closeTimeout="10:01:00"
openTimeout="10:01:00" receiveTimeout="10:10:00" sendTimeout="10:01:00"
transferMode="Streamed" messageEncoding="Mtom">
<readerQuotas maxDepth="1000" maxStringContentLength="1000" maxArrayLength="1000"
maxBytesPerRead="1000" maxNameTableCharCount="1000" />
</binding>
</basicHttpBinding>
<wsHttpBinding>
<binding name="wsHttpMtomBinding" closeTimeout="10:01:00" openTimeout="10:01:00"
receiveTimeout="10:10:00" sendTimeout="10:01:00" maxBufferPoolSize="999999999"
maxReceivedMessageSize="1048576" messageEncoding="Mtom"
useDefaultWebProxy="true">
<readerQuotas maxDepth="100" maxStringContentLength="1000" maxArrayLength="1000"
maxBytesPerRead="100000" maxNameTableCharCount="1000" />
<reliableSession inactivityTimeout="10:10:00" />
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<remove scheme="http" />
<add scheme="http" binding="wsHttpBinding" bindingConfiguration="wsHttpMtomBinding" />
<add scheme="https" binding="basicHttpsBinding" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
Um das Stammverzeichnis der Webanwendung beim Debuggen auszuwählen, legen Sie den Wert unten auf "true" fest.
Legen Sie ihn vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Informationen über den Webanwendungsordner zu vermeiden.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
客户端:app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" messageEncoding="Mtom">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:2364/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1">
<identity>
<userPrincipalName value="AresAdmin" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
客户端:Form1.cs
...
private void button1_Click(object sender, EventArgs e)
{
ServiceReference1.IService1 testService = new ServiceReference1.Service1Client();
ServiceReference1.ServiceRequest testInput = new ServiceReference1.ServiceRequest();
ServiceReference1.ServiceResponse testOutput = new ServiceReference1.ServiceResponse();
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream inoutStream = new MemoryStream();
testInput.Type = "TestType";
String test = "TestContent";
testInput.Contents = new MemoryStream();
formatter.Serialize(testInput.Contents, test);
//testInput.Contents.Position = 0;
testService.TestCase(testInput);
MessageBox.Show("Done!");
}
...
我在web.config(端点等)中看不到任何服务配置数据
<services>
<service behaviorConfiguration="..." name="[Namespace].Service1">
<endpoint address="" binding="basicHttpBinding" bindingNamespace="..." bindingConfiguration="..." contract="[Namespace].IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:5000/Service1"/>
...
您可以在运行时配置端点(基本上是在自托管服务中),但对于简单的场景和IIS基础结构。。。?
参见http://msdn.microsoft.com/en-us/library/ee354381.aspx