Авто подстройка адреса в апплете Silverlight, который вызывает веб сервис с своего сайта.
Я думал что это боян, но меня спросили об этом уже два раза – так что решил написать в блог.
Итак, задача
Дано – есть силверлайт приложение ну или там компонент, в котором используется wcf сервис с того же самого сайта, откуда мы грузим силверлайт приложение (знакомый сценарий, не правда ли).
Мы не знаем URL на котором окажется наше приложение.
Мы при разработке делаем Add Sevrice Reference, получаем ссылку на localhost, в промышленном исполнении получается ссылка не правильная.
ЧТО ДЕЛАТЬ?????!
Решения.
1) Теоретически можно открыть xap файл, это же zip! (и поменять настройку в ServiceReferences.ClientConfig)
2) опишу тут кратко, весь сценарий подробно позже.
нужно при инициализации ServiceClient поменять ему строчку адреса, получив адрес из системы Silverlight, например так
Code Snippet
service = new ServiceReference1.Service1Client();
var host = App.Current.Host;
var newAddress = string.Format("https://{0}:{1}/Service1.svc",
host.Source.Host, host.Source.Port);
service.Endpoint.Address =
new EndpointAddress(newAddress
);
нужно помнить, что config файл не является финальной настройкой, и всегда можно поправить что то в коде.
Подробности
Что я сделал.
1) создал silverlight приложение (file\new project)
2) В сайт добавил (правая кнопка на веб сайте, add New item) WCF сервис.
3) переписал сервис чтобы он что то возвращал
Code Snippet
[OperationContract]
public string DoWork()
{
return DateTime.Now.ToString(); ;
}
3) В силверлайт клиента добавил Add Service Reference
4) написал простое silverlight приложение, которое содержит кнопку, по нажатию на кнопку вызывает сервис. В начале сервис динамически инициализируется
Code Snippet
public partial class MainPage : UserControl
{
ServiceReference1.Service1Client service;
public MainPage()
{
service = new ServiceReference1.Service1Client();
var host = App.Current.Host;
var newAddress = string.Format("https://{0}:{1}/Service1.svc",
host.Source.Host, host.Source.Port);
service.Endpoint.Address =
new EndpointAddress(newAddress
);
service.DoWorkCompleted += new EventHandler<ServiceReference1.DoWorkCompletedEventArgs>(service_DoWorkCompleted);
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
service.DoWorkAsync();
}
void service_DoWorkCompleted(object sender, ServiceReference1.DoWorkCompletedEventArgs e)
{
label1.Content = e.Result;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
label2.Content = service.Endpoint.Address.ToString();
}
}
5) все! можно отправлять куда хотите и приложение само подстроит ссылки на веб сервисы. Я для тестирования менял порт в веб сайте без обновления service reference – все работало.
код прилагается.
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? Спасибо.