如何使用ServiceStack获取嵌套元素?

时间:2019-02-25 20:58:15

标签: nested deserialization servicestack ormlite-servicestack servicestack-autoquery

尽管我可以使用下面的代码访问SchemaVersion,但是我无法访问FormatDocID嵌套元素。

有什么想法如何使用ServiceStack和AutoQueryFeature(或类似功能)轻松获取FormatDocID?

我在这里只放了相关的代码部分

public override void Configure(Container container)
{
    JsConfig.DateHandler = DateHandler.ISO8601;
    SetupValidators(container);
    SetupIOC(container);
    SetupPlugins(container, log);
    ContentTypes.Register("application/xml"
    , CLXmlSerializer.Serialize, ServiceStack.Text.XmlSerializer.DeserializeFromStream);
    SetupMetaDataRedirectionPath();
    SetupGlobalResponseFilters();
}

设置插件

private void SetupPlugins(Container container)
{
    Plugins.Add(new ValidationFeature());
    Plugins.Add(new SwaggerFeature());
    Plugins.Add(new AutoQueryFeature
    {
        MaxLimit = 1000,
        EnableUntypedQueries = false,
        IncludeTotal = true
    });

    Plugins.Add(new AutoQueryDataFeature {MaxLimit = 100}
        .AddDataSource(ctx => ctx.MemorySource(new List<WordDocument>
        {
            new WordDocument()
            {
                SchemaVersion = "",
                Format = new Word.DocumentFormat()
                {
                    FormatDocID = 254
                }
            }
        }))
        );

    typeof(RequestLogs).AddAttributes(new RestrictAttribute {VisibilityTo = RequestAttributes.None});
    typeof(AssignRoles).AddAttributes(new RestrictAttribute {VisibilityTo = RequestAttributes.None});
    typeof(UnAssignRoles).AddAttributes(new RestrictAttribute {VisibilityTo = RequestAttributes.None});
    typeof(Authenticate).AddAttributes(new RestrictAttribute {VisibilityTo = RequestAttributes.None});
}

可序列化的类

public abstract class Document
    {
        public DocumentFormat Format;

        public class DocumentFormat
        {
            [XmlAttribute] public int Version;

            public int FormatDocID;
            public string DocShortName;
        }
    }


public class WordDocument : Document
{
    [XmlAttribute] public string SchemaVersion { get; set; } = "1.0";
}

预先感谢您的回答。

1 个答案:

答案 0 :(得分:1)

不清楚您要达到什么目的或原因,AutoQuery创建自动可查询API,其中Response是按指定的Response Content Type序列化的API Response。

如果您想在返回类型化响应DTO之前对其进行拦截,则可以创建一个Custom AutoQuery Implementation并以这种方式自省响应,例如:

public class MyQueryServices : Service
{
    public IAutoQueryData AutoQuery { get; set; }

    //Override with custom implementation
    public object Any(MyQuery query)
    {
        var q = AutoQuery.CreateQuery(query, base.Request);
        var response = AutoQuery.Execute(query, q);
        return response;
    }
}

但是您使用的AutoQuery Memory Data Source可以提供您自己的Typed POCO 集合作为数据源,因此您在创建数据时已经可以访问它们,但是源POCO应该是具有公共属性 flat 类型(与具有公共字段和嵌套类型的类相反)-无法查询嵌套的对象图值。

这是不使用嵌套类或公共字段的POCO的示例:

public abstract class Document
{
    public int Version { get; set; }
    public int FormatDocID { get; set; }
    public string DocShortName { get; set; }
}

因此,如果要使用自动查询的解决方案是将数据源更改为使用具有公共属性的Flat POCO,否则您需要自己创建服务的实现。