Łukasz Ziomek

Łukasz Ziomek .NET Developer

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

Witam

Napisałem serwis WCF. Serwis przesyła do klienta obiekt „Pozycja”, kod poniżej. Jedną z właściwości jest właściwość obliczana dynamicznie – „Wartosc”.

[DataContract]
public class Pozycja
{
[DataMember]
public double Ilosc { get; set; }

[DataMember]
public double CenaJednostkowa { get; set; }

[DataMember]
public double Wartosc
{
get
{
return Ilosc * CenaJednostkowa;
}
private set { }
}
}

Po stronie serwera wszystko działa ok. Niestety, po wysłaniu obiektu do klienta, lub utworzeniu tego typu obiektu u klienta, właściwość „Wartosc” nie jest już obliczana dynamicznie, staje się zwykłym {get; set;}

Czy istnieje sposób aby po serializacji i deserializacji obiektu nadal działały właściwości wyliczane?

Chciałbym aby klient pobrał obiekt, zmienił wartość "Ilosc" i aby automatycznie policzyła się wartość w obiekcie (bez wysyłania obiektu do serwera).

Pozdrawiam
Łukasz

konto usunięte

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

Łukasz Ziomek:
Witam

Napisałem serwis WCF. Serwis przesyła do klienta obiekt „Pozycja”, kod poniżej. Jedną z właściwości jest właściwość obliczana dynamicznie – „Wartosc”.

[DataContract]
public class Pozycja
{
[DataMember]
public double Ilosc { get; set; }

[DataMember]
public double CenaJednostkowa { get; set; }

[DataMember]
public double Wartosc
{
get
{
return Ilosc * CenaJednostkowa;
}
private set { }
}
}

Po stronie serwera wszystko działa ok. Niestety, po wysłaniu obiektu do klienta, lub utworzeniu tego typu obiektu u klienta, właściwość „Wartosc” nie jest już obliczana dynamicznie, staje się zwykłym {get; set;}

Czy istnieje sposób aby po serializacji i deserializacji obiektu nadal działały właściwości wyliczane?

Chciałbym aby klient pobrał obiekt, zmienił wartość "Ilosc" i aby automatycznie policzyła się wartość w obiekcie (bez wysyłania obiektu do serwera).

Pozdrawiam
Łukasz

Po co tam jest setter jak jest on pusty? Wywal go :)
Nie sprawdzałem, ale postaraj się wywalić też atrybut [DataMember] z dynamicznej wartości.Karim A. edytował(a) ten post dnia 15.09.10 o godzinie 14:36
Łukasz Ziomek

Łukasz Ziomek .NET Developer

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

Karim A.:
Po co tam jest setter jak jest on pusty? Wywal go :)

Jak dla mnie też jest niepotrzebny, ale bez settera nie działa serializacja obiektu i usługa wcf się wywala.

konto usunięte

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

Łukasz Ziomek:
Karim A.:

Po co tam jest setter jak jest on pusty? Wywal go :)

Jak dla mnie też jest niepotrzebny, ale bez settera nie działa serializacja obiektu i usługa wcf się wywala.


To wywal też i atrybut [DataMember]. Raczej zbędna jest serializacja tej właściwości.
Łukasz Ziomek

Łukasz Ziomek .NET Developer

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

Karim A.:
To wywal też i atrybut [DataMember]. Raczej zbędna jest serializacja tej właściwości.

OK, ale jak wtedy dostać się do tej wyliczanej właściwości na kliencie? I właśnie o to mi chodzi :)
Tomasz Poradowski

Tomasz Poradowski Specjalista od
wytwarzania
oprogramowania

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

W prosty sposób (bo pewnie jakoś by się dało jakby ktoś się bardzo uparł) nie ma takiej możliwości - bo chciałbyś "zserializować" także logikę biznesową i sprowadzić rolę serwisu do zwykłego pośrednika wymiany obiektów z danymi. Jeśli już, to zastanów się nad udostępnieniem klientom metody serwisu WyliczWartosc(List<Pozycja> lub Pozycja), co na przyszłość pozwoli Ci zachować logikę biznesową u siebie bez konieczności uaktualniania klientów (np. potem dodasz rabaty, promocje, etc. - i co wtedy z klientami, którym skopiowałbyś swoje "Wartosc = ilosc * cena"?).
Tomasz Poradowski

Tomasz Poradowski Specjalista od
wytwarzania
oprogramowania

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

Łukasz Ziomek:
Karim A.:

To wywal też i atrybut [DataMember]. Raczej zbędna jest serializacja tej właściwości.

OK, ale jak wtedy dostać się do tej wyliczanej właściwości na kliencie? I właśnie o to mi chodzi :)
Jeżeli tak bardzo Ci na tym zależy i rzeczywiście tylko tyle potrzebujesz - to po stronie klienta dodaj sobie taką właściwość z interesującym Cię wyliczeniem - umożliwi Ci to "partial class", gdyż tak właśnie będzie zdefiniowana w wygenerowanym proxy klasa Pozycja i dzięki temu możesz ją sobie rozszerzyć.

konto usunięte

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

Łukasz Ziomek:
Karim A.:

To wywal też i atrybut [DataMember]. Raczej zbędna jest serializacja tej właściwości.

OK, ale jak wtedy dostać się do tej wyliczanej właściwości na kliencie? I właśnie o to mi chodzi :)

Dobre pytanie!

Masz dwa rozwiązania do tego żeby konsumować web service:

1. Klasyczna metoda, że wszystko leży po stronie serwera a po stronie klienta obiekty są generowane na podstawie WSDL jaki publikuje web service. W tej metodzie to jest zrozumiałe, że kontrakty nie mają dynamicznych wartości z tego względu, że muszą być najpierw zapisane w XML (WSDL) a jak wiadomo, XML jest językiem opisowym i ciężko w nim wyrazić logikę. Dlatego tym sposobem nie będziesz w stanie mieć dynamicznych wartości w DataContract.

2. Współdzielone kontrakty, umieść wszystkie typy DataContract, ServiceContract MessageContract w jednej dllce. Same interfejsy i kontrakty.
Następnie po stronie serwera użyj tej dllki, dzidzić z tego interfejsu co jest ServiceContract i w dziedziczącej klasie zaimplementuj logikę serwisu. Będziesz tak miał załatwioną stronę serwera.

Po stronie klienta, również użyj tej dllki z kontraktami i nie generuj obiektów za pomocą "Add service reference" tylko dziedzicz z tego interfejsu kontraktu i z ClientBase. Zaimplementuj interfejs tak, żeby tylko odwoływał się do ClientBase.

np:

interfejs a
{
metoda1()
metoda2()
}


klient:


class aClient: ChannelBase<a>, a
{
metoda1()
{
return Channel.a();
}
...


W ten sposób będziesz miał zachowaną logikę data kontraktów (bo masz bezpośredni dostęp do kodu i implementacji.

Inną zaletą tego rozwiązania jest to, że klient i serwer zawsze będą zsynchronizowani pod względem zmian web service.

Pozdrawiam

EDIT: Widzę, że Tomasz mnie wyprzedził z identycznym pomysłem w trakcie kiedy pisałem posta ;)Karim A. edytował(a) ten post dnia 15.09.10 o godzinie 15:10
Tomasz Poradowski

Tomasz Poradowski Specjalista od
wytwarzania
oprogramowania

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

To jeszcze dorzucając punkt 3 do odpowiedzi Karima:
3. Jeżeli planujesz mieć więcej niż jedną aplikację kliencką, to współdzielenie kontraktów powierz adapterowi, czyli:

serwis <-> adapter (z klasami proxy do serwisu) <-> klient1, klient2, klient3, ...

Wtedy wszystkie dodatki (jak wyliczana właściwość "Wartosc") czy zmiany w kontraktach ukrywasz w adapterze (który udostępniasz klientom, więc masz kontrolę nad wyliczaniem np. właściwości "Wartosc"), a zmiana kontraktów niekoniecznie musi pociągać wtedy za sobą zmiany w klientach (o ile nie muszą skorzystać z uaktualnionego adaptera). Owszem, jest to dodatkowa warstwa abstrakcji, ale wszystko zależy od potrzeb :)
Łukasz Ziomek

Łukasz Ziomek .NET Developer

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

Dziękuje za odpowiedzi i naprowadzenie na rozwiązanie :) Przemyśle sprawę i coś wykombinuje :)

Pozdrawiam
Łukasz

konto usunięte

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

Lukasz, wydaje mi sie ze potrzebujesz tego:
http://msdn.microsoft.com/en-us/library/system.runtime...

konto usunięte

Temat: .NET WCF Przesyłanie obiektów z wyliczanymi właściwościami

Bardziej tego: http://www.code-magazine.com/Article.aspx?quickid=0809101

Następna dyskusja:

Poznańska Grupa .NET




Wyślij zaproszenie do