简体   繁体   English

ASP.NET MVC模型绑定不适用于AJAX GET,但适用于Post

[英]ASP.NET MVC Model binding doesn't work with AJAX GET but works with Post

I'm having a problem using the Jquery AJAX as a GET Request. 我使用Jquery AJAX作为GET请求时遇到问题。 For some reason the ASP.NET MVC model binder doesn't seem to be able to bind to my filter item. 由于某种原因,ASP.NET MVC模型绑定器似乎无法绑定到我的过滤器项。 What happens is the action result is called but an empty object is created. 调用操作结果会发生什么,但会创建一个空对象。

However if I change from HTTP Get to HTTP Post then it works. 但是,如果我从HTTP Get更改为HTTP Post,那么它可以工作。 Why would that be? 那为什么会这样? From what I understand it would be better to use GET as no data is changing on the server. 根据我的理解,最好使用GET,因为服务器上的数据没有变化。

Here's a stripped down version of my code: 这是我的代码的精简版:

AJAX: 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: 的ActionResult:

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

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

    return View(filteredViewModel );
}

Filter: 过滤:

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

First, just to clear up misconceptions, POST doesn't mean change , necessarily. 首先,为了解决误解,POST并不一定意味着改变 It's perfectly valid to request via POST when accessing a "function", for lack of a better word. 由于缺少更好的单词,在访问“功能”时通过POST请求是完全有效的。 For example: 例如:

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

# Response
200 OK
4

Nothing has "changed", but POST is still the most appropriate HTTP verb. 没有任何“改变”,但POST仍然是最合适的HTTP动词。

That said, there's a fundamental difference between GET and POST requests, namely the concept of a POST "body". 也就是说,GET和POST请求之间存在根本区别,即POST“body”的概念。 A POST body can have a content type and therefore can be interpreted properly on the server-side as JSON, XML, etc. With GET, all you have is a querystring, which is just simply a string. POST主体可以具有内容类型,因此可以在服务器端正确解释为JSON,XML等。使用GET,您只需要一个查询字符串,它只是一个字符串。

The problem you're having is that with GET, the filter "object" is just a string, and since a string does not implement IFilter the modelbinder can't bind it. 您遇到的问题是,使用GET时,过滤器“object”只是一个字符串,并且由于字符串不实现IFilter因此模型绑定器无法绑定它。 However, via POST, the filter "object" is sent in the POST body with a proper content type. 但是,通过POST,过滤器“对象”将在POST正文中以适当的内容类型发送。 So, the modelbinder receives it as JSON, and maps the JSON object onto an implementation of IFilter . 因此,modelbinder将其作为JSON接收,并将JSON对象映射到IFilter的实现。

The moral is that GET is only viable for simple requests -- with data that's pretty much only name-value pairs of simple types. 道德观点是,GET仅适用于简单的请求 - 数据几乎只是简单类型的名称 - 值对。 If you need to transmit actual objects, you need to use POST. 如果需要传输实际对象,则需要使用POST。

I don't know why it was accepted, but the currently accepted answer is totally wrong. 我不知道为什么会被接受,但目前接受的答案是完全错误的。

ModelBinders don't bind the sent parameters if your object name is precisely filter . 如果对象名称是精确filter则ModelBinder不会绑定已发送的参数。 So change the name of the object and it will bind properly. 因此,更改对象的名称,它将正确绑定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM