Partilhar via


Авто подстройка адреса в апплете Silverlight, который вызывает веб сервис с своего сайта.

Я думал что это боян, но меня спросили об этом уже два раза – так что решил написать в блог.

Итак, задача

Дано – есть силверлайт приложение ну или там компонент, в котором используется wcf сервис с того же самого сайта, откуда мы грузим силверлайт приложение (знакомый сценарий, не правда ли).

Мы не знаем URL на котором окажется наше приложение.

Мы при разработке делаем Add Sevrice Reference, получаем ссылку на localhost, в промышленном исполнении получается ссылка не правильная.

ЧТО ДЕЛАТЬ?????!

Решения.

1) Теоретически можно открыть xap файл, это же zip! (и поменять настройку в ServiceReferences.ClientConfig)

2) опишу тут кратко, весь сценарий подробно позже.

нужно при инициализации ServiceClient поменять ему строчку адреса, получив адрес из системы Silverlight, например так

Code Snippet

  1.             service = new ServiceReference1.Service1Client();

  2.             var host = App.Current.Host;

  3.             var newAddress = string.Format("https://{0}:{1}/Service1.svc",

  4.                     host.Source.Host, host.Source.Port);

  5.             service.Endpoint.Address =

  6.                 new EndpointAddress(newAddress

  7.                     );

нужно помнить, что config файл не является финальной настройкой, и всегда можно поправить что то в коде.

Подробности

Что я сделал.

1) создал silverlight приложение (file\new project)

Capture01

Capture02

2) В сайт добавил (правая  кнопка на веб сайте, add New item) WCF сервис.

Capture03

3) переписал сервис чтобы он что то возвращал

Code Snippet

  1.         [OperationContract]

  2.         public string DoWork()

  3.         {

  4.             return DateTime.Now.ToString(); ;

  5.         }

3) В силверлайт клиента добавил Add Service Reference

Capture03_1

4) написал простое silverlight приложение, которое содержит кнопку, по нажатию на кнопку вызывает сервис. В начале сервис динамически  инициализируется

Code Snippet

  1.     public partial class MainPage : UserControl

  2.     {

  3.         ServiceReference1.Service1Client service;

  4.         public MainPage()

  5.         {

  6.             service = new ServiceReference1.Service1Client();

  7.             var host = App.Current.Host;

  8.             var newAddress = string.Format("https://{0}:{1}/Service1.svc",

  9.                     host.Source.Host, host.Source.Port);

  10.             service.Endpoint.Address =

  11.                 new EndpointAddress(newAddress

  12.                     );

  13.             service.DoWorkCompleted += new EventHandler<ServiceReference1.DoWorkCompletedEventArgs>(service_DoWorkCompleted);

  14.             InitializeComponent();

  15.         }

  16.         private void button1_Click(object sender, RoutedEventArgs e)

  17.         {

  18.             service.DoWorkAsync();

  19.         }

  20.         void service_DoWorkCompleted(object sender, ServiceReference1.DoWorkCompletedEventArgs e)

  21.         {

  22.             label1.Content = e.Result;

  23.         }

  24.         private void UserControl_Loaded(object sender, RoutedEventArgs e)

  25.         {

  26.             label2.Content = service.Endpoint.Address.ToString();

  27.         }

  28.     }

5) все! можно отправлять куда хотите и приложение само подстроит ссылки на веб сервисы. Я для тестирования менял порт в веб сайте без обновления service reference – все работало.

 код прилагается.

SilverlightWcfProject.zip

Comments

  • Anonymous
    February 24, 2010
    Здравствуйте! Все работает, но только если сервис лежит в корне. Как быть, в случае, если у сервиса фактический адрес такой: "http://myhost/folder/Service1.svc"? Апплет silverlight же показывает такой адрес endpoint'a: "http://myhost/Service1.svc"

  • Anonymous
    May 30, 2010
    Классно. Работает на делоперском компьютере даже если сервисе лежит в подпапке, но на продакшине не работает. Ошибка The remote server returned an error: NotFound. Что может быть: crossdomain, security? Спасибо.