WCF服务无法识别我自己的数据类型
问题描述:
我正在尝试创建概念验证上传WCF服务。我发现周围净博客文章以下部分:WCF服务无法识别我自己的数据类型
namespace GreenWebMediaService
{
[ServiceContract]
public interface IMediaServer
{
[OperationContract]
void UploadData(UploadFile data);
}
// Use a data contract as illustrated in the sample below
// to add composite types to service operations.
[DataContract]
public class UploadFile
{
public UploadFile() { }
[MessageHeader]
public string MetaData { get; set; }
[MessageBodyMember]
public Stream data { get; set; }
}
}
我启动它(在Visual Studio托管),并从一个新创建的Windows参考窗体应用程序,这是我的参考,从app.config中:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMediaServer" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192"
maxArrayLength="16384" maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:49689/MediaServer.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IMediaServer"
contract="mediaServer.IMediaServer"
name="BasicHttpBinding_IMediaServer" />
</client>
</system.serviceModel>
</configuration>
当我做它的一个实例,是指它是这样的:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
IMediaServer mediaServer = new mediaServer.MediaServerClient();
UploadFile file = new UploadFile();
mediaServer.UploadData(null);
}
}
当我访问“文件”变量,它只有一个“file.ExtensionData”属性w ^在这里,我预计会有权访问我在“UploadFile”类中创建的属性。我错过了什么?我试图在Visual Studio的配置对话框中打勾,因为我在其他线程中发现了此信息,仍然没有运气:请参阅我的对话框:http://screencast.com/t/NzhhNzM3Y2Q(对不起,我不知道screencast.com会保留此图像多长时间)
答
您正在合并DataContract
与MessageHeader
和MessageBodyMember
属性。您应该使用
-
DataContract
,DataMember
或 -
MessageContract
,MessageHeader
,MessageBodyMember
,
不是它们的组合。所以,你的UploadFile
声明应该是这样的:
[DataContract]
public class UploadFile
{
[DataMember] public string MetaData { get; set; }
[DataMember] public Stream data { get; set; }
}
或像这样:
[MessageContract]
public class UploadFile
{
[MessageHeader] public string MetaData { get; set; }
[MessageBodyMember] public Stream data { get; set; }
}
答
我看到你的代码的两个问题。第一个问题是DataContract的定义。这是完全错误的。正如罗纳德已经指出你正在将DataContract和MessageContract结合起来。你必须使用第二个罗纳德的建议(首先不会工作):
[MessageContract]
public class UploadFileRequest // Good naming convention for message contracts
{
// Streaming over HTTP demands only single body member of type Stream
// any other data have to be passed as custom headers - that is the reason
// why mentioned data contract doesn't work.
[MessageHeader] public string MetaData { get; set; }
[MessageBodyMember] public Stream Data { get; set; }
}
第二个问题是流作为您的请求的正文成员。只有在BasicHttpBinding上使用Streamed或StreamedRequest传输模式时才有可能。必须手动在客户端绑定定义上设置此信息 - 它不会在WSDL /元数据中传输,并且它不是可互操作的功能。