Sử dụng WCF Service trên Windows Phone 8.1

Sử dụng WCF Service trên Windows Phone 8.1
5 (100%) 3 votes

Trong bài viết trước các bạn đã biết cách viết và cấu hình các WCF REST Service để có thể sử dụng được trên các ứng dụng Mobile. Nếu bạn chưa biết cách sử dụng WCF REST Service hãy cùng xem lại bài viết này:

Trong bài viết này chúng ta sẽ cùng tìm hiểu phần còn lại đó là cách thức sử dụng WCF REST Service trong Windows Phone 8.1

Mở đầu

Trước đây trên Windows Phone 7, Windows Phone 8, Windows 8.1 cách thức sử dụng các WCF Service tương đối dễ dàng chỉ cần Add Service Reference là có thể gọi được luôn các hàm đã được định nghĩa trong WCF Service này. Lên phiên bản Windows Phone 8.1 mọi thứ có vẻ hơi khác lạ một chút vì sẽ có 2 cách thức khác nhau để xây dựng ứng dụng cho Windows Phone đó là sử dụng core Silverlight hoặc Windows Runtime. Các bạn có thể xem qua bài viết sau để hiểu rõ hơn về 2 cách thức này:

Chúng ta sẽ cùng đi tìm hiểu chi tiết cách sử dụng WCF Service với source code chính là ví dụ demo trong bài trước có 2 hàm là GetMessage và PostMessage.

Sử dụng WCF Service trên Windows Phone 8.1 Silverlight

Đầu tiên chúng ta sẽ nói về cách sử dụng WCF Service trên Windows Phone 8.1 Silverlight. Cách thức này đều có thể áp dụng được trên Windows Phone 7, Windows Phone 8, Windows 8.1 App hoặc từ Desktop App (WinForm), Web App (ASP.NET, ASP.NET MVC…)

  • Bước 1: Trong solution WCFRESTDemo ta tạo Project Windows Phone 8.1 Silverlight như hình dưới:
    Tạo Windows Phone Silverlight App
  • Bước 2: Ctrl-F5 để chạy WCF Service lên, mục đích của bước này là để tìm được service khi Add Reference ở bước tiếp theo
    WCF Service Browser
  • Bước 3: Right-click vào References và chọn Add Service Reference. Sau đó ta nhấn Discover để tìm các service trong cùng Solution. Ta sẽ thấy WCFRestDemo service xuất hiện, ta tiến hành đặt tên Namespace service là WCFDemo và nhấn OK
    Add service referenceAdd service reference
  • Bước 4: Qua 3 bước trên ta đã chuẩn bị xong được kết nối đến WCF Service. Tiếp theo ta cần thiết kế giao diện ứng dụng Windows Phone để gọi các hàm trong service này. WCF Service này chỉ có 2 hàm đơn giản nên ta sẽ thiết kế thêm 2 button trên giao diện MainPage.xaml và đổi tên App và tên Page như sauDesign Windows Phone 8.1 Silverlight App
  • Bước 5: Trên Designer Double-Click vào 2 button để xử lý click event của 2 button này. Ta gọi đến 2 hàm GetMessage và PostMessage của WCF Service như bên dưới

Đến đây mọi thứ đã xong xuôi, right-click Set Startup Project là ứng dụng Windows Phone rồi nhấn F5 để hưởng thụ thành quả.
Visual Studio 2013 Set Startup Project

Click thử vào button GetMessage chúng ta sẽ thấy thay vì hiển thị message trả về từ WCF Service thì sẽ có lỗi xảy ra như hình dưới

WCF Endpoint not found exception

Lỗi này là do ở trong ví dụ bài trước chúng ta mới chỉ cấu hình WCFRestDemo service có 1 Endpoint binding webHttpBinding trả về JSON nên không thể sử dụng được với cách Add Service Reference này. Muốn sử dụng được ta phải bổ sung 1 Endpoint nữa với binding là basicHttpBinding trả về dữ liệu kiểu SOAP/XML vào trong file web.config ở project Tungnt.NET.WCFRestDemo như sau:

Sau khi bổ sung xong ta right-click WCFDemo và update lại service.

Update WCF Service Reference

Cuối cùng F5 để chạy và giờ thì mọi thứ đã hoạt động trơn tru.
Windows Phone 8.1 Siverlight AppWindows Phone 8.1 Siverlight App
Rất đơn giản và dễ dàng phải không các bạn :)

Sử dụng WCF Service trên Windows Phone 8.1 Store App/Universal App

Ở phần trên chúng ta đã kết nối và sử dụng được WCF Service với ứng dụng Windows Phone 8.1 Silverlight tương đối dễ dàng vì Visual Studio đã hỗ trợ sẵn hết. Thế nhưng với Windows Phone 8.1 Store App/Universal App với core Windows Runtime mọi thứ trở nên phức tạp hơn vì nó không còn hỗ trợ cách sử dụng Add Service Reference và gọi trực tiếp hàm nữa. Chúng ta buộc phải sử dụng cách thức xây dựng các WCF REST Service và gọi thủ công bằng việc xây dựng các HTTP GET/POST message.

Cách thức này tương đối lạ với những ai lâu nay vẫn sử dụng cách thức Add Service Reference ở trên. Cá nhân mình cũng thấy dường như Microsoft chưa hoàn thiện API này lắm vì rõ ràng là Windows 8.1 vẫn hỗ trợ cách Add Service Reference nhưng Windows Phone 8.1 thì không. Mọi thứ rất có thể sẽ thay đổi khi Windows 10 phát hành nhưng trước mắt chúng ta không còn cách nào khác là sử dụng cách thức đã nói ở trên. Nào hãy cùng bắt đầu tạo ứng dụng Windows Phone 8.1

  • Bước 1: Trong solution WCFRESTDemo ta tạo Project Windows Phone 8.1 Store App như hình dướiWindows Phone 8.1 Store App
  • Bước 2: Thiết kế giao diện ứng dụng Windows Phone tương tự ứng dụng ở trên. Thay tên App thành “Tungnt.net WP8.1 Store App”
    Windows Phone 8.1 Store App
  • Bước 3: Tương tự chúng ta xử lý click event của 2 button trên ứng dụng. Để gọi được các hàm REST chúng ta sẽ sử dụng API HttpClient, HttpRequestMessageHttpResponseMessage (thuộc namespace System.Net.Http) để gửi và nhận dữ liệu.
    Ta sẽ xây dựng 1 hàm chung để gọi 2 hàm REST GetMessage và PostMessage đặt tên là WCFRESTServiceCall. Lưu ý: URI của hàm chính là URL của WCFRestDemo service ở trên + tên phương thức GetMessage hoặc PostMessage.

Vậy là chúng ta đã xây dựng xong ứng dụng Windows Phone 8.1 kết nối đến WCF REST Service, hãy F5 để chạy thử.
Windows Phone 8.1 Store App Windows Phone 8.1 Store App

Kết luận

Trong bài viết này chúng ta đã cùng tìm hiểu cách thức sử dụng WCF Service trên ứng dụng Windows Phone. Bài viết hướng dẫn chi tiết cách làm từng bước cho cả 2 loại ứng dụng Windows Phone 8.1 Silverlight và Windows Phone 8.1 Store App. Mỗi loại đều có ưu và nhược điểm khác nhau vì vậy bạn cần cân nhắc khi sử dụng chúng trong ứng dụng của mình.

  • Add Service Reference đơn giản dễ làm hơn vì Visual Studio đã hỗ trợ tối đa nhưng lại không sử dụng được trên Windows Phone 8.1 Store App và performance không tốt bằng cách sử dụng WCF REST Service trả về JSON
  • Create GET/POST message thủ công và sử dụng HttpClient, HttpRequestMessage, HttpResponseMessage để gửi nhận khó làm hơn, phải viết nhiều code hơn nhưng bù lại hỗ trợ trên Windows Phone 8.1 Store App và performance tốt hơn do sử dụng JSON

Hy vọng bài viết đã giải đáp được phần nào thắc mắc của các bạn khi xây dựng các ứng dụng Windows Phone cần sử dụng server cloud để lưu trữ dữ liệu.

Nếu bạn có bất kì câu hỏi hay kinh nghiệm nào hãy chia sẻ bằng comment bên dưới bài viết và nếu thấy nó hữu ích hãy chia sẻ cho bạn bè của bạn nữa. Nếu bạn muốn nhận được thông báo bài viết mới từ blog của tôi vui lòng subscribe blog nhé. Xin cảm ơn.

Happy coding. Stay tuned.

P/s: Source code example các bạn có thể download tại đây: WCFRESTDemoFinal

Comments

  1. VanDung says

    mong bác có bài hướng dẫn về real time webservice.
    dạng như client A cập nhật là client B có ngay ấy ạ.
    cảm ơn bác 😀

    • tungnt185tungnt185 says

      Hi Dung, bạn có thể mô tả rõ hơn mong muốn không? Như vậy mình sẽ có cơ sở để blog hơn :) welcome bạn đến blog của mình. Ủng hộ nhé. Thanks bạn.

      • VanDung says

        Cảm ơn bác 😀
        dạng như thế này, e có 1 webservice có nhiều client tương tác để nhận, gửi dữ liệu. khi client A cập nhật thông tin lên, client B muốn có thông tin đó phải gửi request dến service để nhận dữ liệu. như vậy thì client B không biết khi nào A gửi lên để nó lấy về. qua tìm hiểu mọi người nói sử dụng Signalr, mà e không biết dùng cho windowsphone như nào? mong bác hướng dẫn 😀

        • tungnt185tungnt185 says

          Hi, Mình hiểu ý của Dung rồi. Sẽ viết một bài về cách sử dụng SignalR trên Windows Phone trong thời gian tới. Hãy subscribe blog đển nhận thông báo khi có bài viết mới nhé!

    • stevenlee says

      Ý bạn có phải là sự kiện khi hàm set ở clientA gửi dữ liệu lên server thì hàm get tự động update ở clientB.

    • tungnt185tungnt185 says

      Dung bỏ thuộc tính WrappedRequest ở service đi xong thử lại xem được không nhé. Nếu có thuộc tính này thì phải bọc Request vào trong object tên là ctcls.

      • VanDung says

        thanks bác. bỏ cái đó đi được rồi bác. 😀
        muốn sử dụng nó thì phải như nào bác

        • tungnt185tungnt185 says

          Để sử dụng WrappedRequest thì bạn build Request thêm ctcls như sau {“clcls”:{“”:””}}. Về cơ bản là gói Object hiện thời vào trong ctcls

  2. Võ Văn Trình says

    Cho em hỏi sao em làm tới “Bước 2: Ctrl-F5 để chạy WCF Service lên, mục đích của bước này là để tìm được service khi Add Reference ở bước tiếp theo” thì không chạy được WCF Service mà hiện lỗi HTTP Error 403.14 – Forbidden.
    Em nghĩ do cái này sai mà ko biết sữa sao:
    Requested URL http://localhost:7947/

    • tungnt185tungnt185 says

      Hi Trình,

      Lỗi em gặp phải có thể do em chưa set project chứa WCF service là project startup nên không chạy đc.
      Em xem lại bài viết về cách tạo wcf service dùng trên ứng dụng Mobile để biết cách kiểm tra service đã chạy được hay chưa nhé.

      Regards.

        • tungnt185tungnt185 says

          Ok em. Đăng kí blog của anh để nhận thông báo bài viết mới qua email nhé. Thanks em.

          • Võ Văn Trình says

            Anh cho em hỏi. Em làm hai cái ví dụ của anh chạy rồi. Giờ em muốn làm trên thiết bị thật và truyền, nhận một ký tự (chuỗi ký tự) lên Web thì phải làm sao ạ?

          • tungnt185tungnt185 says

            Anh ko hiểu câu hỏi của em lắm. Nếu truyền lên thì chính là VD Gửi message ở trên rồi mà.

  3. Võ Văn Trình says

    Ak. Sao cái hai cái VD em build trên máy ảo thì chạy mà build xuống máy thật ko chạy được ta.

    • tungnt185tungnt185 says

      Em ko kết nối được bởi vì device đang kết nối đến mạng internet thật.

      Bài viết ở trên hướng dẫn cách tạo và test service trong môi trường phát triển, service và emulator kết nối đến nhau trong mạng local. Khi phát triển xong muốn test trong môi trường thật, device thật thì em cần phải publish service lên host trên internet và chỉ lại đường dẫn tương ứng thay thế cho đường dẫn uri localhost hiện thời em ạ.

  4. Mr.Bong says

    Em chưa hiểu đoạn này lắm

    private void btnGetMessage_Click(object sender, RoutedEventArgs e)
    {
    WCFRestDemoClient client = new WCFRestDemoClient();
    client.GetMessageCompleted += client_GetMessageCompleted;
    client.GetMessageAsync();
    }

    void client_GetMessageCompleted(object sender, GetMessageCompletedEventArgs e)
    {
    if (e.Error == null)
    {
    MessageBox.Show(e.Result);
    }
    }

    WCFRestDemoClient client = new WCFRestDemoClient(); thì WCFRestDemoClient ở đâu ạ?
    hàm client_GetMessageComplete nữa ạ?

    • tungnt185tungnt185 says

      Hi em,

      WCFRestDemoClient là class .NET sinh ra khi em add web reference và đặt tên là WCFRestDemo .NET sẽ tự thêm Client vào. Còn hàm client_GetMessageCompleted thì chính là hàm ở dưới đã viết đấy em. Em nên download sample của bài này ở cuối bài viết để chạy thử và hiểu rõ hơn nhé.

      Regards.

  5. tranhieunknd says

    bạn cho mình hỏi chút, mình làm theo hướng dấn nhưng khi ấn 2 nút thì lúc check e.Error thì nó lại khác null, mình kiểm tra thi nó bị lỗi như nhau nhưng không biết sửa, bạn có thể giúp mình sửa được không

    System.ServiceModel.CommunicationException: The remote server returned an error: NotFound. —> System.Net.WebException: The remote server returned an error: NotFound. —> System.Net.WebException: The remote server returned an error: NotFound.
    at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
    at System.Net.Browser.ClientHttpWebRequest.c__DisplayClasse.b__d(Object sendState)
    at System.Net.Browser.AsyncHelper.c__DisplayClass1.b__0(Object sendState)
    — End of inner exception stack trace —
    at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
    at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
    at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
    — End of inner exception stack trace —
    at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
    at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
    at System.ServiceModel.ClientBase1.ChannelBase1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
    at ConnectWP_070415.WCFRest.WCFRestClient.WCFRestClientChannel.EndGetMessage(IAsyncResult result)
    at ConnectWP_070415.WCFRest.WCFRestClient.ConnectWP_070415.WCFRest.IWCFRest.EndGetMessage(IAsyncResult result)
    at ConnectWP_070415.WCFRest.WCFRestClient.OnEndGetMessage(IAsyncResult result)
    at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)

    • tungnt185 says

      Hi bạn,

      Lỗi trên là do wcf service chưa được chạy. Bạn phải kiểm tra từ trình duyệt xem wcf service có truy cập được không. Chính vì thế mà ở bài viết trên mình có bước set 2 project start cùng lúc để khi F5 là service đã sẵn sàng.

      Regards.

        • tungnt185 says

          Bạn nên download source code của mình về rồi so sánh với code của bạn xem có gì khác nhau không? Nói thế này rất khó để hình dung được lỗi bạn ạ.

          • tranhieunknd says

            mình download source code của bạn về nhưng cũng không chạy được :( nó lỗi giống như của mình
            System.ServiceModel.CommunicationException: The remote server returned an error: NotFound. —> System.Net.WebException: The remote server returned an error: NotFound. —> System.Net.WebException: The remote server returned an error: NotFound.
            at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
            at System.Net.Browser.ClientHttpWebRequest.c__DisplayClasse.b__d(Object sendState)
            at System.Net.Browser.AsyncHelper.c__DisplayClass1.b__0(Object sendState)
            — End of inner exception stack trace —
            at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
            at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
            at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
            — End of inner exception stack trace —
            at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
            at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
            at System.ServiceModel.ClientBase1.ChannelBase1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
            at Tungnt.NET.WP8._1Silverlight.WCFDemo.WCFRestDemoClient.WCFRestDemoClientChannel.EndPostMessage(IAsyncResult result)
            at Tungnt.NET.WP8._1Silverlight.WCFDemo.WCFRestDemoClient.Tungnt.NET.WP8._1Silverlight.WCFDemo.IWCFRestDemo.EndPostMessage(IAsyncResult result)
            at Tungnt.NET.WP8._1Silverlight.WCFDemo.WCFRestDemoClient.OnEndPostMessage(IAsyncResult result)
            at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)

          • tungnt185 says

            Bạn hãy thử kết nối đến service từ trình duyệt trên emulator của bạn đến wcf service xem có được không. Nếu không thì tức là có vấn đề kết nối giữa emulator của bạn và wcf service.

            Kiểm tra tắt firewall đi xem có được không vì source code của mình đã test thử chạy rất tốt không có vấn đề gì.

  6. nguyễn ngọc cường says

    anh ơi
    em download code anh về chạy vẫn bị cái lổi trên anh post, em kiểm tra trong web.config vẫn còn dòng này:

    ra cái lổi y chang trên hình anh post lun á

  7. nguyễn ngọc cường says

    Hi anh,

    Trong project Windows Phone 8.1 Store App, giờ không điền câu GetMessage lên Dialog nửa mà muốn gán vào cái ListBox ngoài view thì làm sao anh, ví dụ trên project WCF REST kết nối database lấy ra danh sách của 1 bảng và bên Windows Phone 8.1 Store App điền dữ liệu ra ngoài view theo dạng table được ko anh? hepl em với, thanks nhiều.

    • tungnt185 says

      Hi em,

      Các bước hoàn toàn giống như trên thôi. Chỉ khác là viết hàm ở server thì trả về Listrồi ở app lấy về gán hoặc binding vào ItemSource của ListBox.

      Regards

      • nguyễn ngọc cường says

        hi anh,

        anh viết cho em 1 đoạn mẫu được ko, project Tungnt.NET.WP8.1Silverlight dùng add service referrence thì em lấy danh sách trong Database ra ok còn project Tungnt.NET.WP8.1StoreApp thì em lấy và điền ra view ko được, anh hepl em với 😀

        • tungnt185 says

          Hi Cường em hãy tự viết theo hướng dẫn trong bài đó của anh vì rõ ràng là bài đó đã hướng dẫn rất chi tiết từng bước. Anh không thể viết thay em được vì kiến thức là phải tự mình trải nghiệm em ạ. Nếu vướng mắc ở đâu thì anh sẽ giải đáp giúp ở đó thôi. OK quan điểm như thế nhé.

          • nguyễn ngọc cường says

            cảm ơn anh, em có code theo bài viết của anh thì chạy ok ạ, có điều hàm GETMessage của anh trả về 1 chuổi em đọc về và gán ra view thì ok anh, còn em tự viết 1 hàm kết nối DB trả về 1 đối tượng json như vậy này anh: [{“MaNhomMH”:”DC”,”TenNhomMH”:”đồ chơi”,”VAT”:0,”id”:8}], em có code như vậy ngoài view :

            //ham này em bỏ ko show dialog mà show ra view như vậy có đúng ko anh, em run không báo lỗi mà cũng chẳng hiển thị được dữ liệu lên.

            private async void btnGetMessage_Click(object sender, RoutedEventArgs e)
            {
            string result = await WCFRESTServiceCall(“GET”, “getallnmh”);
            //var dialog = new MessageDialog(result);
            //await dialog.ShowAsync();
            nhommathang.DataContext = result;
            }

            cái này có cần phải khai báo 1 lớp .CS khai báo các hàm tạo GET, SET cho id,MaNhomMH,TenNhomMH,VAT, em có tham khảo 1 số bài thấy họ có khai báo GET,SET thì mới lấy ra dc, mong anh chỉ giúp, thanks anh nhiều.

          • tungnt185 says

            Hi em,

            Bài này anh demo chỉ trả về string nên hiển thị trên dialog luôn như thế. Còn nếu em trả về List object thì sau khi lấy được kết quả dạng string, em cần convert nó hay còn gọi là deserialize nó thành list object của .net. Em cần tạo cho nó và deserialize string thành list. Sau đó em gán cho itemsource của listview là được.

            Em tham khảo bài này của anh nhé: https://tungnt.net/download-va-upload-anh-su-dung-wcf-rest-service-tren-windows-phone-2/

            Regards.

  8. nguyen cuong says

    Hi anh em đã viết được app kết nối tới sql và đọc dữ liệu về theo hướng dẫn của anh(rất cảm ơn anh) web service đã up lên hositng và giờ đóng gói project store app để cài vào máy như thế nào anh? em có làm theo.. vào solution ==> store ==> create app packege xong em ấn create nó tạo ra file .appx rồi em bỏ vào máy lumia 430 cài đặt thì bị báo không thể cài đặt ứng dụng công ty… anh có thể hướng dẫn em đóng gói cài vào máy lumia 430 với(máy này xài wp 8.1 ý)…

    • tungnt185 says

      Hi Cường,

      Anh rất vui vì bài viết của anh giúp ích được cho em.
      Về việc cài ứng dụng windows phone 8.1 lên device anh chưa gặp trường hợp lỗi như em nói.
      Quy trình deploy là sau khi có file appx sẽ sử dụng Application Deployment Tool để deploy app lên device, chỉ có 1 lưu ý ở đây là device đó đã phải đăng kí là device test trong windows developer center.

      Regards.

    • tungnt185 says

      Lỗi này nó khi cho tiết rồi em. Do kiểu của phương thức implement interface và kiểu của phương thức khai báo trong interface đang không giống nhau. Em chỉ cần implement lại là được. Vui lòng đọc kĩ bài của anh có hướng dẫn phần đấy nhé.

Trackbacks

Leave a Reply

Your email address will not be published. Required fields are marked *