【发布时间】:2014-10-23 00:07:19
【问题描述】:
我正在构建一个使用 EF 6 访问 POCO 的 RESTful WCF 服务。我还使用 Ninject 和存储库模式来访问数据库。这是我的服务设置:
配置
<serviceBehaviors>
<behavior name="commonServicebehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="sbLoginSAS">
<transportClientEndpointBehavior>
<tokenProvider>
<sharedAccessSignature keyName="RootManageSharedAccessKey" key="oJh2klf242iwISUDcsTQHeR/3W3FlQTQte/M=" />
</tokenProvider>
</transportClientEndpointBehavior>
<webHttp defaultOutgoingResponseFormat="Json" />
<serviceRegistrySettings discoveryMode="Public" />
</behavior>
合同
[ServiceContract]
public interface ILoginService
{
[OperationContract]
[WebInvoke(UriTemplate = "")]
ErrorCollectionDTO Login(LoginRequestDTO loginRequest);
}
实施
class LoginService : ILoginService
{
private readonly ILoginValidator _loginValidator;
private readonly IErrorMapper _errorMapper;
private readonly IEncryptor _encryptor;
private readonly IUserManager _userManager;
public LoginService(ILoginValidator loginValidator, IErrorMapper errorMapper, IEncryptor encryptor, IUserManager userManager)
{
_loginValidator = loginValidator;
_errorMapper = errorMapper;
_encryptor = encryptor;
_userManager = userManager;
}
public ErrorCollectionDTO Login(LoginRequestDTO loginRequest)
{
//Validate the request
var completeSummary = _loginValidator.Validate(loginRequest);
//Maps validation errors to a response DTO
var errorCollectionDTO = _errorMapper.Transform(completeSummary);
//If request not valid, return errors
if (!errorCollectionDTO.IsValid) return errorCollectionDTO;
//At this point, user is correctly authenticated
//so we prepare and send him an authorization token
var user = _userManager.GetUser(loginRequest.CPR);
var token = _encryptor.Encrypt(loginRequest.CPR);
user.SecurityToken = new SecurityToken
{
Token = token,
ValidUntil = DateTime.Now.AddMinutes(5)
};
_userManager.UpdateUser(user);
return new LoginResponseDTO(errorCollectionDTO, token.ToString());
}
我对所有使用 [DataContract] / [DataMember] 属性的所有请求和响应都使用 DTO。该服务正确接受 JSON 请求。但是我在该行中遇到错误:
var completeSummary = _loginValidator.Validate(loginRequest);
当调用方法尝试使用 _userManager.GetUser(entity.CPR) 通过其存储库检索实体的条目时:
private IEnumerable<IError> ValidateEntity(LoginRequestDTO entity)
{
if (entity == null)
yield return new Error("Login request was null or invalid");
else
{
var user = _userManager.GetUser(entity.CPR);
if (user == null)
yield return new Error("User doesn't exist or password is wrong");
}
}
Type 'System.Data.Entity.DbSet`1[ITU.MAP.Domain.Model.User]' cannot be serialized.
Consider marking it with the DataContractAttribute attribute, and marking all of its
members you want serialized with the DataMemberAttribute attribute. If the type is
a collection, consider marking it with the CollectionDataContractAttribute.
据我了解,WCF 尝试序列化方法调用的数据库条目。我认为这应该不是问题,因为我使用 DTO 进行响应,而这与响应构造相去甚远。我用谷歌搜索并尝试了一些解决方案,例如
Configuration.ProxyCreationEnabled = false;
和
Configuration.LazyLoadingEnabled = false;
但他们没有工作。当然,我还向我的所有 POCO 添加了 DataContract 和 DataMember 属性,如错误消息所示,但无济于事。
更新:这是 WCF 尝试序列化的 POCO。我还尝试使用仅用 [DataContract] 和 [DataMember] 装饰的其他非抽象类,但会发生相同的错误。 KnownType 中的子类型也使用上述属性正确修饰。
[DataContract(IsReference = true)]
[KnownType(typeof(Paramedic))]
[KnownType(typeof(Resident))]
[Table("Users")]
public abstract class User : IIdentifiable
{
[Key]
[DataMember]
[DisplayName("Id")]
public int Id { get; set; }
[DataMember]
[DisplayName("CPR")]
public string CPR { get; set; }
[DataMember]
[DisplayName("Password hash")]
public byte[] Password { get; set; }
[DataMember]
[DisplayName("Name")]
public string Name { get; set; }
[DataMember]
[DisplayName("Surname")]
public string Surname { get; set; }
[DataMember]
[DisplayName("Region")]
public int RegionId { get; set; }
[DataMember]
[DisplayName("Region")]
[ForeignKey("RegionId")]
public virtual Region Region { get; set; }
[DataMember]
[DisplayName("Age")]
public int Age { get; set; }
[DataMember]
[DisplayName("Blood type")]
public BloodType BloodType { get; set; }
[DataMember]
[DisplayName("Rhesus")]
public Rhesus Rhesus { get; set; }
[DataMember]
public int? SecurityTokenId { get; set; }
[DataMember]
[DisplayName("Security token")]
[ForeignKey("SecurityTokenId")]
public virtual SecurityToken SecurityToken { get; set; }
[DataMember]
public virtual ICollection<Allergy> Allergies { get; set; }
[DataMember]
public virtual ICollection<Condition> Conditions { get; set; }
[DataMember]
public virtual ICollection<Prescription> Prescriptions { get; set; }
}
【问题讨论】:
标签: c# .net entity-framework wcf