前言
前陣子同事問我一個問題,要怎麼在server端post資料給遠端的.ashx。突然間我還真不知道怎麼做,因為通常都是在client端用ajax呼叫.ashx,如果是網站外的服務,通常都是Web service或WCF,.ashx還真沒碰到過。
所以survey了一下,寫了個小小Sample Code,當個memo。
需求
在server端post資料到.ashx,.ashx處理完後,接收.ashx的response。
範例
.aspx.cs
前陣子同事問我一個問題,要怎麼在server端post資料給遠端的.ashx。突然間我還真不知道怎麼做,因為通常都是在client端用ajax呼叫.ashx,如果是網站外的服務,通常都是Web service或WCF,.ashx還真沒碰到過。
所以survey了一下,寫了個小小Sample Code,當個memo。
需求
在server端post資料到.ashx,.ashx處理完後,接收.ashx的response。
範例
.aspx.cs
protected void Button1_Click(object sender, EventArgs e)
{
var url = "http://localhost:13488/serverPostAshx/MyHandler.ashx";
string uri = string.Format("{0}?who={1}", url, "joey");
WebRequest request = WebRequest.Create(uri);
request.Method = "POST";
//加上"data=",讓server端可以透過Request.Form["data"]讀取
string postData = "data={a:1, b:2, c:[3,4]}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
using (Stream dataStream = request.GetRequestStream())
{
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
}
// Get the response.
using (WebResponse response = request.GetResponse())
{
using (Stream dataStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(dataStream))
{
string responseFromServer = reader.ReadToEnd();
this.Button1.Text = responseFromServer;
}
}
}
}
.ashx
public class MyHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
//Get QueryString
var whom = context.Request.QueryString["who"];
//取得整個Request傳過來的InputStream資料
//var result = GetFromInputStream(context);
//取得整個form資料
//var result = HttpUtility.UrlDecode(context.Request.Form.ToString());
var result = HttpUtility.UrlDecode(context.Request.Form["data"]);
context.Response.Write(string.Format("{0} {1}", whom, result));
}
private static string GetFromInputStream(HttpContext context)
{
var reader = new System.IO.StreamReader(context.Request.InputStream);
var result = reader.ReadToEnd();
return result;
}
public bool IsReusable
{
get
{
return false;
}
}
}
說明
- 使用WebRequest,Method屬性使用Post。
- 將要post的資料,assign到WebRequest的InputStream這個屬性。
- 在.ashx中,就可以透過context.Request.InputStream來取得Request post過來的資料。
- 透過Encoding.UTF8.GetString就可以將InputStream還原成原本的字串。(可能是序列化後的字串)
- 若有經過序列化(xml or json)可以將字串反序列化後,操作物件。
- .aspx透過Request的GetResponse(),可以取得.ashx的回應。
結果畫面
結論
因為太少碰到這樣的需求了,所以memo一下,順便練習一下WebRequest的用法。如果大家有更好的建議作法,麻煩請不吝告知,謝謝。
參考
Source Code : serverPostAshx.zip
勘誤1:感謝同事的提醒,送Request的方式一樣,只需要在post的data加上Form的Key。接著在server端就能透過Request.Form取得data的資料,經過UrlDecode後就是原本的資料。程式碼已經同步修改了,感謝提醒。
勘誤2:感謝黑大提醒,將原本讀取InputStream的部分,改為直接用StreamReader的ReadToEnd(),更為簡潔。程式碼已經同步修改了,感謝提醒。
JAVA部分
private static final String USER_AGENT = "Mozilla/5.0"; private static final String GET_URL = "http://網址/tt.ashx"; private static final String POST_URL = "http://網址/tt.ashx"; private static final String POST_PARAMScc = "?gg=ww";private static final String POST_PARAMS ="data="+"資料"
//傳送資料private boolean sendPOST() { String urlData = null; URL url = null; HttpURLConnection httpUrlConnection = null; try { url = new URL(POST_URL+POST_PARAMScc); URLConnection rulConnection = url.openConnection(); httpUrlConnection = (HttpURLConnection) rulConnection; httpUrlConnection.setDoOutput(true); httpUrlConnection.setDoInput(true); httpUrlConnection.setUseCaches(false); //httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object"); httpUrlConnection.setRequestProperty("Content-type", "application/x-www-form-urlencoded"); //httpUrlConnection.setRequestMethod("GET"); httpUrlConnection.setRequestMethod("POST"); // For POST only - START OutputStream os = httpUrlConnection.getOutputStream(); os.write(POST_PARAMS.getBytes()); os.flush(); os.close(); // For POST only - END int responseCode=httpUrlConnection.getResponseCode(); String decodedString; if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader in = new BufferedReader(new InputStreamReader( httpUrlConnection.getInputStream())); while ((decodedString = in.readLine()) != null) { urlData += decodedString; } in.close(); } httpUrlConnection.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } if(httpUrlConnection != null) { httpUrlConnection.disconnect(); } //return false; }
記得加上
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
沒有留言:
張貼留言