首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

前端 JSON 傳遞至後端:ASP.NET AJAX (ScriptService) 完整實作

     編輯:ASP.NET 基礎

架構圖解

前端 (JS)          序列化          HTTP POST          反序列化          後端 (C#)
┌─────────┐       ┌──────────┐     ┌────────────┐     ┌───────────┐     ┌─────────┐
│ JS 物件 │ ──▶  │ $.toJSON │ ──▶ │ application│ ──▶ │ JsonHelper│ ──▶ │ 強型別  │
│         │       │          │     │ /json      │     │ .Deserialize│   │ 物件    │
└─────────┘       └──────────┘     └────────────┘     └───────────┘     └─────────┘

前端準備:引用 JSON 序列化庫

<!-- 必須在 jQuery 之前或之後均可 -->
<script src="/Scripts/jquery.json-2.4.min.js"></script>

或使用現代瀏覽器原生 JSON.stringify(obj) (IE8+),無需額外庫。

前端呼叫範例

function saveExam() {
    // 1. 蒐集表單資料組成 JS 物件
    var exam = {
        ExamId: '<%= ExamId %>',
        YearTerm: $('#<%= DDLYearTerm.ClientID %>').val(),
        ExamType: $('#<%= DDLExamType.ClientID %>').val(),
        ExamDate: $('#ExamDate').val(),
        ExamName: $('#ExamName').val()
    };

    // 2. 序列化為 JSON 字串
    var json = JSON.stringify(exam); // 或 $.toJSON(exam)

    // 3. 呼叫 ASP.NET AJAX 產生的 Proxy 方法
    AjaxController.EditExam(json, onSuccess, onError, null);
}

function onSuccess(result) {
    if (result === "Success") {
        alert("儲存成功");
        parent.$.fancybox.close(); // 關閉彈窗
    } else {
        alert("失敗:" + result);
    }
}

function onError(err) {
    alert("AJAX 錯誤:" + err.get_message());
}

後端 WebService 實作

1. 定義資料傳輸物件 (DTO)

[Serializable]
public class ExamDto
{
    public string ExamId { get; set; }
    public string YearTerm { get; set; }
    public string ExamType { get; set; }
    public string ExamDate { get; set; }
    public string ExamName { get; set; }
}

2. 實作 WebService 類別

[WebService(Namespace = "https://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[ScriptService] // 關鍵:啟用 AJAX/JSON 支援
public class AjaxController : WebService
{
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false)]
    public string EditExam(string value)
    {
        try
        {
            // 1. 驗證登入狀態
            if (!HttpContext.Current.Request.IsAuthenticated)
                return "會話已過期,請重新登入";

            // 2. 反序列化 JSON 字串為強型別物件
            var exam = JsonHelper.Deserialize(value);

            // 3. 業務邏輯
            new ExamService().UpdateExam(exam);

            return "Success";
        }
        catch (Exception ex)
        {
            // 記錄日誌...
            return "伺服器錯誤:" + ex.Message;
        }
    }
}

3. JSON 反序列化輔助類 (使用 JavaScriptSerializer)

public static class JsonHelper
{
    private static readonly JavaScriptSerializer _serializer = new JavaScriptSerializer();

    public static T Deserialize(string json)
    {
        return _serializer.Deserialize(json);
    }

    public static string Serialize(object obj)
    {
        return _serializer.Serialize(obj);
    }
}

頁面註冊 AJAX Proxy (必要步驟)

protected void Page_Load(object sender, EventArgs e)
{
    // 註冊型別讓 ASP.NET AJAX 產生 JS Proxy
    Ajax.Utility.RegisterTypeForAjax(typeof(AjaxController));
    
    if (!IsPostBack) BindData();
}

這會在頁面輸出 <script src="/AjaxController/jsdebug">,產生 AjaxController.EditExam 等 Proxy 方法。

現代替代方案:ASP.NET Web API / ASP.NET Core

// Web API Controller (ASP.NET 4.5+ / Core)
[Route("api/exam")]
public class ExamController : ApiController
{
    [HttpPut]
    public IHttpActionResult Update(ExamDto dto)
    {
        if (!ModelState.IsValid) return BadRequest(ModelState);
        _service.Update(dto);
        return Ok("Success");
    }
}

// 前端呼叫 (jQuery / fetch)
fetch('/api/exam', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(exam)
}).then(r => r.json()).then(console.log);

優點:RESTful、無 ViewState/ScriptManager 包袱、易測試、前後端完全分離、支援 Swagger/OpenAPI 文件自動生成。

常見問題排查

現象 原因 解決
前端收到 "Invalid web service call, missing value for parameter" JSON 字串參數名稱不匹配 確認 JS 物件屬性名稱與 C# 參數名稱一致 (value)
ScriptMethod 回傳 XML 而非 JSON Request Content-Type 非 application/json 確認前端送出 headers 或加上 [ScriptMethod(ResponseFormat=Json)]
DateTime 反序列化失敗 JSON 日期格式不符 使用 ISO 8601 字串 "2024-01-15T14:30:00" 或自訂 JavaScriptSerializer.Converters
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved