Как предотвратить раскрытие частных свойств в объектах .NET как общедоступных через службы? - PullRequest
3 голосов
/ 13 февраля 2009

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

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

Ответы [ 2 ]

3 голосов
/ 13 февраля 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), которые можно легко разделить и расширить.

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

2 голосов
/ 13 февраля 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...