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);
// JavaScriptResult
return JavaScript("alert('Hello World!');");
// ContentResult 等效
return Content("alert('Hello World!');", "application/x-javascript");
多數瀏覽器將 application/x-javascript 視同 text/javascript。
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;
}
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);
DenyGet (預設):防止 JSON Hijacking 攻擊,GET 請求拋出例外。AllowGet:明確允許 GET 回應 JSON (需評估風險)。內建 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 提升序列化效能與彈性。