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

ASP.NET MVC ActionResult 本質解析:JavaScriptResult 與 JsonResult 深度剖析

     編輯:關於ASP.NET

JavaScriptResult:動態腳本回應

public class JavaScriptResult : ActionResult
{
    public string Script { get; set; }
    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        response.ContentType = "application/x-javascript"; // 非 text/javascript
        response.Write(Script);
    }
}

// Controller 便利方法
protected virtual JavaScriptResult JavaScript(string script);

與 ContentResult 等價替代

// JavaScriptResult
return JavaScript("alert('Hello World!');");

// ContentResult 等效
return Content("alert('Hello World!');", "application/x-javascript");

多數瀏覽器將 application/x-javascript 視同 text/javascript。

實戰範例:購物車訂單處理 AJAX 回應

public class HomeController : Controller
{
    private static Dictionary<string, int> _stock = new Dictionary<string, int> { {"001",20}, {"002",30}, {"003",40} };
    
    public ActionResult Index()
    {
        var cart = new ShoppingCart();
        cart.Add(new ShoppingCartItem { Id="001", Quantity=1, Name="商品A" });
        cart.Add(new ShoppingCartItem { Id="002", Quantity=1, Name="商品B" });
        cart.Add(new ShoppingCartItem { Id="003", Quantity=1, Name="商品C" });
        return View(cart);
    }
    
    public ActionResult ProcessOrder(ShoppingCart cart)
    {
        var sb = new StringBuilder();
        foreach (var item in cart)
            if (!_stock[item.Id] >= item.Quantity)
                sb.Append($"{item.Name}: {_stock[item.Id]};");
        
        if (sb.Length == 0)
            return Content("alert('購物訂單成功處理!');", "text/javascript");
        
        return JavaScript($"alert('庫存不足! ({sb.ToString().TrimEnd(';')})');");
    }
    
    private bool CheckStock(string id, int qty) => _stock[id] >= qty;
}

JsonResult:JSON 資料回應

public class JsonResult : ActionResult
{
    public object Data { get; set; }
    public string ContentType { get; set; }
    public Encoding ContentEncoding { get; set; }
    public JsonRequestBehavior JsonRequestBehavior { get; set; } // 預設 DenyGet
    
    public override void ExecuteResult(ControllerContext context)
    {
        if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && 
            context.HttpContext.Request.HttpMethod == "GET")
            throw new InvalidOperationException("GET 請求不允許 JSON 回應,請設定 JsonRequestBehavior.AllowGet");
        
        var response = context.HttpContext.Response;
        response.ContentType = String.IsNullOrEmpty(ContentType) ? "application/json" : ContentType;
        if (ContentEncoding != null) response.ContentEncoding = ContentEncoding;
        if (Data != null)
            response.Write(new JavaScriptSerializer().Serialize(Data));
    }
}

// Controller 便利方法
protected JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior);

JsonRequestBehavior 安全機制

  • DenyGet (預設):防止 JSON Hijacking 攻擊,GET 請求拋出例外。
  • AllowGet:明確允許 GET 回應 JSON (需評估風險)。

JavaScriptSerializer vs JSON.NET

內建 JavaScriptSerializer 效能與功能有限,實務建議替換為 Json.NET (NuGet: Newtonsoft.Json):

public class JsonNetResult : JsonResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        // ... 同前,但使用 JsonConvert.SerializeObject(Data, Formatting.Indented, new JsonSerializerSettings { ... })
    }
}

總結

JavaScriptResult 適用於傳統 AJAX 腳本注入回應,JsonResult 為現代 RESTful API 標準回應格式。注意 JsonRequestBehavior.DenyGet 安全預設值,生產環境建議採用 JSON.NET 提升序列化效能與彈性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved