json 如何修复OData查询返回错误的结果,虽然底层数据是正确的?

bvjveswy  于 2022-12-15  发布在  其他
关注(0)|答案(1)|浏览(138)

平台:

Blazor,EF酷睿6
当向我的服务器发送OData过滤器查询时,它对某些属性有效,对其他属性失败,尽管它们具有相同的类型。

public partial class DocumentRequestDTO
    {
        public DocumentRequestDTO()
        { }

        [Key]
        public Guid ID { get; set; }
        public string AuthorID { get; set; } = string.Empty;
        public string Authorname { get; set; } = string.Empty;
        public Guid DocumentID { get; set; } = Guid.Empty;
        public string OwnerID { get; set; } = string.Empty;
        public string Ownername { get; set; } = string.Empty;
        public string Filename { get; set; } = string.Empty;
        public string Description { get; set; } = string.Empty;
        public string ReasonForRequest { get; set; } = string.Empty;
        public string WatermarkText { get; set; } = string.Empty;
        public bool IsForInternalUse { get; set; } = false;
        public DateTime TimeStamp { get; set; } = DateTime.Now;
        public string ReasonForDecision { get; set; } = string.Empty;
        public string Statusname { get; set; } = string.Empty;
        public List<ProxyTooltipData>? Proxies { get; set; } = null;
        }
    }

控制器代码:

[EnableQuery]
    public IQueryable<DocumentRequestDTO> GetForSelect(string userID, bool showByAuthor)
    {
        IQueryable<DocumentRequest> qBase = null!;
        try
        { 
            qBase = 
                _context.Requests
                    .Include(r => r.Document)
                        .ThenInclude(d => d.Owner)
                    .Include(r => r.Author)
                    .Where(r => r.TimeStamp.Date >= DateTime.Today.AddDays(-ServerGlobals.RequestLifespan))
                    ;
        }
        catch (Exception e)
        {
            Console.WriteLine($"Error '{e.Message}' occurred while quyering requests.");
        }

        UserInfo user = _context.UserInfo.FirstOrDefault(e => e.AccountID == userID);

        if ((user != null) && (user.AccessLevel < AccessLevels.Admin))
        {
            try
            {
                if ((user.AccessLevel == AccessLevels.Requester) || showByAuthor)
                {
                    qBase = qBase.Where(x => x.AuthorID == user.AccountID);
                }
                else
                {
                    List<string> proxiedOwners = new();
                    foreach (var p in _context.ProxyInfo.Where(p => p.ProxyID == user.AccountID).ToList())
                        proxiedOwners.Add(p.AccountID);
                    qBase = qBase.Where(x => proxiedOwners.Contains(user.AccountID));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error '{e.Message}' occurred while determining proxied owners.");
            }
        }

        IQueryable<DocumentRequestDTO> qFinal = null!;
        try
        {
            qFinal = qBase
                .Select(
                    x => new DocumentRequestDTO()
                    {
                        ID = x.ID,
                        AuthorID = x.AuthorID,
                        TimeStamp = x.TimeStamp,
                        DocumentID = x.Document.ID,
                        Filename = (x.Document == null) ? "unknown" : x.Document.Filename,
                        OwnerID = x.Document.OwnerID,
                        Ownername = x.Document.Owner.Name,
                        Authorname = x.Author.Name,
                        Description = x.Document.Description,
                        WatermarkText = x.WatermarkText,
                        ReasonForRequest = x.ReasonForRequest,
                        ReasonForDecision = x.ReasonForDecision,
                        IsForInternalUse = x.IsForInternalUse,
                        ReviewStatus = x.ReviewStatus,
                        Statusname = DocumentRequest.StatusName(x.ReviewStatus),
                        Proxies = new()
                    });
        }
        catch (Exception e)
        {
            Console.WriteLine($"Error '{e.Message}' occurred while building request result.");
        }

        List<DocumentRequestDTO> l = null!;
        try
        {
            l = qFinal.ToList();
        }
        catch (Exception e)
        {
            Console.WriteLine($"Error '{e.Message}' occurred while verifying request result.");
        }

        return qFinal;
    }

状态名称代码:

public enum RequestStatus
{
    Pending,
    Approved,
    Declined,
    NoDecisionNeeded
}

public class DocumentRequest : PropertyIndexer
{
    public static string StatusName(RequestStatus status)
    {
        switch (status)
        {
            case RequestStatus.Pending:
                return "Pending";

            case RequestStatus.Approved:
                return "Approved";

            case RequestStatus.Declined:
                return "Declined";

            case RequestStatus.NoDecisionNeeded:
                return "No decision needed";

            default:
                return "unknown";
        }
    }
}

工作请求:

https://localhost:12345/TestServer/RequestDto
    ?$count=true&$orderby=Ownername&$select=Ownername&userID=0388&showByAuthor=False

结果:

{@odata.context: "https://localhost:44393/DocServer2/$metadata#RequestDto(Ownername)", @odata.count: 4,…}
@odata.context: "https://localhost:44393/DocServer2/$metadata#RequestDto(Ownername)"
@odata.count: 4
    value: [{Ownername: "Baggins, Frodo"}, 
            {Ownername: "Baggins, Frodo"}, 
            {Ownername: "Wonka, Willy"},…]
        0: {Ownername: "Baggins, Frodo"}
        1: {Ownername: "Baggins, Frodo"}
        2: {Ownername: "Wonka, Willy"}
        3: {Ownername: "Wonka, Willy"}

请求失败:

https://localhost:12345/TestServer/RequestDto
    ?$count=true&$orderby=Filename&$select=Filename&userID=0388&showByAuthor=False

结果:

{"@odata.context":"https://localhost:44393/DocServer2/$metadata
 #RequestDto(Filename)",
 "@odata.count":4,"value":[

来自控制器的基础数据:(来自列表l)

选择文件名或状态名时出错。我发现当给这些属性(“Testfile.pdf”和“Test Status”)分配常量值时,错误不会出现。但是,从我的控制器返回的数据是完整的,包含所有返回记录的有效文件名,并且在执行我的控制器代码时没有抛出异常;即使是从查询结果中获取数据列表时也是如此。
关于状态名称:如果你检查我下面的相关代码,你会注意到总是会有有效的字符串数据分配给它。

6uxekuva

6uxekuva1#

我自己发现了问题:这是

Statusname = DocumentRequest.StatusName(x.ReviewStatus)

在控制器中。
当OData尝试使用我的控制器返回的IQueryable检索数据时,它无法调用那个静态类成员,因为它需要来自这里的数据库表的属性。
现在的问题是,是否有一个不需要添加数据库表属性的解决方案,因为我希望显示数据的ReviewStatus属性的用户可读版本。

相关问题