作者hoyunxian (WildDagger)
看板WindowsPhone
標題[教學] 簡單讓自己的APP能夠處理Big-5碼等資料
時間Sat May 10 01:01:34 2014
其實這篇教學某程度上是Azure推薦文(喂
這個方法是我在寫核能APP的時候找到的方法
如果流量不會一秒鐘數MB上下的話可以試看看。
當初是因為看了《HTML5完美風暴》這本書,知道原來有這方法後
才開始研究用Azure實現的可能性
簡單的說,就是Windows 8.1/Windows Phone 8.1內建的新型HttpClient
因為已經不支援直接讀取位元組資料,要使用string也很麻煩
更何況如果你的資料有多種來源,每個APP都要重寫一次處理邏輯的話果然很困擾
(以我的那個核能APP來說,最大的問題是原能會給的檔案全部是Big-5編碼CSV檔,
而CSV檔又不是規則的欄為屬性列為資料,所以也不能用網路慣用的CSV外掛,
因此最後還是只能自己寫處理程式)
所以最後想到的方法,就是將資料轉換邏輯全部放在網路伺服器上,
到時候只要去自己架好的網路伺服器把伺服器程式轉換好的JSON資料抓下來就能用
這個方法最大的好處是可以把多個不同來源的資料整合成一個資料,
因此資料的處理邏輯不僅Win8/Win8.1/WP8/WP8.1都可通用,
要寫成Android/iOS或甚至是Firefox OS(Web App)也可以直接用同一份資料
因此資料的處理可以更加明確化,甚至要另外做成Open API與JSONP都沒問題
要做到這個,需要的就是Azure的WebSites服務
雖然說Azure的WebSites服務是最基本網站,但就算是這麼基本的網站服務,
要在上面跑ASP.NET也是完全沒有問題
(更甚者這次教的部分完全不牽涉伺服器端檔案管理權限問題,
所以WebSites服務更可以勝任)
簡單的說Azure WebSites的服務,
就是給你一個基本大小為1GB,可以跑ASP.NET且基本流量上限為165MB的免費網頁空間
(以上是免費模式,所以我才說如果不是一秒鐘幾十MB上下的網站,
這就很夠了,而且這個模式下也不用一毛錢)
重點是你需要設定的部分很少,甚至需要的話也可以透過Visual Studio來處理部分設定
對於要架一個普通網站的人而言其實這就很夠了。
而且因為本身實際上算免費網頁空間,你大可直接網站丟上去,
這樣子也不會碰上惡名昭彰(?的跨網域問題
(而真的要跨網域存取資料就全部交給程式處理吧)
另外Azure WebSites還有個可以把其他免費網頁空間都打趴的特性
就是上面可以跑NuGet套件(只要支援的話都能跑)
其中包括解析JSON最常用的JSON.NET
(不過光是能跑ASP.NET這點其它免費網頁空間大概就已經躺平了吧......)
那麼介紹完後,就直接開始這次教學,
這次的教學會牽涉到的東西倒是跟Win8系沒什麼關係就是了......(被打)
如果你的Visual Studio是Professional或以上的話,那麼網站功能是內建的
如果你的Visual Studio僅是Express的話,請先去載Express for Web版
(另外順便一提,WP8.1推出之後如果沒打算出WP7的APP的話,
其實你也可以直接把Express for Windows Phone給移除掉,
因為Express for Windows在更新到Update 2後就可以寫WP8.1的APP,
在未來所有WP8手機都能升級WP8.1的保證下,
硬碟空間若是不夠把Express for Windows Phone給砍掉可以幫硬碟省點空間)
載完之後,開啟Express for Web,接著選擇
檔案→新網站
(注意不是新專案,
但因為建網站的同時也會在文件/Visual Studio XXXX/Project底下建立同名專案,
所以如果在Project資料夾下有同名的專案資料夾也請注意專案名字會變動)
再來就是開始用網站來建立處理邏輯了
這邊的教學基本上是使用在中文版中稱為「泛型處理常式(附檔名.ashx)」的檔案
這個檔案執行起來不會有介面,但是相較於MVC等大型框架而言是一種很簡單的網路程式
不必去學太多MVC或其他林林總總資料也能簡單學起來
ashx檔的新增方法就跟開個新網頁/新APP頁面一樣很簡單,在此不贅述
當你建起來後,內容應該是這個樣子:
-------------------------------------------------------------------
<%@ WebHandler Language="C#" Class="ClassOne" %>
using System;
using System.Web;
public class ClassOne : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
}
public bool IsReusable {
get {
return false;
}
}
}
-------------------------------------------------------------------
基本上不會有了,就這麼簡單
你會發現這檔案甚至沒有namespace這概念
而這個程式簡單說就是執行的時候去跑ProcessRequest這個方法
跑完了就結束,不會回傳任何資訊
所以其他的不用管,只要把你的處理邏輯都寫進ProcessRequest方法就OK
當然就算是這樣也是支援把函式給寫在別的方法的類型
我們要讀取傳進來的資料並傳出去結果的話,就要善用context物件
context物件是一個HttpContext物件,去翻MSDN的話會發現東西很多
不過跟我們的教學有關的是Request與Response物件
有接觸網路就會知道Request是收到的資料,Response是回應的資料
這邊說明幾個常用的方法/屬性
Request["參數名"]:可以獲取參數名稱的資訊,
如果要做JSONP的話可以用Request["callback"]來取得回傳函式
Request.InputStream:二進位圖檔等等會比較常用。
Response.Write:把文字寫進回應資訊中,
JSONP的話是寫進[函式名稱]([JSON資料])當回傳方式
Response.BinaryWrite:把位元組寫進回應中,這跟圖檔比較有關係
Response.ContentType:指定回傳資訊的MIME類型,
普通JSON、XML或文字檔可只使用text/plain(預設的普通文字)
但如果要做JSONP記得設定成text/javascript。
知道這些後,就可以開始在ProcessRequest函式裡面撰寫處理程式
在ashx裡面可以使用的網路連接物件是System.Net.WebClient
WebClient裡面就有個名為DownloadData()的方法,這個方法會傳回位元組陣列
如果確定資料的內容是Big-5的話,就可以用System.Text的Encoding物件,
以Encoding.GetEncoding(950).GetString([位元組陣列])的方法
將Big-5編碼的文字轉成UTF-8的字串
如果沒有什麼特別大的問題的話,自然也可以直接就這樣寫進回應資訊中
當然如果下載的不是文字而是圖檔的話,則要搭配System.IO.MemoryStream,
將資料作處理後用BinaryWrite寫入回傳資料中。
如果是多個JSON檔需要做整合的話,
請善用List物件、class宣告新類別,JSON.NET進行解析並組裝完畢後轉成JSON物件字串
這樣絕大多數多重API來源的問題都可以先在網頁伺服器上解決。
此外因為預設不會引用System.Linq命名空間
所以如果你需要用LINQ來進行查詢的話也別忘了引用
另外如果有宣告複雜的變數,在ProcessRequest方法結束前記得設成null
免得到時候變數清不完會發生異常狀況。
做好之後,記得要發行,發行的時候可以選擇發佈到Azure上
等待部署完成後你的ashx就可以用了。
回到Win8/WP8,使用ashx的方式,
就是直接用Windows.Web.Http或者是System.Net.Http去讀取ashx(有參數的話記得加參數)
正常情況下ashx應該會給你一串文字或者是圖片之類的
接著就跟普通的JSON/圖片沒甚麼兩樣,但因為整理資料的部分都是伺服器幫你處理
相對而言本機端所需的處理就少很多,多多少少也可以分擔一下系統資源的問題。
--
推 galilei503:原PO國文老師經長請假#1Duc8INo (StupidClown) 05/30 02:16
→ leo8064047:樓上的國文老師也...05/30 02:58
推 galilei503: 常...我不該採在地板上,我對不起地球..05/30 03:00
推 leo8064047: 踩05/30 03:15
推 galilei503:樓上你...想害我被做成簽名檔= =(沒有錯字了我撿查過!)05/30 04:56
推 leo8064047: 檢05/30 09:39
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.250.111.244
※ 文章網址: http://www.ptt.cc/bbs/WindowsPhone/M.1399654898.A.FCE.html
※ 編輯: hoyunxian (111.250.111.244), 05/10/2014 01:03:02
推 TsaoCCFGOGO:先推 05/10 01:06
推 Kelunyang:其實有簡單的方法,一個是 Encoding4silverlight 05/10 02:03
→ Kelunyang:但是在 Universal App沒辦法用,我最近嘗試使用nuget 05/10 02:04
→ Kelunyang:裡的 Portable.Text.Encoding 這個,可以到Github裡 05/10 02:04
→ Kelunyang:抓他的原始檔重編,Universal App都可以用 05/10 02:04
嗯,不過我會推薦用Azure除了有辦法可以處理外
另外一個原因是這樣跨平台比較方便(笑)
而且到時若引用的Open Data改了呈現內容的話
(比方說那個一直在改的台北捷運票價......我今天才又發現北捷把系統改掉了......)
就可以只改網頁端的程式而不用動到APP端的程式
(不然每改版一次就要重新發行一次,未免有點太麻煩了)
※ 編輯: hoyunxian (111.250.111.244), 05/10/2014 02:08:58
推 felaray:今天才丟了一隻泛型上去,你去azure還可以玩排程器 05/10 02:08
推 felaray:寫好功能以後用排程器去呼叫 可以做些定時的功能 05/10 02:08
→ felaray:ashx有趣的地方是一隻檔案只要改變ContentType就可以傳回 05/10 02:10
→ felaray:不同格式的資料XD 05/10 02:10
有時我真的會想為什麼會有跨網域問題
然後前陣子看Firefox OS的推廣影片時,
才發現Firefox OS上好像已經沒那個惡名昭彰(?的跨網域問題了
※ 編輯: hoyunxian (111.250.111.244), 05/10/2014 02:13:07
→ Kelunyang:喔喔這樣,我考慮的是如果都透過我自己寫Webservice 05/10 07:25
→ Kelunyang:哪天要是我的Service沒錢續約了,App就掛了XD 05/10 07:25
→ Kelunyang:所以才會盡量留給本機處理XD 05/10 07:25
→ felaray:Azure可以免費創10個 website 05/10 09:49
推 hungys:我愛看中職的資料&API也都是在Azure處理的,只是我是用Pyth 05/10 10:23
→ hungys:on寫xD 05/10 10:23
推 hdtp:推有心教學文! 05/10 18:34
推 defenders:看不懂,推 05/11 21:47