2016-03-16 15 views
1

我们一直在使用SS可定制字段(查询字符串中的“字段=”),我认为我们可能会在某处丢失配置。对我们来说,字段名称似乎区分大小写 - 如果它们不匹配DTO,则不会返回。然而,这不是说是一个从自动查询GitHub的页面链接的例子真(更换外壳仍然会导致正确的领域回来):ServiceStack“可定制字段”

github.servicestack.net/repos.json?fields=Name,Homepage,Language,Updated_At

我们有什么缺失?

谢谢!

这里是表现出我们所看到的行为的示例:

APPHOST:

using System.Configuration; 
using ServiceStack; 
using ServiceStack.Data; 
using ServiceStack.OrmLite; 
using ServiceStack.Text; 

namespace TestSS.Service { 
    public class AppHost : AppHostBase { 
     public AppHost() 
      : base("TestSS Service", typeof(AppHost).Assembly) { 
     } 

     public override void Configure(Funq.Container container) { 
      Plugins.Add(new AutoQueryFeature { EnableUntypedQueries = false }); 
      Plugins.Add(new CorsFeature()); 

      PreRequestFilters.Add((httpReq, httpRes) => { 
       if (httpReq.Verb == "OPTIONS") 
        httpRes.EndRequest(); 
      }); 

      container.Register<IDbConnectionFactory>(
       new OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["TestSS"].ConnectionString, SqlServerDialect.Provider)); 

      JsConfig.DateHandler = DateHandler.ISO8601; 
      JsConfig.IncludeNullValues = true; 
      JsConfig.EmitCamelCaseNames = true; 
     } 
    } 
} 

的DTO:

using ServiceStack.DataAnnotations; 

namespace TestSS.DTO { 
    public class Employee { 
     [PrimaryKey] 
     public int Id { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     [References(typeof(Department))] 
     public int DepartmentId { get; set; } 

     [Ignore] 
     public Department Department { get; set; } 
    } 


    public class Department { 
     [PrimaryKey] 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 

} 

服务:

using ServiceStack; 
using TestSS.DTO; 

namespace TestSS.Service.Services { 
    [Route("/employees/{Id}", "GET")] 
    public class SingleEmployeeRequest : QueryBase<Employee> { 
     public string Id { get; set; } 
    } 

    [Route("/employees", "GET")] 
    public class FindEmployeesRequest : QueryBase<Employee>, IJoin<Employee, Department> { 
    } 
} 

请尝试以下路线:

/employees?fields=FirstName,LastName <-- works 

/employees?fields=firstname,LastName <-- Only LastName returned 

/employees?fields=firstname,lastname <-- All properties returned ? 

现在,除去IJoin从FindEmployeesRequest在员工服务并再次尝试的路线。

/employees?fields=FirstName,LastName <-- works 

/employees?fields=firstname,LastName <-- works 

/employees?fields=firstname,lastname <-- works 

UPDATE:

外壳问题是固定4.0.55,但似乎有一个更奇怪的行为与这条路线:

/employees?fields=departmentid 

响应包含两个DepartmentID的AND Id属性和ID值实际上是DepartmentId值。这同样适用于这条航线:

/employees?fields=id,departmentid 

回答

2

支持不区分大小写的自定义字段中添加in this committests for AutoQuery in this commit。此更改可从现在的available on MyGet v4.0.55获得。

您可以现在使用大小写敏感的自定义字段,但如果你选择升级到最新的版本也有一些重大的命名,将在未来的v4.0.56发行说明文件后用自动查询的变化。

由于支持自定义数据源的新的非RDBMS版本的AutoQuery(称为AutoQueryData),我们必须重命名一些现有的AutoQuery属性,以便它们在2个实现之间保持一致的隔离命名法。

命名更改在obsoleted attributes捕捉,基本上它涉及添加Db后缀以任何[Query]属性或QueryBase<T>类,你正在使用,我。E:

[Obsolete("Use [QueryDb]")] 
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 
public class QueryAttribute : AttributeBase { } 

[Obsolete("Use [QueryDbField]")] 
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 
public class QueryFieldAttribute : AttributeBase { } 

[Obsolete("Use QueryDb")] 
public abstract class QueryBase<T> : QueryBase, IQueryDb<T>, IReturn<QueryResponse<T>> { } 

[Obsolete("Use QueryDb")] 
public abstract class QueryBase<From, Into> 
    : QueryBase, IQueryDb<From, Into>, IReturn<QueryResponse<Into>> { } 

[Obsolete("Use IQueryDb<From>")] 
public interface IQuery<From> : IQueryDb { } 
[Obsolete("Use IQueryDb<From,Into>")] 
public interface IQuery<From, Into> : IQueryDb { } 

虽然使用现有的QueryBase类仍然受支持,这是现在已经过时了,你应该在你自己的休闲切换到新的QueryDb基类。

所以不是:

[Route("/movies")] 
public class FindMovies : QueryBase<Movie> 
{ 
    public string[] Ratings { get; set; } 
} 

新的基类来用的是QueryDb,如:

[Route("/movies")] 
public class FindMovies : QueryDb<Movie> 
{ 
    public string[] Ratings { get; set; } 
} 

的发行说明explains the Custom Fields behavior

领域仍需要在Resp上定义onse DTO,因为此功能不会更改Response DTO Schema,只会填充哪些字段。这确实会改变执行的底层RDBMS SELECT,也会从RDBMS和App Server之间的带宽减少中受益。

一个有用的JSON定制,你可以指定自定义字段时补充的是ExcludeDefaultValues,如:

/query?Fields=Id,Name,Description,JoinTableId&jsconfig=ExcludeDefaultValues 

这将删除所有值类型字段从JSON响应的默认值,如:

本质上只有你选择的查询和填充的响应DTO的领域,其他所有领域都有各自的默认值,其引用类型是null但是对于值类型,为int为0的日期时间是DateTime.MinValue等。

?jsconfig=ExcludeDefaultValues修改指示ServiceStack的JSON序列从被序列省略使用默认值的属性,所以上面的链接,而不是将返回:

{ 
    Total: 30, 
    Results: [ 
    { 
     Name: "ServiceStack", 
     Homepage: "https://servicestack.net", 
     Language: "C#", 
     Updated_At: "/Date(1443370980000+0000)/" 
    }, 
    { 
     Name: "ServiceStack.Examples", 
     Homepage: "https://servicestack.net", 
     Language: "C#", 
     Updated_At: "/Date(1443326228000+0000)/" 
    }, 
    ... 
} 
+0

完整阅读发行说明,并爱“jsconfig = ExcludeDefaultValues”,但我的问题是字段名称的大小写。在上面的服务中,我可以将“fields = Name ...”更改为“fields = name ...”或“fields = NAME ...”,并且Name属性总是在响应中返回。但对于我的服务,这不起作用 - 如果外壳不匹配,则该属性不会在响应中返回。 – jaybird

+0

@ user3146832您尚未提供任何有关您服务的信息。即您使用的是什么RDBMS?你看到这个是什么POCO课程?你的AutoQuery Request DTO是什么样的?您是否使用自定义请求自动查询服务?您是否使用任何自定义JsConfig配置?等等,不可能在没有任何事情的情况下复制或识别您的问题。 – mythz

+1

我会做更多的研究。我在家里有一种服务,它的行为应该像它应该的那样 - 这种情况**不敏感**。我不确定在工作中发生了什么。谢谢,你让我看看地方。 – jaybird