【问题标题】:ASP.NET MVC Model binding doesn't work with AJAX GET but works with PostASP.NET MVC 模型绑定不适用于 AJAX GET 但适用于 Post
【发布时间】:2025-12-18 01:20:07
【问题描述】:

我在使用 Jquery AJAX 作为 GET 请求时遇到问题。 由于某种原因,ASP.NET MVC 模型绑定器似乎无法绑定到我的过滤器项。发生的情况是调用了操作结果,但创建了一个空对象。

但是,如果我从 HTTP Get 更改为 HTTP Post,则它可以工作。 为什么会这样? 据我了解,使用 GET 会更好,因为服务器上没有数据发生变化。

这是我的代码的精简版:

AJAX:

$.ajax({
    url: url,
    contentType: 'application/json',
    dataType: 'json',            
    type: "GET",
    data: "{'filter':" + ko.toJSON(model.filter) + "}",
    error: function (xhr, textStatus, errorThrown) {

    },
    success: function (returnedData) {

    }

动作结果:

[HttpGet]
public virtual ActionResult Index(IFilter filter)
{
    ViewModel filteredViewModel = GetFilteredViewModel(filter);

    if (Request.IsAjaxRequest())
    {
        return toJSON(filteredViewModel );
    }

    return View(filteredViewModel );
}

过滤器:

public class Filter: IFilter 
{    
   public Nullable<DateTime> LogDate { get; set; }        
   public Nullable<int> SpecificItem_ID { get; set; }
}

【问题讨论】:

  • 这是因为GET 对发布Route Parameters(Query String) 有一些限制。 GET 不适用于发布复杂参数。
  • 能贴出toJSON方法的代码吗?
  • 对不起,我不能,因为这只是 KnockoutJS 的 toJSON 函数但是我可以向您展示它正在创建的 JSON 类型:{"logDate":"01/08/2013","specificItem_ID":null "}
  • 您是否尝试过只使用data: ko.toJSON(model.filter)。我认为这可能有效。至少对于这个简单的案例,我认为应该这样做。
  • Aaraon 我刚试过,但不幸的是没有任何区别

标签: asp.net-mvc jquery http-get


【解决方案1】:

首先,为了澄清误解,POST 并不一定意味着改变。在访问“函数”时通过 POST 请求是完全有效的,因为没有更好的词。例如:

# Request
POST /add-xy
{ "x": 2, "y": 2 }

# Response
200 OK
4

什么都没有“改变”,但 POST 仍然是最合适的 HTTP 动词。

也就是说,GET 和 POST 请求之间存在根本区别,即 POST“主体”的概念。 POST 正文可以具有内容类型,因此可以在服务器端正确解释为 JSON、XML 等。使用 GET,您所拥有的只是一个查询字符串,它只是一个字符串。

您遇到的问题是,使用 GET 时,过滤器“对象”只是一个字符串,并且由于字符串没有实现 IFilter,modelbinder 无法绑定它。但是,通过 POST,过滤器“对象”以适当的内容类型在 POST 正文中发送。因此,modelbinder 将其作为 JSON 接收,并将 JSON 对象映射到 IFilter 的实现。

道理是 GET 只适用于简单的请求——数据几乎只是简单类型的名称-值对。如果需要传输实际对象,则需要使用 POST。

【讨论】:

    【解决方案2】:

    我不知道它为什么被接受,但目前接受的答案是完全错误的。

    如果您的对象名称恰好是filter,则ModelBinders 不会绑定发送的参数。所以更改对象的名称,它将正确绑定。

    【讨论】: