Как предотвратить раскрытие частных свойств в сущностях .NET как общедоступных через службы?

Я создаю службу WCF, которая передает объекты сущностей, созданные через структуру сущностей. У меня есть объект User, который сопоставляется с таблицей User db. Существуют определенные пользовательские поля (пароль, DateCreated и т. Д.), Которые я не хочу раскрывать клиенту, но, поскольку они не допускают значения NULL в базе данных, Visual Studio требует сопоставлений. Установка этих свойств как частных кажется хорошим решением, но эти свойства преобразуются в общедоступные при использовании клиентом.

Есть ли способ обойти это или лучший подход? Я бы предпочел избегать изменения этих полей на уровне базы данных, просто чтобы порадовать EF.


person Keith    schedule 12.02.2009    source источник


Ответы (2)


Вы всегда можете реализовать IXmlSerializable для объекта. объект. Тогда вы сможете диктовать структуру того, что отправляется клиенту (очевидно, клиент получит другое представление).

Либо так, либо, если можете, добавьте атрибут DataContract к типу, а атрибут DataMember только для тех свойств, которые вы хотите передать по сети.

person casperOne    schedule 12.02.2009
comment
Это самый простой и, я считаю, совершенно правильный ответ. - person EnocNRoll - AnandaGopal Pardue; 13.02.2009
comment
Очень просто и интуитивно понятно ... Я попробую. Спасибо! - person Keith; 13.02.2009

Похоже, это прекрасная возможность разделить слои приложения. Что вам следует сделать, так это создать объекты, специфичные для уровня WCF, которые действуют только как объекты передачи данных (DTO) для внешних потребителей.

Итак, на уровне службы WCF вы будете выполнять вызовы на уровень доступа к данным (Entity Framework), который извлекает объекты User, и вы должны вернуться к своим объектам-потребителям, созданным только с тем, что вы хотите раскрыть.

Если вы сделаете это, вы можете явно контролировать то, что вы делаете видимым для внешнего мира, а также скрывать любые детали реализации того, что вы делаете, с точки зрения хранения данных.

В качестве чрезвычайно грубого примера на уровне Entity Framework у вас может быть этот объект:

namespace ACME.DataAccessLayer.Entities
{
    public class User
    {
        public int Id { get; set; }

        public string UserName { get; set; }

        public string Password { get; set; }

        public string Hash { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }
    }
}

namespace ACME.DataAccessLayer.Services
{
    using ACME.DataAccessLayer.Entities;

    public class UserService
    {
        public User GetUser(int id)
        {
            using (ACMEDataContext dc = new ACMEDataContext())
            {
                // psuedo code to return your user with Entity Framework
                return dc.Users.FirstOrDefault(user => user.Id == id);
            }
        }
    }
}

Затем в вашем WCF позже у вас может быть такая сущность, как:

namespace ACME.Services.DataTransferObjects
{
    [DataContract]
    public class User
    {
        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public string FirstName { get; set; }

        [DataMember]
        public string LastName { get; set; }
    }
}

Then you would expose a service endpoint that would return back the DTO as such:

namespace ACME.Services
{
    using ACME.DataAccessLayer.Services;

    public class PublicWCFService : IUserService
    {
        public ACME.Services.DataTransferObjects.User GetUser(int userId)
        {
            ACME.DataAccessLayer.Entities.User entityFrameowrkUser = new UserService().GetUser(userId);

            return new ACME.Services.DataTransferObjects.User
                       {
                           Id = entityFrameowrkUser.Id,
                           FirstName = entityFrameowrkUser.FirstName,
                           LastName = entityFrameowrkUser.LastName
                       };
        }
    }
}

Теперь вам нужно просто вернуть объект DTO, который не будет иметь никаких атрибутов или методов, которые могут быть у вас в реальных объектах, которые вы используете в своей системе.

При таком подходе вы можете безопасно разбить уровни приложения на разные уровни (DLL), которые можно легко совместно использовать и расширять.

Это быстрый пример, поэтому дайте мне знать, если есть что-нибудь еще, что сделало бы этот пример более понятным.

person Dean Poulin    schedule 12.02.2009