Laboratorium 10 - Web Services W ramach laboratorium zapoznamy się z koncepcją Web Service ów (odmiana point-to-point Web Service). W kolejnych krokach utworzony zostanie projekt, w którym wykorzystana zostanie istniejąca usługa sieciowa. Następnie utworzony zostanie kolejny projekt, w którym zbudujemy i opublikujemy własną usługę. W dalszej części dołączymy ją do swojego projektu konsumenta. Na zakończenie wykonamy połączenia z usługą sieciową w sposób asynchroniczny i na dowolnym strumieniu danych. A. Konsumpcja usługi WS Zadanie polega na utworzeniu projektu ASP.NET Web Site o nazwie GeoIP. Do utworzonej strony Default.aspx dodajemy TextBox a o nazwie adres i Button Sprawdz oraz jedną Label o nazwie wynik. Dodajemy do projektu referencje Add Web References w url podać adres: http://ws.cdyne.com/ip2geo/ip2geo.asmx?wsdl, kliknąć GO -> wyszuka i pokaże jakie metody oferuje wołana usługa sieciowa. W polu Web reference name podać GeoIP i kliknąć Add Reference. 1
Dodajemy metodę na OnClick do Button a protected void Button1_Click(object sender, EventArgs e) try IPHostEntry ipki = Dns.GetHostEntry(TextBox1.Text); String ip= ipki.addresslist[0].tostring(); GeoIP.IP2Geo geo = new GeoIP.IP2Geo(); GeoIP.IPInformation info = new GeoIP.IPInformation(); info = geo.resolveip (ip,"0"); Label1.Text = info.country; catch (Exception ex ) Label1.Text = ex.message; Dodać using System.Net; B. Tworzenie własnej usługi WS Zadaniem będzie utworzenie własnego WS o nazwie kalkulator z czterema metodami dodaj, odejmnij, mnoz, dziel. Tworzymy nowy projekt typu Web Site i wybieramy template ASP.NET Web Service o nazwie Kalkulator Wpisujemy kod czterech metod nasze usługi [WebService(Namespace = "http://dziubich.net/")] [WebServiceBinding(ConformsTo = WsiProfiles.None)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. // [System.Web.Script.Services.ScriptService] public class Service : System.Web.Services.WebService public Service () //Uncomment the following line if using designed components //InitializeComponent(); [WebMethod] public double dodaj(double a, double b) return (a + b); [WebMethod(MessageName="dodaj2")] public double dodaj(string a, String b) return dodaj(double.parse(a),double.parse(b)); [WebMethod(Description="Metoda odejmuje dwie liczby")] public double odejmnij(double a, double b) return (a - b); [WebMethod] public double mnoz(double a, double b) return (a * b); 2
[WebMethod] public double dziel(double a, double b) if (b == 0) throw new Exception("Bład dzielenia przez zero"); return (a/b); C. Konsumpcja własnej WS do tego samego solution dodać projekt konsolowy z dopisaniem klasy konsolowej konsumującej nasz WS kalkulator należy dodać usługę sieciową przez Add Service Reference -> Advanced -> Add Web References D. Wywołanie asynchroniczne WS Celem jest utworzenie klienta WS, która tłumaczy zadany tekst na alfabet Brailla. W tym celu zakładamy nowe Solution i projekt WinForm. Dodajemy referencje WSX do usługi http://www.webservicex.net/braille.asmx?wsdl (jak w punkcie C) Na formie umieszczamy jeden TextBox, Button i PictureBox. Dodajemy przestrzeń nazw System.IO. Dodajemy metodę na OnClick do Button a private void button1_click(object sender, EventArgs e) WSX.Braille usluga = new WSX.Braille(); // przy wpisaniu poniższej linii po znaku += można użyć //Alt+TAB do wygenerowania potrzebnego nagłówka metody usluga.brailletextcompleted += new WindowsFormsApplication6.WSX.BrailleTextCompletedEventHandl er(usluga_brailletextcompleted); usluga.brailletextasync(this.textbox1.text, (float)26.0); void usluga_brailletextcompleted(object sender, WindowsFormsApplication6.WSX.BrailleTextCompletedEventArgs e) byte[] obraz = e.result; this.picturebox1.image = new Bitmap (new MemoryStream(obraz)); 3
E. Strumień danych wykorzystanie gotowego WS (mapy) w aplikacji typu WindowsForm W kolejnym kroku podejmiemy próbę pobrania mapy dla określonych współrzędnych geograficznych. 1. W nowym solution zakładamy nowy projekt Windows Forms Application o nazwie KlientWSMap. 2. Do utworzonego projektu dodajemy referencję od usługi przez Add Service References (Z okna usługi klikamy na Advanced i wybieramy Add Web References) lub Add Web References bezpośrednio jeżeli jest. Wpisujemy adres http://terraservice.net/terraservice2.asmx i nazywamy przestrzeń jako TS. Klikamy na Add References Pieniek dla wywołania usługi został wygenerowany. W kodzie Form1.cs, uzupełniamy namespace y o System.Drawing.Imaging i System.IO i dodajemy poniższe metody wywołujące WS. //metoda pobierająca obraz zawierający dane miejsce. Bitmap GetTiledImage(string City, string State, TS.Scale Scale, int cx, int cy) Bitmap bitmap = null; Graphics g = null; try // budowanie obiektu z klasy pienka TS.TerraService ts = new TS.TerraService(); // ustawienie danych miejsca do wyświetlenia TS.Place place = new TS.Place(); 4
place.city = City; place.state = State; place.country = "USA"; // pozyskanie współrzędnych miejsca do wyświetlenia TS.LonLatPt point = ts.convertplacetolonlatpt(place); // Compute the parameters for a bounding box TS.AreaBoundingBox abb = ts.getareafrompt(point,1, Scale, cx, cy); // Create an image to fit the bounding box bitmap = new Bitmap(cx, cy, PixelFormat.Format32bppRgb); g = Graphics.FromImage(bitmap); int x1 = abb.northwest.tilemeta.id.x; int y1 = abb.northwest.tilemeta.id.y; int x2 = abb.northeast.tilemeta.id.x; int y2 = abb.southwest.tilemeta.id.y; for (int x = x1; x <= x2; x++) for (int y = y1; y >= y2; y--) TS.TileId tid = abb.northwest.tilemeta.id; tid.x = x; tid.y = y; Image tile = Image.FromStream (new MemoryStream(ts.GetTile(tid))); g.drawimage(tile, (x - x1) * tile.width - (int)abb.northwest.offset.xoffset, (y1 - y) * tile.height - (int)abb.northwest.offset.yoffset, tile.width, tile.height); tile.dispose(); mapy"); return bitmap; catch (Exception) if (bitmap!= null) bitmap.dispose(); return GetErrorImage("Nie można pokazać żądanej 5
finally if (g!= null) g.dispose(); Bitmap GetErrorImage(string message) Bitmap bitmap = new Bitmap(1, 1, PixelFormat.Format32bppRgb); Graphics g = Graphics.FromImage(bitmap); Font font = new Font("Verdana", 8); SizeF size = g.measurestring(message, font); int cx = (int)size.width; int cy = (int)size.height; bitmap.dispose(); g.dispose(); // Generate a bitmap containing the error message bitmap = new Bitmap(cx, cy, PixelFormat.Format32bppRgb); g = Graphics.FromImage(bitmap); SolidBrush redbrush = new SolidBrush(Color.Red); SolidBrush whitebrush = new SolidBrush(Color.White); g.fillrectangle(whitebrush, 0, 0, 256, 64); g.drawstring(message, font, redbrush, 0, 0); whitebrush.dispose(); redbrush.dispose(); font.dispose(); g.dispose(); // Return the image return bitmap; 6
Na formę wstawiamy kontrolkę PictureBox oraz przycisk Pobierz mapę Do przycisku Pobierz mapę dopisujemy metodę na kliknięcie private void button1_click(object sender, EventArgs e) this.picturebox1.image = GetTiledImage("Los Angeles", "CA", TS.Scale.Scale8m, picturebox1.width, picturebox1.height); 7