如何通过Html.ActionLink()方法传递JavaScript对象?
Great question! Let's break this down first: the @Html.ActionLink is rendered server-side when your page is generated, while your JavaScript object exists only client-side after the page loads. That means you can't directly reference the JS object in the ActionLink's route values—by the time the JS runs, the server has already sent the finished HTML to the browser.
But don't worry, there are two solid ways to pass that JS object data to your ProceedToPay action:
方案1:修改ActionLink的URL(适合简单数据,GET请求)
We'll add an ID to the ActionLink so we can target it with JavaScript, then dynamically append the JS object's data as query parameters to the link's URL.
Step 1: Update the ActionLink
Add an id attribute to make it easy to select in JS:
@Html.ActionLink("order","ProceedToPay","Shop", new {}, new {@class="btn btn-primary", id="payLink" })
Step 2: Modify the URL with JavaScript
Convert your JS object to a query string and update the link's href property:
@section Scripts() { <script> var objectDeclaredInJavascriptIwantToSend = { userId: 123, cartId: 456, totalAmount: 99.99 }; // Helper function to convert JS object to query string function objToQueryParams(obj) { return Object.keys(obj) .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`) .join('&'); } // Get the link element and update its href const payLink = document.getElementById('payLink'); payLink.href += '?' + objToQueryParams(objectDeclaredInJavascriptIwantToSend); </script> }
Step 3: Receive the data in your Action
Your ProceedToPay action can accept the parameters directly:
public ActionResult ProceedToPay(int userId, int cartId, decimal totalAmount) { // Process the data here return View(); }
方案2:用表单提交(适合复杂/大量数据,POST请求)
If your JS object has nested data or you want to avoid exposing data in the URL, use a hidden form and submit it via JavaScript.
Step 1: Add a hidden form to your page
<form id="payForm" action="@Url.Action("ProceedToPay", "Shop")" method="POST"> @Html.AntiForgeryToken() <!-- Required for ASP.NET POST actions --> </form>
Step 2: Replace the ActionLink with a clickable element
We'll use a link (or button) that triggers the form submission instead of navigating directly:
<a href="#" class="btn btn-primary" id="payBtn">order</a>
Step 3: Populate and submit the form with JavaScript
Dynamically add hidden fields for each property in your JS object, then submit the form:
@section Scripts() { <script> var objectDeclaredInJavascriptIwantToSend = { userId: 123, cartId: 456, items: [ { productId: 789, quantity: 2 }, { productId: 1011, quantity: 1 } ] }; document.getElementById('payBtn').addEventListener('click', function(e) { e.preventDefault(); // Stop the default link behavior const form = document.getElementById('payForm'); // Clear any existing dynamic fields form.querySelectorAll('.dynamic-field').forEach(field => field.remove()); // Recursive function to add nested/array data as form fields function addFormFields(obj, prefix = '') { for (const key in obj) { if (obj.hasOwnProperty(key)) { const fieldName = prefix ? `${prefix}.${key}` : key; if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) { addFormFields(obj[key], fieldName); } else if (Array.isArray(obj[key])) { obj[key].forEach((item, index) => { addFormFields(item, `${fieldName}[${index}]`); }); } else { const input = document.createElement('input'); input.type = 'hidden'; input.name = fieldName; input.value = obj[key]; input.className = 'dynamic-field'; form.appendChild(input); } } } } // Add all fields from the JS object addFormFields(objectDeclaredInJavascriptIwantToSend); // Submit the form form.submit(); }); </script> }
Step 4: Receive the complex object in your Action
Create a model class to match your JS object structure, then accept it as a parameter:
public class OrderRequest { public int UserId { get; set; } public int CartId { get; set; } public List<OrderItem> Items { get; set; } } public class OrderItem { public int ProductId { get; set; } public int Quantity { get; set; } } [HttpPost] [ValidateAntiForgeryToken] public ActionResult ProceedToPay(OrderRequest model) { // Process the order data here return View(); }
To recap: you can't directly mix server-side Razor code with client-side JavaScript here, but you can modify the link's URL or use a form to send the JS data once the page is loaded in the browser.
内容的提问来源于stack exchange,提问作者Abdullah Sohail

