文章出處

首先,寫這篇博文的目的是給未來自己看的,希望以后每天都讀一下,這樣就不會犯錯誤了。

前兩天,在開發項目的時候,寫一個功能,就是使用 Ajax 異步加載一些信息,這個在平常開發過程中,我們一般都會遇到,在 Controller 中寫一個異步 Action 方法,使用 HttpGet 或 HttpPost,然后在方法中處理一些操作,最后返回拼接的 Html 字符串,View 中的操作就是寫一個 Ajax 腳本進行調用,貼一點示例代碼:

Controller 中的 Action 方法:

public class CommonAjaxController : Controller
{
    [HttpGet]
    public async Task<ContentResult> GetAjaxInfo(int para)
    {
        var item = await .......GetInfo(para);
        StringBuilder resultHtml = new StringBuilder();
        foreach (var item in news)
        {
            resultHtml.Append("< li >< a href = \"/n/\{item.Url}/\" target = \"_blank\" >\{item.Title}< / a > < / li >");
        }
        return Content(resultHtml.ToString());
    }
}

View 中的 Ajax 腳本:

$(function () {
    $.ajax({
        url: '/CommonAjax/GetAjaxInfo',
        type: 'GET',
        datatype: "json",
        contentType: "application/json; charset=utf-8",
        data: { para: para },
        success: function (data) {
            if (data) {
                $("#div_id").html(data);
            }
        }
    });
});

什么問題呢?就是我不管怎么調試,最后 div_id 中填充的 data 始終是字符串格式,也就是沒有轉換的 html 格式,說實話,這個問題,我當時“掙扎”了很久,我以為是 Controller 中的 Action 只能返回格式化的字符串,然后就各種搜索關鍵字,花了很長時間,最后也沒有一個結果,因為是通過 Ajax 腳本填充的,不是通過 ViewData 之類的東西傳遞,所以你不能直接使用 View 中的 Html.Raw() 進行 Html 格式轉換,所以轉換操作必須在 Action 方法中,但關鍵是,沒有這之類的解決方式,這個問題,大概花了我幾個小時的時候,我隱約記得之前這樣寫的方式是沒問題的,為此我有查看了下之前項目中相類似的代碼,確實沒什么問題,為此我更郁悶了。。。

哎,往事不堪回首,最后發現,原因出在我“復制粘貼”的 Html 字符串上,不知道為什么,我是使用瀏覽器的查看元素功能,然后復制現有的 Html 代碼,拷貝在 VS2015 中,當時沒怎么注意,你可以仔細看下 GetAjaxInfo 中的 Html 字符,會發現中間莫名多了一個“空格”,哎,哎,哎,當我發現是這個問題的時候,我的第一想法是:窗戶在哪里???我要跳下去。

當然,一個問題場景證明不了自己有多“”,就在今天,又是類似的問題,哎!

我使用 ASP.NET 5,在 Action 中給 ViewData 賦一個值,然后在 View 中進行展示,Html 中訪問 ViewData 沒有什么問題,但是當我在 JS 腳本中訪問,就出現了問題,示例代碼:

Controller 中的 Action 方法:

public async Task<IActionResult> About()
{
    using (var context=new BloggingContext())
    {
        ViewData["data"] = await context.Blogs.FirstOrDefaultAsync();
    }
    //ViewData["data"] = await Task<string>.Run(() => { return "data"; });
    //ViewData["data"] = "data";
    ViewBag.Message = "Your application description page. XISHUAI";
    return View();
}

View 代碼

@{
    ViewBag.Title = "About";
}
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3>

<h1>@ViewData["data"]</h1>

<p>Use this area to provide additional information.</p>
<script type="text/javascript">
    alert(@ViewData["data"])
    window.onload = function () {
        alert(@ViewData["data"]);
    }
</script>

上面是我后來的測試代碼,可能有些亂,但寫出來都是有原因的,這一次我鉆什么“”了呢?答案是:async 的 Action 只能給 ViewData 賦值,然后 JS 腳本才能訪問到。聽起來可能有點暈,為什么我會這樣認為呢?因為之前我寫類似的代碼,ViewData["data"] 是通過 await 獲取訪問到的數據,而今天我寫的 Action 方法,ViewData["data"] 是同步賦值的,但這種寫法就不行,所以我把“嫌疑”放在了它身上,然后有去搜索“async Action ViewData”之類的關鍵詞,但卻沒搜到什么有“價值”的東西,現在想想,能搜到的話,就真的奇怪了,為了重現這個“問題”,我又搞了個測試項目進行操作,最后發現同步賦值的 JS 也不能訪問了,當時做到這,真是要死的感覺,然后花了兩個小時進行再思考,沒辦法,一點頭緒都沒有,然后肚子餓了,下班吃東西,在路上,以至于吃飯的時候,我都在思考這個問題,在想到底是哪方面出了問題?最后,還是一點頭緒都沒有。

回到住的地方,倒了杯茶,然后再“思考”,不知道抽了什么筋,把 alert(@ViewData["data"]) 改成 alert("@ViewData["data"]"),你猜怎么著???居然訪問到了,我的天哪???自己到底是有多”二“啊,哎!


總結下自己寫代碼的方式,或者是尋找解決問題的方式:

  • 一定要細心。
  • 反復 CodeReview 自己寫的代碼,不要過于“相信”自己。
  • 如果陷在一個問題,試著跳出這個問題,散散步,或者喝一杯茶,也許就會發現問題所在了。

謹記謹記。。。


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()