第一種方案,最麻煩,而且容易出錯(可能跟我個人不喜歡拼接字串有關係);
第二種方案,有一定的通用性,但是不利於資料驗證;
第三種方案,通用,可以進行有效資料驗證,應對一般的需求夠用了,但是處理更複雜的對象不行;
第四種方案,幾乎可以處理我們遇到的所有情況
另外,這是在asp教程.net mvc2中的使用,到了asp.net教程 mvc3,微軟已經把jsonvalueproviderfactory作為內建的功能了
先來看看該功能的截圖:
一般情況下這些資訊會對應一個實體類,就命名為:receiverinfo,簡單起見,我定義receiverinfo如下:
1、將需要的值拼接成json文本,再action裡面處理
首先您需要將要儲存的值拼接成一個json文本,類似:
var test = "{ receiverid: 5, receivername: 'will', sex: 'f', createdate: '2011-02-21' }";
然後用jquery儲存到資料庫教程,代碼如下:
$.ajax({
url: "/home/test1",
type: "post",
cache: false,
data: test
});
然後您在action裡面這樣操作:
streamreader reader = new streamreader(request.inputstream);
string bodytext = reader.readtoend();
網頁特效serializer js = new javascriptserializer();
receiverinfo receiver = js.deserialize<receiverinfo>(bodytext);
//儲存。。。
2、利用自訂的modelbinder實現
jsonbinder
1
public class jsonbinder<t> : imodelbinder
2 {
3 public object bindmodel(controllercontext controllercontext, modelbindingcontext bindingcontext)
4 {
5 streamreader reader = new streamreader(controllercontext.httpcontext.request.inputstream);
6 string json = reader.readtoend();
7
8 if (string.isnullorempty(json))
9 return json;
10
11 javascriptserializer serializer = new javascriptserializer();
12 object jsondata = serializer.deserializeobject(json);
13 return serializer.deserialize<t>(json);
14 }
15 }
我們繼承imodelbinder介面,實現其 方法:
public object bindmodel(controllercontext controllercontext, modelbindingcontext bindingcontext)
即可。我們可以在action裡面這樣使用:
public actionresult test1([modelbinder(typeof(jsonbinder<receiverinfo>))] receiverinfo receiverinfo)
這樣我們自訂的 imodelbinder就會取代defaultmodelbinder完成資料繫結。
3、直接傳遞一個json對象
上面兩種方法並沒有利用mvc的system.componentmodel.dataannotations進行有效資料驗證。您可能需要自己手動驗證,無疑增加了工作量。
我們試試這種方式。
前端的寫法:
var b = {
receiverid: 5,
receivername: "will",
sex: "f",
createdate: "2011-02-21"
};
$.ajax({
url: "/home/test1",
type: "post",
cache: false,
data: b,
success: function(data) { alert(data.message); },
error: function(xhr, a, b) { alert(xhr.responsetext); }
});
action的寫法:
public actionresult test1(receiverinfo receiverinfo)
我們能正常的得到綁定後的資料。而且我們還能利用system.componentmodel.dataannotations進行資料驗證。我們為receiverinfo做如下改動:
[system.componentmodel.dataannotations.required(errormessage = "收貨人必須填寫")]
public string receivername { get; set; }
並在前端為receivername賦值為空白字串,再次執行,得到提示:
很好,不過我們有新的要求了,那就是傳遞更複雜的對象,比如對象套嵌對象,對象有集合屬性,這種方式不能勝任了。
4、利用mvcfutures的jsonvalueproviderfactory
每一版的mvc都有一個mvcfutures,裡面會有一些額外的功能,這些功能有些會加入下一個版本中,而這些功能在某些時候很有用處。我查看了裡面的類,發現有一個類jsonvalueproviderfactory正是處理複雜物件的提交和資料驗證。由於json對象需要特定解析才能使用預設的defaultmodelbinder,而這個解析過程需要在valueprovider階段完成,所以需要實現特定的valueprovider給defaultmodelbinder。我們需要實現一個valueproviderfactory和ivalueprovider,而mvc裡面的dictionaryvalueprovider<tvalue>(繼承了ivalueprovider)已經足夠使用了,所以只需要繼承valueproviderfactory實現其方法:public override ivalueprovider getvalueprovider(controllercontext controllercontext)即可,具體代碼您可以看jsonvalueproviderfactory。
我們定義另一個類:
receiverinfochild
public class receiverinfochild
{
[system.componentmodel.dataannotations.required(errormessage = "childid必須填寫")]
public string childid { get; set; }
}
並為類receiverinfo增加一個屬性public list<receiverinfochild> receiverinfochild { get; set; }
我們把jsonvalueproviderfactory拿出來放在項目裡面,然後在global.asax裡面註冊一下,就可以使用了。
protected void application_start()
{
arearegistration.registerallareas();
registerroutes(routetable.routes);
valueproviderfactories.factories.add(new jsonvalueproviderfactory());
}
因為jsonvalueproviderfactory中有:if (!controllercontext.httpcontext.request.contenttype.startswith("application/json", stringcomparison.ordinalignorecase))來判斷進來的請求是不是json對象,所以我們提交資料的時候需要這樣寫:
var receiverinfo = [
{
receiverinfochild: [{ childid: "1" }, { childid: "11"}],
receiverid: 5,
receivername: "will",
sex: "f",
createdate: "2011-02-21"
},
{
receiverinfochild: [{ childid: "2" }, { childid: "22"}],
receiverid: 5,
receivername: "will",
sex: "f",
createdate: "2011-02-21"
}
];
$.ajax({
url: "/home/test1",
type: "post",
cache: false,
contenttype: "application/json;charset=utf-8",
data: json.stringify(receiverinfo),
success: function(data) { alert(data.message); },
error: function(xhr, a, b) { alert(xhr.responsetext); }
});
其中json.stringify(receiverinfo)是將json對象轉換成字串,您可以到ps教程://github.com/douglascrockford/json-js">這裡下載該類庫。
在action裡面,我們這樣寫就可以了:
public actionresult test1(list<receiverinfo> receiverinfo)
看一下調試的結果:
完全正常綁定了值。我們再看看資料驗證: