Kendo jQuery Grid数据源为空:跨域WebAPI返回JSON无法加载
Hey Andrew, sorry to hear you've been stuck on this for days—let's break down what's likely going wrong and how to fix it.
First, let's recap your scenario: you're dealing with a cross-subdomain WebAPI that requires authentication, returns a valid JSON array, but your Kendo DataSource won't load the data (Grid shows structure but no rows, AJAX throws an unknown error). The key issue here ties into JSONP configuration gaps and mismatched DataSource settings for your API's response format.
1. Your WebAPI isn't returning JSONP (critical for cross-subdomain requests)
You mentioned switching from XML to JSON and using JSONP for cross-subdomain, but plain JSON won't work for cross-origin requests without CORS enabled. WebAPI doesn't return JSONP by default—you need to explicitly configure it to wrap your JSON response in a callback function (the core of JSONP).
Fix on WebAPI side:
Add JSONP support to your WebAPI configuration (in WebApiConfig.cs):
using System.Net.Http.Formatting; using System.Web.Http; public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Enable JSONP globally var jsonpFormatter = new JsonpMediaTypeFormatter(); config.Formatters.Insert(0, jsonpFormatter); // Keep your existing routing and other configs... } }
If you prefer a per-action approach, you can define a [Jsonp] attribute and apply it to your API method (you'll need to implement the attribute logic, but the global formatter is simpler for this use case).
2. Mismatched Kendo DataSource Settings
Looking at your code snippet, there are two key issues breaking the data load:
- You set
type: 'odata'but your API returns a plain JSON array, not OData-formatted data (which includes avaluewrapper and metadata). This confuses Kendo's DataSource parser. - You didn't explicitly set
dataType: "jsonp"for the read operation—cross-subdomain requests require JSONP (unless you enable CORS on the API, which is an alternative we'll cover).
Fixed Frontend Code:
$(document).ready(function() { var apDs = new kendo.data.DataSource({ transport: { read: { url: "http://xxx.xxx.xxx.xxx/Sec/Api/ProcessInfo", dataType: "jsonp", // Critical for cross-subdomain JSONP requests // Add authentication handling if using Basic Auth (adjust credentials as needed) beforeSend: function(xhr) { var authCredentials = btoa("your-username:your-password"); xhr.setRequestHeader("Authorization", "Basic " + authCredentials); } } }, // Remove type: 'odata'—your API returns plain JSON, not OData schema: { // Optional: Explicitly define model fields for clarity (Kendo can auto-detect, but this avoids guesswork) model: { fields: { id: { type: "number" }, ProcessName: { type: "string" }, Username: { type: "string" }, Password: { type: "string" } } } } }); // Bind the DataSource to your Grid (example setup) $("#your-grid-id").kendoGrid({ dataSource: apDs, columns: [ { field: "id", title: "ID" }, { field: "ProcessName", title: "Process Name" }, { field: "Username", title: "Username" }, { field: "Password", title: "Password" } ], autoBind: true }); });
3. Debugging Steps to Verify Fixes
- Open your browser's DevTools > Network tab:
- Check the API request response: it should look like
callbackFunctionName([your-json-array])—if not, your WebAPI JSONP configuration is incomplete. - Look for CORS or authentication errors in the Console tab—even with JSONP, missing auth headers or blocked origins can cause silent failures.
- Confirm the
Authorizationheader is being sent (if using Basic Auth) in the request headers.
- Check the API request response: it should look like
4. Alternative: Enable CORS on WebAPI (instead of JSONP)
If JSONP feels restrictive (it only supports GET requests), you can enable CORS on your WebAPI to allow cross-subdomain requests with regular JSON:
// In WebApiConfig.cs using System.Web.Http.Cors; public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Allow your frontend domain to access the API config.EnableCors(new EnableCorsAttribute("http://your-frontend-subdomain.com", "*", "*")); // Other configs... } }
Then update your Kendo DataSource to use dataType: "json" and add withCredentials: true if using cookie-based authentication:
read: { url: "http://xxx.xxx.xxx.xxx/Sec/Api/ProcessInfo", dataType: "json", withCredentials: true, beforeSend: function(xhr) { // Add auth headers if needed } }
Give these fixes a try—most likely the missing JSONP configuration on either the API or frontend is why your DataSource stays empty without a clear error.
内容的提问来源于stack exchange,提问作者Andrew

