Bài 52: Tạo định dạng JSON trong C# asp.net service vs Android


Tiếp tục bài 51, Trong bài này Tui sẽ hướng dẫn cách tạo định dạng JSON trong C# asp.net service, sau đó dùng KSOAP API để kết nối để sử dụng trong Android.

– Cái hay của bài này là Tui viết code cho phép mọi đối tượng có thể tự parser ra định dạng JSON thông qua kỹ thuật viết Extendsion Method.

– Tui sẽ cấu hình IIS local để chạy, bạn có thể demo lên somee.com để test.

– Ở đây Tui giả lập dữ liệu để cho các bạn dễ tiếp cận, Tui có mô hình lớp như sau:

android_51_18Tui sẽ viết coding cho tất cả các đối tượng đều tự có khả năng tạo ra JSON để tăng tốc độ coding cũng như giảm thiểu code.

Bạn new 1 empty asp.net project tên WebApplication_JSON:

android_52_1Lớp Sanpham:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication_JSON
{
public class SanPham
{
public string MaSP { get; set; }
public string TenSP { get; set; }
public int SoLuong { get; set; }
public double DonGia { get; set; }
public double ThanhTien { get; set; }
public string Hinh { get; set; }
}
}

Lớp DanhMuc:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication_JSON
{
public class DanhMuc
{
public DanhMuc()
{
Sanphams = new List<SanPham>();
}
public List<SanPham> Sanphams { get; set; }
public string MaDM { get; set; }
public string TenDM { get; set; }

}
}

– Bạn cần tạo thêm 1 static class ExtensionMethod (chú ý là đặt tên gì cũng được), mục đích của lớp này là ta cung cấp các phương thức giúp các đối tượng có thể tự gán kết thêm các phương thức:

– Quy tắc như sau:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;

namespace WebApplication_JSON
{
public static class ExtensionMethod
{
public static string ParserJSon(this object data)
{
JavaScriptSerializer sc = new JavaScriptSerializer();
string strJson=sc.Serialize(data);
return strJson;
}
}
}

– lớp bắt buộc là static

– hàm bắt buộc là static

– đối số đầu tiên của hàm là this

==> những kiểu dữ liệu nào đằng sau từ khóa this sẽ tự động có hàm ParserJSon.

Hàm ParserJSon cho phép biến mọi đối tượng thành định dạng JSON, JavaScriptSerializer  có phương thức Serialize giúp ta làm được điều này.

– Tiếp tục tạo .net webservice, Tui giả lập dữ liệu để cho lẹ:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace WebApplication_JSON
{
/// <summary>
/// Summary description for WebService1
/// </summary>
[WebService(Namespace = "http://tranduythanh.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// 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 WebService1 : System.Web.Services.WebService
{

[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
[WebMethod]
public string get1SanPhamMau()
{
SanPham sp = new SanPham();
sp.MaSP = "sp_1xxx";
sp.TenSP = "DELL Inspiron 14NR";
sp.SoLuong = 100;
sp.DonGia = 150000;
sp.Hinh = "https://duythanhcse.wordpress.com/h1.png";
return sp.ParserJSon();
}
[WebMethod]
public string get1DanhMuc()
{
DanhMuc dm = new DanhMuc();
dm.MaDM = "DM1";
dm.TenDM = "Hàng máy tính";
SanPham sp1 = new SanPham();
sp1.MaSP = "sp_1xxx";
sp1.TenSP = "DELL Inspiron 14NR";
sp1.SoLuong = 100;
sp1.DonGia = 150000;
sp1.Hinh = "https://duythanhcse.wordpress.com/h1.png";
dm.Sanphams.Add(sp1);

SanPham sp2 = new SanPham();
sp2.MaSP = "sp_2yyyy";
sp2.TenSP = "HP Inspiron 113";
sp2.SoLuong = 130;
sp2.DonGia = 140000;
sp2.Hinh = "https://duythanhcse.wordpress.com/h2.png";
dm.Sanphams.Add(sp2);

return dm.ParserJSon();
}
[WebMethod]
public string getListDanhMuc()
{
List<DanhMuc> dsDM = new List<DanhMuc>();
DanhMuc dm1 = new DanhMuc();
dm1.MaDM = "DM1";
dm1.TenDM = "Hàng máy tính";
SanPham sp1 = new SanPham();
sp1.MaSP = "sp_1xxx";
sp1.TenSP = "DELL Inspiron 14NR";
sp1.SoLuong = 100;
sp1.DonGia = 150000;
sp1.Hinh = "https://duythanhcse.wordpress.com/h1.png";
dm1.Sanphams.Add(sp1);

SanPham sp2 = new SanPham();
sp2.MaSP = "sp_2yyyy";
sp2.TenSP = "HP Inspiron 113";
sp2.SoLuong = 130;
sp2.DonGia = 140000;
sp2.Hinh = "https://duythanhcse.wordpress.com/h2.png";
dm1.Sanphams.Add(sp2);
dsDM.Add(dm1);

DanhMuc dm2 = new DanhMuc();
dm2.MaDM = "DM2";
dm2.TenDM = "Hàng Điện tử";
SanPham sp3 = new SanPham();
sp3.MaSP = "sp_3jjjj";
sp3.TenSP = "Bóng đèn Lượng Tử";
sp3.SoLuong = 95;
sp3.DonGia = 13000;
sp3.Hinh = "https://duythanhcse.wordpress.com/h3.png";
dm2.Sanphams.Add(sp3);

SanPham sp4 = new SanPham();
sp4.MaSP = "sp_4aaa";
sp4.TenSP = "HP Inspiron 113";
sp4.SoLuong = 120;
sp4.DonGia = 12000;
sp4.Hinh = "https://duythanhcse.wordpress.com/h4.png";
dm2.Sanphams.Add(sp4);
dsDM.Add(dm2);

return dsDM.ParserJSon();
}
}
}

– Tiến hành cấu hình IIS, chạy lên ta được (nếu không rõ các bạn cần xem lại các bài trước Tui trình bày rất kỹ về .net webservice):

android_52_2– Test thử get1SanPhamMau:

android_52_3– Test thử get1DanhMuc:

android_52_4– Test thử getListDanhMuc:

android_52_5

– Source code: Tải source code ở đây nầy

– Tiếp theo ta cần dùng KSOAP API kết nối tới asp.net webservice để đọc ra chuỗi JSON ở trên, sau đó parser ra JSONObject để sử dụng (hoặc bạn làm cách nào cũng được, miễn là Android thấy được chuỗi kết quả với định dạng JSon như trên):

– Tui sẽ trình bày cách đọc dữ liệu trong getListDanhMuc vì nó phức tạp nhất, các dịch vụ khác các bạn tự nghiên cứu.

Bạn quan sát dữ liệu trả về trong hàm getListDanhMuc được để trong cặp ngoặc vuông –> Đó chính là mảng đối tượng JSONArray, ứng với mỗi phần tử trong JSONArray là JSONObject (Là từng danh mục) bạn quan sát nó có Sanphams[…] nó lại chứa tập các phần tử là sản phẩm…

Bạn tạo Project như sau:

android_52_6Kết quả khi chạy ứng dụng:

android_52_7Màn hình chính là 1 ListView hiển thị theo dạng custom layout, mỗi dòng sẽ có Danh mục màu đỏ và Spinner chứa sản phẩm tương ứng với Danh mục đó.

Nhớ cấp quyền Internet.

– Giao diện chính (activity_main):


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="tranduythanh.com.learnjsonnetservice.MainActivity" >

<ListView
android:id="@+id/lvDanhMuc"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>

</LinearLayout>

– Customlayout  (custom_list_product.xml):


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/txtDanhMuc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Danh mục ở đây" />

<Spinner
android:id="@+id/spinner_sanpham"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout>

– Xử lý coding :


package tranduythanh.com.learnjsonnetservice;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

public class MyAdapter extends ArrayAdapter<JSONObject>
{
private Activity context;
private int resource;
private List<JSONObject>objects;
public MyAdapter(Activity context, int resource,
List<JSONObject> objects) {
super(context, resource, objects);
this.context=context;
this.resource=resource;
this.objects=objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater= this.context.getLayoutInflater();
View custom_row= inflater.inflate(this.resource, null);
TextView txtDM=(TextView) custom_row.findViewById(R.id.txtDanhMuc);
Spinner spinner_sp=(Spinner) custom_row.findViewById(R.id.spinner_sanpham);
//Đối tượng này là DanhMujc
JSONObject jsonObj=this.objects.get(position);
try {
//Lấy thuộc tính của Danh mục
String dm=jsonObj.getString("MaDM")+" - "+jsonObj.getString("TenDM");
txtDM.setText(dm);
txtDM.setTextColor(Color.RED);
//Lấy Danh sách sản phẩm:
JSONArray arrJson=jsonObj.getJSONArray("Sanphams");
ArrayList<String>arrSanpham=new ArrayList<>();
for(int i=0;i<arrJson.length();i++)
{
//lấy từng sản phẩm theo danh mục:
JSONObject jsonSanpham=arrJson.getJSONObject(i);
String sp=jsonSanpham.getString("TenSP");
arrSanpham.add(sp);
}
ArrayAdapter<String>adapter=new ArrayAdapter<>
(this.context, android.R.layout.simple_spinner_item,
arrSanpham);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_sp.setAdapter(adapter);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return custom_row;
}

}

– Coding MainActivity:


package tranduythanh.com.learnjsonnetservice;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {
public final static String URL="http://192.168.0.147/testjson/WebService1.asmx?WSDL";
public final static String NAMESPACE="http://tranduythanh.com/";
ListView lvDanhMuc;
ArrayList<JSONObject>arrData;
MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addControlAndEvents();
}
private void addControlAndEvents() {
lvDanhMuc=(ListView) findViewById(R.id.lvDanhMuc);
arrData=new ArrayList<>();
adapter=new MyAdapter(this,
R.layout.custom_list_product, arrData);
lvDanhMuc.setAdapter(adapter);

JSonAsyncTask task=new JSonAsyncTask();
task.execute();
}

public class JSonAsyncTask extends AsyncTask<Void, Void, ArrayList<JSONObject> >
{
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected ArrayList<JSONObject> doInBackground(Void... params) {
ArrayList<JSONObject> listJSon=new ArrayList<>();
final String METHOD="getListDanhMuc";
final String SOAPACTION=NAMESPACE+METHOD;
SoapSerializationEnvelope envelope=new
SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
SoapObject request=new SoapObject(NAMESPACE, METHOD);
envelope.setOutputSoapObject(request);
HttpTransportSE transport=new HttpTransportSE(URL);
try {
transport.call(SOAPACTION, envelope);
SoapPrimitive data= (SoapPrimitive)
envelope.getResponse();
//Chuỗi định dạng ban đầu
String jsonText=data.toString();
//Chuỗi định dạng này có kiểu JSONArray:
//nó trả về tập Danh mục
JSONArray arr=new JSONArray(jsonText);
for(int i=0;i<arr.length();i++)
{
//Lấy 1 Đối tượng danh mục ra (JSONObject):
JSONObject jsonObj=arr.getJSONObject(i);
listJSon.add(jsonObj);
}

} catch(Exception e) {
Toast.makeText(getApplicationContext(), e.toString(),
Toast.LENGTH_LONG).show();
}
return listJSon;
}
@Override
protected void onPostExecute(ArrayList<JSONObject> result) {
super.onPostExecute(result);
arrData.clear();
arrData.addAll(result);
adapter.notifyDataSetChanged();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

– Các bạn có gắng đọc hiểu coding ở trên (thực ra nó tương tự như bài 50, không có gì khó).

– Bạn nghĩ cách để tương tác nhanh gọn hơn thay vì thông qua nhiều bước như vậy, nhưng chú ý luôn phải dùng đa tiến trình.

Các bạn có thể tải Source code mẫu ở đây

Chúc các bạn thành công!

12 responses

  1. Thầy cho em hỏi cách xử lý upload 01 file hoặc mình tấm hình từ client lên Server với ạ.

  2. […] Bài 52: Tạo định dạng JSON trong C# asp.net service vs Android […]

  3. thầy ơi xin thầy hướng dẫn em cách cấu hình để kết nối genymotion với web service chạy trên localhost với ạ

    1. Hi em, cách chạy tương tự không khác gì. Nhưng chạy localhost em cần dùng IP là: 10.0.2.2 (chi tiết http://developer.android.com/tools/devices/emulator.html#emulatornetworking)

  4. thầy cho em hỏi Ksoap này có thể thêm xóa sữa trên SQL server được ko ạ?

    1. được em. em chỉ cần viết insert rồi gọi qua KSOAP là thực thi được

  5. Reblogged this on Cuong Le KMS and commented:
    Tạo định dạng JSON trong C# asp.net service vs Android

  6. Nguyễn Đức Anh | Reply

    Thầy cho em hỏi trang web của em bị mất hết file và nó báo lỗi Site:
    The server on which your website is hosted is temporarily down!
    em cảm ơn thầy ak

    1. em có thể chuyển coding qua sub domain mới (do somee đóng)

      1. Nguyễn Đức Anh

        em làm được rồi , em cảm ơn thầy nhiều ak 🙂

  7. Thầy cho em hỏi em làm theo hướng dẫn của thầy để parse JSON. Nhưng em gặp lỗi
    org.xmlpull.v1.XmlPullParserException: Unexpected <! (position:START_DOCUMENT null@1:1 in java.io.InputStreamReader@21c95da8) trong android. Thầy cho em hỏi là giờ em phải sửa sao ạ. Chi tiết lỗi ở http://stackoverflow.com/questions/33667260/anroid-error-org-xmlpull-v1-xmlpullparserexception-unexpected. Em cảm ơn thầy nhiều.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: