我使用wcf rest starter kit preview 2创建了一个WCF Rest API服务,它根据请求的内容类型自动返回JSON或XML数据。一切正常,但是当我的服务方法返回多个数据类型时,某些方法返回类的对象或类,bool,int或集合类型的集合。所以我计划在所有方法中返回相同的响应。我创建一个新类如下:
[DataContract(Namespace = "")]
public class ServiceResponse
{
[DataMember]
public bool IsError
{ get; set; }
[DataMember]
public string ResponseMessage
{ get; set; }
[DataMember]
public Object ResponseData
{ get; set; }
}
和User类如下:
[DataContract(Namespace = "")]
public class User
{
[DataMember]
public string UserName
{ get; set; }
[DataMember]
public int UserID
{ get; set; }
}
在ServiceResponse类中,我声明了一个Object Type属性ResponseData,而我的all方法的返回类型为ServiceResponse。我的问题是,当我设置任何字符串,bool,int类型作为ResponseData时,它被序列化但是当我设置集合类型或另一个类的对象也具有DataContarct属性时,此类未被序列化,请参阅下面的代码:
public ServiceResponse GetUser(int userID)
{
User user = getUser(userID); get user data from database
ServiceResponse response=new ServiceResponse();
var response = new ServiceResponse
{
IsError = false,
ResponseMessage = string.Empty,
ResponseData = user; // Setting Result Data here
};
return response;
}
当我调用上面的方法(GetUser)时,由于序列化问题,我得到了Null响应,但是下面的代码工作正常
public ServiceResponse TestMethod(string testMessage)
{
ServiceResponse response=new ServiceResponse();
var response = new ServiceResponse
{
IsError = false,
ResponseMessage = string.Empty,
ResponseData = testMessage; // Setting Result Data here
};
return response;
}
任何人都可以帮助我吗?
答案 0 :(得分:2)
您遇到的问题是由于您在DataContract
中将ResponseData
声明为Object
,但没有告诉WCF哪些类型有效已知类型。您需要明确告诉WCF哪些已知类型对您的服务有效,并且您可以使用ServiceKnownType
属性来执行此操作。我已经采用了你的代码并做了一些修改来证明这一点:
[DataContract(Name="ServiceResponse")]
public class ServiceResponse
{
[DataMember(Name="IsError", Order=1)]
public bool IsError
{ get; set; }
[DataMember(Name="ResponseMessage", Order=2)]
public string ResponseMessage
{ get; set; }
[DataMember(Name="ResponseData", Order=3)]
public Object ResponseData
{ get; set; }
}
[DataContract(Name="User")]
public class User
{
[DataMember(Name="UserName", Order=1, IsRequired=true)]
public string UserName
{ get; set; }
[DataMember(Name="UserID", Order=2, IsRequired=true)]
public int UserID
{ get; set; }
}
[DataContract(Name = "User2")]
public class User2
{
[DataMember(Name = "UserName", Order = 1, IsRequired = true)]
public string UserName
{ get; set; }
[DataMember(Name = "UserID", Order = 2, IsRequired = true)]
public int UserID
{ get; set; }
}
[ServiceContract(Namespace = "WebApplication1")]
[ServiceKnownType(typeof(User))]
[ServiceKnownType(typeof(User2))]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1
{
[OperationContract(Name="GetUser")]
[WebGet(UriTemplate = "GetUser/{userID}", ResponseFormat = WebMessageFormat.Json)]
public ServiceResponse GetUser(String userID)
{
User theUser = new User()
{
UserID=Convert.ToInt32(userID),
UserName="bob"
};
ServiceResponse sr = new ServiceResponse()
{
IsError = false,
ResponseMessage = "",
ResponseData = theUser
};
return sr;
}
[OperationContract(Name = "GetUser2")]
[WebGet(UriTemplate = "GetUser2/{userID}", ResponseFormat = WebMessageFormat.Json)]
public ServiceResponse GetUser2(String userID)
{
User2 theUser = new User2()
{
UserID = Convert.ToInt32(userID),
UserName = "bob"
};
ServiceResponse sr = new ServiceResponse()
{
IsError = false,
ResponseMessage = "",
ResponseData = theUser
};
return sr;
}
}
我做了什么:
这就是它。使用ServiceKnownType属性有点难看 - 有一些解决方案可以绕过它(here)。
如果您还有其他问题,请与我们联系。希望这有帮助!