ASP.NET MVC模型绑定无法与AJAX GET一起使用,但可以与Post一起使用。

3
我在使用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) {

    }

ActionResult:

[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; }
}

2
这是因为GET在发布路由参数(查询字符串)方面有一些限制。GET无法使用复杂参数进行发布。 - Imad Alazani
你能发布 toJSON 方法的代码吗? - ataravati
抱歉,我不能这样做,因为这只是KnockoutJS的toJSON函数。但是我可以向您展示它正在创建的JSON类型: {"logDate":"01/08/2013","specificItem_ID":null"} - Chris Nevill
你尝试过只使用 data: ko.toJSON(model.filter) 吗?我认为这可能会起作用。至少对于这个简单的情况,我相信它应该可以。 - AaronLS
Aaraon 我刚刚尝试了这个,但不幸的是它没有产生任何影响。 - Chris Nevill
2个回答

5

首先,为了消除误解,POST并不一定意味着“更改”。当访问一个“函数”时,请求通过POST是完全有效的,缺乏更好的词语。例如:

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

# Response
200 OK
4

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

话虽如此,GET和POST请求之间存在根本差异,即POST的“body”概念。POST body可以具有内容类型,因此可以在服务器端正确地解释为JSON、XML等格式。而使用GET请求时,您只有一个查询字符串,它只是一个简单的字符串。

你遇到的问题是,在使用GET时,筛选“对象”只是一个字符串,由于字符串不实现IFilter,所以模型绑定器无法将其绑定。然而,通过POST,筛选“对象”以正确的内容类型发送到POST body中。因此,模型绑定器将其接收为JSON,并将JSON对象映射到IFilter的实现上。

道义是:GET仅适用于简单请求 - 数据基本上只是简单类型的名称-值对。如果需要传输实际对象,则需要使用POST。


-1

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

如果您的对象名称恰好为filter,则ModelBinders不会绑定发送的参数。因此,请更改对象的名称,它将正确地绑定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接