Using partial and predicted objects in the Web API

I use the breeze using the Web API. I donโ€™t understand very well how to "filter columns" or how not to expose the whole table in my web API. I use the Entity Framework as a source, and both of my questions are addressed by John Papa here: http://www.johnpapa.net/spajs04/#comment-113761 and confirmed that they are a good solution to Ward Bell below. Can someone please show me how I should use the entity infrastructure to create a partial or projection query, which is requested in my webapi and will work with the breeze?

Here is my current function in webapi

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

Here is my current class:

 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; } } 

I would like to have the requested webapi function, which is the current WITHOUT class in the SSN field. A solution that works with the "database first" and does not involve modifying my database or adding "views" would be great.

+4
source share
5 answers

On the client side, the projection is great when you are trying to reduce the payload. You need something server-side, when you need to make sure that certain data (for example, SSN) is really and safely hidden from the client.

@james suggestion - use the [NonSerialized] attribute (or JSON.NET [JsonIgnore] ) - this is a simple and efficient approach when the SSN should never go to the client.

It is too inflexible if the SSN is to be visible on the client in permitted circumstances (for example, a user viewing his own SSN or an HR person with the right to see the SSN). JSON.NET IContractResolver gives you tremendous flexibility with a dynamic solution based on authorization rules about which properties can cross the boundary of a service.

Some may consider the serializer problem as too much of a hack. They may be satisfied with the server-side projection you showed @chris_dotnet. By the way, it still makes sense to return IQueryable from the projection so that the client can reduce the network payload using a filter query.

Others prefer to define DTO ( ContactDTO ) and serialize it by wire.

  [HttpGet]
     public IQueryable GetContacts ()
     {
       return _contextProvider.Context.Contacts
         .Select (p =>
             new ContactDto
             {
                 FirstName = p.FirstName,
                 ID = p.ID,
                 LastName = p.LastName
             });
     }

This IQueryable more reliable than the projection version because filtering can be done at the data level rather than at the server level.

On the client side, you can either define metadata for the ContactDTO type, or use the JsonResultsAdapter to map ContactDTO data to a Contact Breeze object.

Using the JsonResultsAdapter assumes that you really want the Contact type โ€” the type that it is formed in the business model on the server โ€” to be known on the client.

You may not need the server-side Contact form from your service. Many people take this very strongly. If you are one of those people, you'd better define a โ€œDTO modelโ€ that represents entities as you want them to be seen on the client. This means learning to create metadata for your DTO model and writing server mapping logic to move between the DTO and your business model.

You can see how all this can become a big topic. This is the one that I will come to Breeze documentation soon. View this answer as a taste of future events. Conclusion ... you have a good choice for hiding data that users should not see.

+6
source

Thanks to John for this information, I took a look at it, and it was useful for client-side filtering. I found that I can do this from the client and / or server side.

Client side with a breeze:

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

Server side:

  [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 ; } 
+2
source

Chris - In this example, there is an example with particles of a speaker and a session. I return forecasts from those where I do not return a description field (for sessions), as well as a bio field (for speakers). Check this out and use the same style that you don't show your SSN field for your Employee class

+1
source

Can you mark your attribute as [NonSerialized]

 [NonSerialized] public string SSN { get; set; } 
+1
source

I just found another solution to ignore columns based on criteria. Just add a partial class (my model will be generated) belonging to the model of interest, and use ShouldSerialize%PropertyName% :

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

In this example, the ResetPassword property of the ResetPassword table tblEmployees passed only if the user is an administrator.

+1
source

All Articles