1. WCF只能传输序列化的类型,WCF 能自动序列化.net内置的之类型,但是如果需要传输自定义的类型,必须把自定义的类型标注DataContract
DataContract标注这个类作为数据契约,DataMember属性指明那些字段公布为原数据,是否必需,顺序是多少。
2. 上面的定义,使得Student可以用在服务契约里,下面的Name可以让客户端的名称和服务端不同。
3. 下面是我们生成的代理类,可以看到客户端的名字,而且由于Student的Address未声明DataMember,所以客户端是不可见的

Code
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1433
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace JackWangServiceClient.CalcService {
using System.Runtime.Serialization;
using System;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="Student", Namespace="http://schemas.datacontract.org/2004/07/JackWangWCFService")]
[System.SerializableAttribute()]
public partial class Student : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
[System.NonSerializedAttribute()]
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
private string FirstNameField;
private string LastNameField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private int AgeField;
[global::System.ComponentModel.BrowsableAttribute(false)]
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
public string FirstName {
get {
return this.FirstNameField;
}
set {
if ((object.ReferenceEquals(this.FirstNameField, value) != true)) {
this.FirstNameField = value;
this.RaisePropertyChanged("FirstName");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
public string LastName {
get {
return this.LastNameField;
}
set {
if ((object.ReferenceEquals(this.LastNameField, value) != true)) {
this.LastNameField = value;
this.RaisePropertyChanged("LastName");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute(Order=2)]
public int Age {
get {
return this.AgeField;
}
set {
if ((this.AgeField.Equals(value) != true)) {
this.AgeField = value;
this.RaisePropertyChanged("Age");
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="CalcService.CalcService")]
public interface CalcService {
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/CalcService/AddInt", ReplyAction="http://tempuri.org/CalcService/AddIntResponse")]
long AddInt(int firstInt, int SecondInt);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/CalcService/addAgeOfStudent", ReplyAction="http://tempuri.org/CalcService/addAgeOfStudentResponse")]
JackWangServiceClient.CalcService.Student addAgeOfStudent(JackWangServiceClient.CalcService.Student student);
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface CalcServiceChannel : JackWangServiceClient.CalcService.CalcService, System.ServiceModel.IClientChannel {
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class CalcServiceClient : System.ServiceModel.ClientBase<JackWangServiceClient.CalcService.CalcService>, JackWangServiceClient.CalcService.CalcService {
public CalcServiceClient() {
}
public CalcServiceClient(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public CalcServiceClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public CalcServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public CalcServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
public long AddInt(int firstInt, int SecondInt) {
return base.Channel.AddInt(firstInt, SecondInt);
}
public JackWangServiceClient.CalcService.Student addAgeOfStudent(JackWangServiceClient.CalcService.Student student) {
return base.Channel.addAgeOfStudent(student);
}
}
}
4. 客户端调用示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using JackWangServiceClient.CalcService;
namespace JackWangServiceClient
{
class Program
{
static void Main(string[] args)
{
CalcServiceClient proxy = new CalcServiceClient();
long result = proxy.AddInt(50, 60);
Student myStudent = new Student();
myStudent.FirstName = "Jack";
myStudent.LastName = "Wang";
myStudent.Age = 18;
Student resultStudent = proxy.addAgeOfStudent(myStudent);
Console.Out.WriteLine("result from server is:" + result);
Console.Out.WriteLine(resultStudent.FirstName + "," + resultStudent.LastName + "," + resultStudent.Age);
Console.ReadLine();
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)