C# MVC中控制器返回后拦截修改JSON对象的技术问询
Absolutely feasible! In ASP.NET MVC, you don't need extra third-party frameworks—you can leverage the built-in Action Filter feature to intercept the response right after the controller action executes, modify the JSON data, and then send it to the client. This is perfect for your requirement of adding a formatted date field from a Unix timestamp.
Step 1: Create a Custom Action Filter
We'll create an ActionFilterAttribute that overrides the OnActionExecuted method—this is where we can access and modify the response before it's sent.
First, make sure you have the Newtonsoft.Json package installed (it's the default JSON serializer for older MVC projects; if you're using System.Text.Json, we'll cover that too).
Here's the filter code:
using System; using System.Web.Mvc; using Newtonsoft.Json.Linq; public class AddFormattedDateTimeFilter : ActionFilterAttribute { public override void OnActionExecuted(ActionExecutedContext filterContext) { // Check if the action returned a JsonResult if (filterContext.Result is JsonResult jsonResult) { // Convert the response data to a JObject for easy manipulation var jsonData = JObject.FromObject(jsonResult.Data); // Check if the UnixTime field exists (adjust the property name to match your model) if (jsonData.TryGetValue("UnixTime", out var unixTimeToken) && unixTimeToken.Type == JTokenType.Integer) { long unixTimestamp = unixTimeToken.Value<long>(); // Convert Unix timestamp (seconds) to DateTime DateTime dateTime = DateTimeOffset.FromUnixTimeSeconds(unixTimestamp).UtcDateTime; // Add the new formatted date field to the JSON jsonData.Add("FormattedDateTime", dateTime.ToString("yyyy-MM-dd HH:mm:ss")); // Update the JsonResult with the modified data jsonResult.Data = jsonData; } } base.OnActionExecuted(filterContext); } }
Step 2: Apply the Filter
You can use this filter in three ways:
Option 1: Apply to a Single Action
Add the attribute directly to your controller action that returns the order data:
public class OrderController : Controller { [AddFormattedDateTimeFilter] public JsonResult GetOrder(int orderId) { // Your existing code to fetch order data with UnixTime var order = new { OrderId = orderId, Total = 99.99, UnixTime = 1717248000 // Example: Unix timestamp for 2024-06-01 00:00:00 UTC }; return Json(order, JsonRequestBehavior.AllowGet); } }
Option 2: Apply to an Entire Controller
Add the attribute to the controller class to modify all JSON responses from this controller:
[AddFormattedDateTimeFilter] public class OrderController : Controller { // All actions here will have their JSON responses processed }
Option 3: Register Globally (Affects All Controllers)
To apply this filter to every JSON response in your application, register it in Global.asax.cs:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); // Add the global filter GlobalFilters.Filters.Add(new AddFormattedDateTimeFilter()); }
If You're Using System.Text.Json
If your project uses System.Text.Json instead of Newtonsoft.Json, modify the filter to use JsonDocument and JsonElement:
using System; using System.Text.Json; using System.Web.Mvc; using System.Collections.Generic; public class AddFormattedDateTimeFilter : ActionFilterAttribute { public override void OnActionExecuted(ActionExecutedContext filterContext) { if (filterContext.Result is JsonResult jsonResult) { var jsonString = JsonSerializer.Serialize(jsonResult.Data); using var doc = JsonDocument.Parse(jsonString); var root = doc.RootElement; // Check for UnixTime field if (root.TryGetProperty("UnixTime", out var unixTimeElement) && unixTimeElement.ValueKind == JsonValueKind.Number) { long unixTimestamp = unixTimeElement.GetInt64(); DateTime dateTime = DateTimeOffset.FromUnixTimeSeconds(unixTimestamp).UtcDateTime; // Create a new JSON object with the added field var modifiedData = new Dictionary<string, object>(); foreach (var property in root.EnumerateObject()) { modifiedData[property.Name] = JsonSerializer.Deserialize<object>(property.Value.GetRawText()); } modifiedData["FormattedDateTime"] = dateTime.ToString("yyyy-MM-dd HH:mm:ss"); jsonResult.Data = modifiedData; } } base.OnActionExecuted(filterContext); } }
Key Notes
- Make sure the property name
UnixTimematches exactly what's returned from your controller. Adjust it if your model uses a different name (likeOrderTimestamp). - You can customize the date format string (
"yyyy-MM-dd HH:mm:ss") to match your client's requirements. - If your response data is a strongly-typed model instead of an anonymous type, the JObject/Dictionary approach still works—you don't need to modify your original model class.
内容的提问来源于stack exchange,提问作者SW Dog

