首页 文章

EF 6的WCF序列化错误

提问于
浏览
0

我正在构建一个使用EF 6访问POCO的RESTful WCF服务 . 我还使用Ninject和存储库模式来访问数据库 . 这是我的服务设置:

Configuration

<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>

Contract

[ServiceContract]
public interface ILoginService
{
    [OperationContract]
    [WebInvoke(UriTemplate = "")]
    ErrorCollectionDTO Login(LoginRequestDTO loginRequest);
}

Implementation

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());
    }

我将DTO用于所有使用[DataContract] / [DataMember]属性的请求和响应 . 该服务正确接受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尝试序列化方法调用的db条目 . 我认为这应该不是问题,因为我正在使用DTO进行响应,而且它远不及响应构造 . 我google了一下,我尝试了一些解决方案,如

Configuration.ProxyCreationEnabled = false;

Configuration.LazyLoadingEnabled = false;

但他们没有工作 . 当然,我还将DataContract和DataMember属性添加到我的所有POCO中,因为错误消息指示但无济于事 .

Update: 这是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; }
}

2 回答

  • 0

    尝试使用数据协定和具有数据成员属性的属性来装饰类 .

  • 0

    看来WCF无法序列化我在通用存储库类方法中使用的IQueryable类型来返回数据库结果的集合 . 它通过使用List来工作,如果你问我,这是非常icky . 如果有人比使用List更好的建议,请提及它 .

相关问题