Как Вы возвращаете определяемый пользователем тип из службы WCF?

Прежде всего, абсолютно не используйте IntegerFields для этих значений. Это внешние ключи, вы должны использовать поле ForeignKey. Они должны называться user и client - обратите внимание, что вы по-прежнему можете получить доступ к базовым идентификаторам, как и раньше.

(Кроме того, нет необходимости явно объявлять поле id; вам почти никогда не следует переопределять __init__ в модели, но особенно нет никакой точки, переопределяющей метод, который вызывает только супер метод. Просто удалите это.)

class AccessLevel(models.Model):
    user = models.ForeignKey('Users', null=False, blank=False)
    client = models.ForeignKey('Client', null=False, blank=False)

class Users(models.Model):
    client = models.ForeignKey('Client', null=False, blank=False)

Теперь, для вашей реальной проблемы, идентификатор назначается базой данных, что происходит только после сохранения. Таким образом, вы должны создать связанный элемент после этого.

def save(self, *args, **kwargs):
    super(Users, self).save(*args, **kwargs)
    AccessLevel(user_id=self.id,
            client_id=self.client_id).save(using='default')

    print('Access Level Set for User while saving')

Другим способом создания элемента, который может быть немного более понятным, является использование средства доступа, предоставляемого внешним ключом:

self.accesslevel_set.create(client_id=self.client_id)

Наконец, это, вероятно, лучше, чем [117 ] сигнал после сохранения , а не в методе сохранения.

7
задан flesh 13 January 2009 в 11:32
поделиться

4 ответа

Только к мыслям второго Yossi's/Rich:

  • да, можно добавить ссылку на общий dll (вместо того, чтобы использовать сгенерированный прокси-класс)
  • да, это побеждает много намерения контрактов данных, и если какой-либо вид пользовательской сериализации происходит, у Вас могут быть проблемы, расширяющие Ваш сервис

Я шел по этой дороге прежде и до некоторой степени жаль, что не имел. Расширяемость ре / пользовательская сериализация - необходимо быть очень осторожными. Немного легче, если Вы используете предварительно прокрученный сериализатор, такой как protobuf-сеть (который может интегрироваться непосредственно в WCF, и который разработан с расширяемостью в памяти), но не легкий.

На самом деле одно преимущество совместного использования классов состоит в том, что оно делает немного легче протестировать: так как у Вас есть то же IFoo везде, можно дразнить это IFoo с разумными шансами на успех. Более трудно дразнить, когда прокси принимает участие (поскольку Вы изменяете больше подвижных частей между тестовым кодом и производственным кодом).

4
ответ дан 6 December 2019 в 08:17
поделиться

Если тип, который Вы хотите возвратить из своего служебного вызова, не отмечен как a DataContract затем Вы не сможете возвратить его из WCF, не предоставляя копию того же самого блока к Вашему клиентскому приложению.

using System;
using System.ServiceModel;

[ServiceContract]
interface IService
{
    [OperationContract]
    TimeSpan GetTimeSpan();
}

class Service : IService
{
    public TimeSpan GetTimeSpan() { return DateTime.Now.TimeOfDay; }
}

Почему предыдущее кодирует работу затем? Это работает, потому что обе стороны служебного вызова имеют System.dll таким образом, они оба знают о System.TimeSpan введите, который является типом возврата OperationContract GetTimeSpan().

Вот пример с помощью a DataContract:

using System;
using System.ServiceModel;
using System.Runtime.Serialization;

[ServiceContract]
interface IService
{
    [OperationContract]
    Contract GetContract();
}

[DataContract]
class Contract
{
    [DataMember]
    public String MyProperty { get; set; }
}

class Service : IService
{
    public Contract GetContract() { return new Contract(); }
}

Теперь Вы предоставили атрибуты сериализации классу, который Вы определили (Contract) - это позволит Вам использовать svcutil.exe создать прокси-классы в Вашем клиентском приложении, которое будет сериализировано и отправлено службе WCF.

Теперь, если Вы хотите возвратить тип, который не является a DataContract необходимо предоставить копию блока, содержащего тот тип к клиентскому приложению.

10
ответ дан 6 December 2019 в 08:17
поделиться

Одна из вещей, которые должны будут произойти, - то, что пользователь должен настроить сервисную ссылку для использования типов от DLL, а не класса, определенного прокси - http://msdn.microsoft.com/en-us/library/bb628653.aspx

4
ответ дан 6 December 2019 в 08:17
поделиться

Мы спустились с того пути в прошлом, и действительно проблема состоит в том, что, конечно, это два различных класса, таким образом, необходимо будет перейти по ссылке, предоставленной @Rich Агентством Рейтер;

Мы, тем не менее, научились на горьком опыте, почему это - плохая практика, поскольку она идет agains 3-й принцип SOA - "Сервисы совместно используют схему и контракт, не класс".

Конечно, проблема только не следует "правилу", установленному кем-то в какой-то момент, но что были большие причины этого, чтобы быть предложенными - мы узнали, что цена такого плотного соединения между сервисом и клиентом означает, что очень трудно выпустить любого - если сервис должен добавить другое поле к тому классу, для обслуживания другого клиента - первый клиент мог бы быть затронут; если сервис, чем потребности изменить что-то в том определении класса (для обслуживания другого клиента) - первый клиент будет снова затронут, и наоборот - клиент может влиять на жизненный цикл сервиса.

В крупных проектах это быстро становится огромной нагрузкой обслуживания.

4
ответ дан 6 December 2019 в 08:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: