2014-06-15 54 views
1

好日子之间的对象序列化,ServiceStack问题测试方法和服务

我们的产品与序列化的问题,即用一个值设置一个属性请求对象最终通过与分配给值服务接收一个不同的属性。请参阅下面的更多信息。

我们使用3.9.71版本的ServiceStack NuGet包。该解决方案由以下项目组成:

  • Project.Host:用于自托管ServiceStack并包含Service类。
  • Project.DTO:所有服务DTO和周围的类。
  • Project.Tests:包含单元测试。

的问题已被确认只有一个类/服务,即MinimalUser和MinimalUserService,你可以看到代码如下两种:

MinimalUser.cs

namespace Project.DTO 
{ 
    [Route("/User/{Identity}", "GET")] 
    [Route("/User/{Username}", "GET")] 
    [Route("/User/{DisplayName}", "GET")]  
    public class MinimalUser : IReturn<MinimalUser> 
    { 
     #region Properties 

     public int? Identity { get; set; } 
     public string Username { get; set; } 
     public string Password { get; set; } 
     public string DisplayName { get; set; } 
     public string Email { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string Language { get; set; } 
     public string TimeZone { get; set; } 
     public string Culture { get; set; } 
     public List<string> Roles { get; set; } 
     public List<string> Permissions { get; set; } 
     public DiscUserDetails DiscUserDetails { get; set; } 

     #endregion 

     #region Constructors 
     public MinimalUser() { } 

     public MinimalUser(UserAuth auth) 
     { 
      if (auth != null) 
      { 
       this.Identity = auth.Id; 
       this.Username = auth.UserName; 
       this.DisplayName = auth.DisplayName; 
       this.Email = auth.Email; 
       this.FirstName = auth.FirstName; 
       this.LastName = auth.LastName; 
       this.Language = auth.Language; 
       this.TimeZone = auth.TimeZone; 
       this.Culture = auth.Culture; 
       this.Roles = auth.Roles; 
       this.Permissions = auth.Permissions; 
       this.DiscUserDetails = auth.Get<DiscUserDetails>(); 
      } 
     } 

     #endregion 

     #region Methods 

     public static MinimalUser FromUserAuth(UserAuth auth) 
     { 
      return auth == null ? new MinimalUser() : new MinimalUser 
      { 
       Identity = auth.Id, 
       Username = auth.UserName, 
       DisplayName = auth.DisplayName, 
       Email = auth.Email, 
       FirstName = auth.FirstName, 
       LastName = auth.LastName, 
       Language = auth.Language, 
       TimeZone = auth.TimeZone, 
       Culture = auth.Culture, 
       Roles = auth.Roles, 
       Permissions = auth.Permissions, 
       DiscUserDetails = auth.Get<DiscUserDetails>() 
      }; 
     } 

     #endregion 
    } 
} 

DiscUserDetails.cs

namespace Project.DTO 
{ 
    public class DiscUserDetails 
    { 
     public int? LocationId { get; set; } 
     public bool IsActive { get; set; } 
     public byte NumberOfFailedLoginAttempts { get; set; } 
     public bool MustChangePasswordAtNextLogon { get; set; } 
     public int? LastAcceptedPolicyId { get; set; } 
    } 
} 

MinimalUserService.cs

namespace Project.Services 
{ 
    [Authenticate] 
    [RequiredRole(new string[] { RoleNames.Admin })] 
    public class MinimalUserService : Service 
    { 
     IUserAuthRepository authRepo = AppHost.Resolve<IUserAuthRepository>() as OrmLiteAuthRepository; 

     /// <summary> 
     /// Return a minimalist structure of user insensitive information. 
     /// </summary> 
     /// <param name="request">The request containing the ID of the user.</param> 
     /// <returns>A minimalist structure of user insensitive information.</returns> 
     public object Get(MinimalUser request) 
     { 
      if (request.Identity != null)    
       return new MinimalUser(authRepo.GetUserAuth(request.Identity.ToString())); 
      else if (request.Username != null) 
       return new MinimalUser(authRepo.GetUserAuthByUserName(request.Username)); 
      else 
       return null; 
     }    
    } 
} 

从我的测试项目,我运行下面的测试:

[TestMethod] 
public void GetMinimalUserByUsername() 
{ 
    AuthResponse authResponse = client.Post<AuthResponse>("/auth", new Auth 
    { 
     UserName = "accountwithadminrole", 
     Password = "blablabla", 
     RememberMe = true, 
     provider = CredentialsAuthProvider.Name 
    }); 

    MinimalUser request = new MinimalUser 
    { 
     DisplayName = BaseAccounts.System, 
    }; 

    MinimalUser user = client.Get<MinimalUser>(request); 

    Assert.IsNotNull(user); 
} 

我清楚地看到,发出client.Get方法之前,该请求对象有其所有属性设置为null,除了显示名称它具有“系统”的价值。当MinimalUserService Get方法接收到此请求时,现在将值“系统”分配给属性UserName,并且DisplayName为空。

此外,我试图在MinimalUser类中逐个注释属性,怀疑它的某个字段可能会导致序列化问题,并且当注释一定数量的属性时,最终会出现随机“错误请求”。虽然,我可以随机评论一个属性,并且之前导致“错误请求”的一个属性不会根据其他属性注释掉。

我真的很困惑这可能发生。我觉得这个服务和DTO比起同样的项目中的其他人来说简单,但我确信我在这里做了一些非常愚蠢的事情。

不要犹豫,要了解更多的细节,我很高兴能够提供您需要的所有信息。

谢谢。

回答

1

填充用户名而不是DisplayName的原因是由于您为MinimalUser定义的路由。在MinimalUser.cs中,您定义了2条相同的路由:

[Route("/User/{Identity}", "GET")] 
[Route("/User/{Username}", "GET")] 
[Route("/User/{DisplayName}", "GET")] 

用户名和显示名都是字符串。这使得ServiceStack无法确定指定请求的适当路由,因为它无法区分路由。您可以通过删除路线或向其中一条路线添加其他文字来解决此问题;例如/User/ByDisplayName/{Username}

+0

谢谢朋友,现在都在工作! – d1ssonance

相关问题