4

我正在使用带有 Web API 的微风。我对如何“过滤列”或如何不将整个表公开给我的 Web API 没有很好的掌握。我使用实体框架作为我的来源,John Papa 在这里解决了我的两个问题:http: //www.johnpapa.net/spajs04/#comment-113761 并被 Ward Bell 确认是一个很好的解决方案。有人可以告诉我如何使用实体框架来创建可在我的 webapi 中查询并且可以与微风一起使用的部分或投影吗?

这是我在 webapi 中的当前功能

[HttpGet]
public IQueryable<Contact> GetContacts()
{
    return _contextProvider.Context.Contact;
}

这是我目前的课程:

public class Contact
{
    [Key]
    public Guid ID { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string NickName { get; set; }
    public string JobTitle { get; set; }
    public DateTime BirthDate { get; set; }
    public bool Gender { get; set; }
    public string SSN { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateUpdated { get; set; }

    public virtual ICollection<Address> Address { get; set; }
}

我想要一个可查询的 webapi 函数,它是我当前的类,没有SSN 字段。一个“数据库优先”实体且不涉及更改我的数据库或添加“视图”的解决方案会很棒。

4

5 回答 5

6

当您尝试减少有效负载时,客户端投影很好。当您必须确保某些数据(例如,SSN)对客户端真正安全地隐藏时,您需要一些服务器端的东西。

@james 建议 - 使用[NonSerialized](或JSON.NET[JsonIgnore]属性) - 当 SSN永远不应该发送给客户端时,这是一种简单而有效的方法。

如果在授权情况下 SSN 应该在客户上可见(例如,查看她自己的 SSN 的用户或有权查看 SSN 的 HR 人员),这太不灵活了。JSON.NET IContractResolver为您提供了极大的灵活性,可以根据授权规则动态决定哪些属性可以跨越服务边界。

有些人可能会认为用序列化程序解决这个问题太过分了。他们可能会对您展示的服务器端投影感到满意,@chris_dotnet。顺便说一句,从投影返回一个仍然有意义,IQueryable以便客户端可以通过过滤查询减少网络负载。

其他人会更喜欢定义一个 DTO ( ContactDTO) 并通过网络对其进行序列化。

[HttpGet]
    公共 IQueryable GetContacts()
    {
      返回 _contextProvider.Context.Contacts
        .选择(p =>
            新联系人Dto
            {
                名字 = p.名字,
                ID = p.ID,
                姓氏 = p.姓氏
            });
    }

IQueryable比投影版本更健壮,因为过滤可以在数据层而不是服务器层上进行。

在客户端,您可以为ContactDto类型定义元数据,也可以使用 aJsonResultsAdapterContactDto数据映射到ContactBreeze 实体中。

使用JsonResultsAdapter前提是您实际上希望Contact类型(在服务器上的业务模型中形成的类型)在客户端上是已知的。

Contact您可能不希望从您的服务中公开服务器端形状。许多人对此感到非常强烈。如果您是这些人中的一员,最好定义一个“DTO 模型”来表示您希望在客户端上看到的实体。这意味着学习为您的 DTO 模型创建元数据并在服务器上编写映射逻辑以在 DTO 和您的业务模型之间移动。

您可以看到所有这些如何成为一个大话题。这是我将很快在 Breeze 文档中讨论的内容。将这个答案视为即将发生的事情的味道。要点是……您有很好的选择来隐藏用户不应该看到的数据。

于 2013-04-21T23:03:13.357 回答
2

感谢 John 提供此信息,我查看了该信息,这对客户端过滤很有帮助。我发现我可以从客户端和/或服务器端做到这一点。

微风客户端:

var query = EntityQuery.from("Customers")
.select("ID, FirstName, LastName");

服务器端:

    [HttpGet]
    public IQueryable<Contact> GetContacts()
    {
        var contactList = _contextProvider.Context.Contacts
        .ToList()
        .Select(p =>
            new Contact
            {
                FirstName = p.FirstName,
                ID = p.ID,
                LastName = p.LastName
            })
        .AsQueryable(); // actually IQueryable is not useful after "ToList()"

        return contactList ;
    }
于 2013-04-19T12:32:18.330 回答
1

Chris - 在课程中有一个关于演讲者和会话部分的例子。我从那些我不返回描述字段(用于会话)或生物字段(用于演讲者)的人返回预测。检查并使用相同的样式不为您的 Employee 类显示您的 SSN 字段

于 2013-04-18T20:25:57.107 回答
1

你不能将你的属性标记为 [NonSerialized]

[NonSerialized] 
 public string SSN { get; set; }
于 2013-04-18T20:40:10.147 回答
1

我刚刚找到了另一种根据条件忽略列的解决方案。只需添加一个属于感兴趣模型的部分类(生成我的模型)并使用ShouldSerialize%PropertyName%

namespace ProvSys.Models
{
    partial class tblEmployees
    {
        public static bool ShouldSerializeResetPassword()
        {
            // Only hand over ResetPassword Field for admin role
            return (ProvSysRepository.IsAdmin);
        }
    }
}

在此示例中,仅当用户处于管理员角色时才会传输表的ResetPassword属性。tblEmployees

于 2013-10-20T01:14:09.730 回答