事實證明Ajax的世界更需要ASP.NET MVC

來源:互聯網
上載者:User

真正走進ASP.NET MVC的世界,才知道它的精彩。

“拋棄WebService,在.NET4中用 jQuery 調用 WCF”——原來拋棄WebService之後,還可以用jQuery調用ASP.NET MVC的Controller。

“Ajax為主的應用不需要ASP.NET MVC”,原來Ajax的世界更需要ASP.NET MVC。

曾經天真的想法,在實踐中證明了它的天真,但在從天真到事實的過程中,得到的是成長。

下面就談談我是如何認識到這個的。相比於結論,其中的過程更重要。

還是以之前文章中的部落格園站內短訊息功能(顯示目前使用者短訊息列表)為例,開始用的是jQuery外掛程式Templates進行列表資料繫結,後來遇到了兩個問題:

1) 在綁定時需要根據條件判斷產生不同的元素,比如使用者發過來的短訊息,寄件者顯示為連結,如果是系統通知,則顯示為文本。Templates對這樣的操作處理起來不是很方便;

2) 綁定後的資料無法在服務端重用。有時從搜尋引擎友好或者使用者體驗的角度,在頁面第一次載入時,不用ajax,在頁面載入後點擊重新整理或分頁連結時,才使用ajax。這樣就要在服務端與用戶端分別維護資料繫結操作。

也就是說原來服務端返回的是實體類對象列表,現在要返回的是將資料與Html組裝起來的字串。

1. 開始我們考慮的是一種醜陋的方法,用StringBuilder進行字串拼接產生資料繫結結果,伺服器端WCF服務中的代碼如下:

顯然這種方法易出錯,維護性差。

2. 接著我們考慮了第二種方法(參考自Render User Control as String Template),通過Web User Control產生字串。WCF服務中的代碼如下:

Page page = new Page();
Control control = page.LoadControl("~/Controls/MsgListControl.ascx");
((IRenderable<List<SiteMsg>>)control).PopulateData(siteMsgList);
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
using (HtmlTextWriter htw = new HtmlTextWriter(sw))
{
control.RenderControl(htw);
return sb.ToString();
}
}

由於MsgListControl.ascx的類型是動態編譯產生的,所以無法通過強制類型轉換將control轉換為MsgListControl類型,然後傳遞資料給它。

這裡需要通過一個另外的IRenderable<T>介面來實現資料的綁定,MsgListControl實現了這個介面,代碼如下:

public partial class MsgListControl : UserControl, IRenderable<List<SiteMsg>>
{
public void PopulateData(List<SiteMsg> siteMsgList)
{
rptMsgList.DataSource = siteMsgList;
rptMsgList.DataBind();
}
}

public interface IRenderable<T>
{
void PopulateData(T data);
}

在WCF服務中通過調用介面中的PopulateData方法進行資料的綁定。

這個方法增加了額外的介面,顯得有些複雜。

3. 後來我們想到了ASP.NET MVC,雖然不熟悉,但要嘗試一下,看能否更好地解決這個問題。

於是,上ASP.NET MVC 3,用Razor,咱們也MVC一把。

應用情境:在現有的VS2010 Web Site項目中應用ASP.NET MVC 3。MsgController收到請求後,由Inbox(一個Action)將包含短訊息列表的整個整頁模式返回給用戶端;當使用者點擊頁面的重新整理或者分頁連結時,通過Ajax發起POST請求以擷取短訊息列表,MsgController收到請求後,由List(一個Action)將短訊息列表的視圖返回給用戶端。

期望的效果:短訊息列表視圖能重用,Inbox與List使用的是同一個視圖。

一開始遇到了兩個小問題:

a) MapRoute配置之後,訪問出現" HTTP Error 404.0 - Not Found"錯誤。原因是訪問的網址沒有檔案名稱,未走ASP.NET管線。解決方案是在web.config的system.webServer中加上以下的配置:

<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" /> 

b) 繼續訪問,出現“The resource cannot be found.”錯誤。解決方案:由於用的是Web Site項目,要將Controllers檔案夾移至App_Code。

然後進入MVC相關代碼編寫,先從Ajax調用部分開始。

Controller的代碼如下:

public class MsgController : Controller
{
[HttpPost]
public ActionResult List(SiteMsgQuery msgQuery)
{
List<SiteMsg> siteMsgList = GetInboxMsgList(msgQuery);
return View("MsgList", siteMsgList);
}
}

需要注意的就一個地方:[HttpPost],既然是Ajax調用,當然要響應POST請求。

View的代碼(MsgList.cshtml)如下:

@using CNBlogs.UcHome.ExternalService.MsgWcfService
@model List<SiteMsg>
@foreach(SiteMsg msg in Model){
<div class="msg_item">
<div class="msg_sender">@msg.SenderName</div>
<div class="msg_title"><a href='/msg/item/@msg.id/'>@msg.Subject</a></div>
<div class="msg_sendtime">@msg.SendTime.ToString("yyyy-MM-dd HH:mm")</div>
</div>
}

比在.ascx中寫起來方便多了。

用戶端js調用代碼如下:

function GetMsgList(pageIndex, pageSize) {
var msgQuery = {}
msgQuery.PageIndex = pageIndex;
msgQuery.PageSize = pageSize;
$.ajaxSettings.dataType = 'plain/text';//不要用json
$.ajaxSettings.url = '/msg/list';
$.ajaxSettings.data = '{"msgQuery":' + JSON.stringify(msgQuery) + '}';
$.ajaxSettings.success = function (data) {
$("#msg_list").html(data);
};
$.ajax();
}

需要注意的是兩個地方(因為伺服器端Controller返回的不是json格式的資料):

a) dataType不要用json,用jQuery預設的就行,如果指定的話,就用plain/text;

b) 返回資料就在data中,不要通過data.d擷取。

這樣,用ASP.NET MVC就輕鬆搞定Ajax調用,比之前的WCF, StringBuider, .ascx都要方便。

原來在ASP.NET MVC中使用Ajax如此方便,完全可以取代以前用的WCF中轉站。

解決了Ajax的問題,接著處理整個頁面的顯示。

在頁面的View中直接重用剛才Ajax所用的View就行了,範例程式碼如下:

View(Inbox.cshtml):

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
@Html.Partial("MsgList")
</body>
</html>

Control:

public class MsgController : Controller
{
public ActionResult Inbox()
{
SiteMsgQuery msgQuery = new SiteMsgQuery()
{
PageIndex = 1,
PageSize = 30
};
List<SiteMsg> siteMsgList = GetInboxMsgList(msgQuery);
return View("Inbox", siteMsgList);
}
}

搞定!真的很方便!想要的解決方案就是它--ASP.NET MVC!

在這裡為我的錯誤觀點“Ajax為主的應用不需要ASP.NET MVC”向大家道歉!請大家諒解!

好好學習,不進則退!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.