如何将复杂模型从客户端传递到服务器端?

时间:2022-08-24 14:52:43

I have some data "Foo" that I want to pass from the browser to the server and retrieve predicted statistics based on the information contained within foo.

我有一些数据“Foo”,我希望从浏览器传递到服务器,并根据Foo中包含的信息检索预测的统计信息。

$.ajax({
      type: 'GET',
      url: "/api/predictedStats/",
      data: "foo=" + ko.toJSON(foo, fooProperties),
      contentType: 'application/json; charset=utf-8',
      dataType: 'json',
      success: function(data) {
        return _this.viewModel.setPredictedStats(data);
      },
      error: function(jqXHR, statusText, errorText) {
        return _this.viewModel.setErrorValues(jqXHR, errorText);
      }
    });

I created a predicted stats controller and get method taking an argument of Foo.

我创建了一个预测的stats控制器,并得到了使用Foo参数的方法。

public class PredictedStatsController : ApiController
{
    public PredictedStats Get(Foo foo)
    {
        return statsService.GetPredictedStats(foo);
    }
}

Sticking a breakpoint on the Get method I see the Foo object is always null. There are no errors thrown from the webapi trace logging just the following lines.

在Get方法上粘贴一个断点,我看到Foo对象总是null。以下几行没有从webapi跟踪日志记录中抛出错误。

WEBAPI: opr[FormatterParameterBinding] opn[ExecuteBindingAsync] msg[Binding parameter 'foo'] status[0]  
WEBAPI: opr[JsonMediaTypeFormatter] opn[ReadFromStreamAsync] msg[Type='foo', content-type='application/json; charset=utf-8'] status[0]  
WEBAPI: opr[JsonMediaTypeFormatter] opn[ReadFromStreamAsync] msg[Value read='null'] status[0]   

I've no problem sending the data via a post to the Foo controller to create the Foo object on the server so I can say there's nothing wrong with the json created clientside.

通过post向Foo控制器发送数据以在服务器上创建Foo对象,我没有问题,所以我可以说json创建的clientside没有问题。

Looking in fiddler the resulting Get looks like the following where jsondata is the object foo.

在fiddler中查找,结果Get看起来如下所示,其中jsondata是对象foo。

GET /api/predictedStats?foo={jsondata} HTTP/1.1

Is this even possible or am I going about this all wrong?

这是可能的吗?还是我说错了?

Thanks Neil

谢谢尼尔


EDIT: I feel like I almost got this working with the following

编辑:我觉得我几乎是用下面的方法完成的

public PredictedStats Get([FromUri]Foo foo)
{
    return statsService.GetPredictedStats(foo);
}

The object foo was coming back fine but no properties of Foo were being populated properly.

对象foo很好地返回,但是没有正确地填充foo的属性。


In the mean time I've resorted to using a POST with near identical data just dropping the "foo=" and this is working just fine.

在此期间,我使用了一个几乎相同数据的POST,只是删除了“foo=”,这是正常的。

I'm not sure whether the POST or the GET should be used in this case but that would be interesting to know.

我不确定在这种情况下应该使用POST还是GET,但是知道这个会很有趣。


I also found this http://bugs.jquery.com/ticket/8961 which seems to suggest you can't attach a body to a GET request with jquery so POST is probably the only sensible option

我还发现了http://bugs.jquery.com/ticket/8961,这似乎表明您不能使用jquery将一个主体附加到一个GET请求中,因此POST可能是惟一明智的选择

1 个解决方案

#1


6  

You almost got there :)

你差点就成功了

When you use [FromUri] (which you have to use for 'complex' objects because by default Web API doesn't 'bind' complex objects, it's always looking to deserialize them from the body) you don't need to pass param= in the Uri - you just pass the members of the value as query string parameters. That is 'member1=value&member2=value' - where member1 and member2 are members of the Foo.

当您使用[FromUri](你必须使用复杂的对象,因为默认Web API并不“绑定”复杂的对象,它总是要反序列化从身体里)你不需要通过Uri参数=——你只是传递的成员值作为查询字符串参数。这是'member1=value&member2=value'——其中member1和member2是Foo的成员。

Note there is no 'bug' in jQuery - while the HTTP spec doesn't prohibit a request body, it's likely that the browser does (and if that's the case, the jQuery can't send it), and it's more than likely that a server will never read it anyway. It's just not accepted practise. It also has interesting issues with caching potentially, as well, in that a browser won't cache a POST, PUT, DELETE etc, but will cache a GET if the response headers don't prohibit it - that could have serious side effects for a client application. I recommend you look at this SO: HTTP GET with request body for more information and some useful links on this subject.

请注意,jQuery中没有“bug”——尽管HTTP规范没有禁止请求主体,但浏览器很可能会这样做(如果是这样,jQuery就不能发送),而且很可能服务器永远也不会读取它。这是不被接受的练习。它还可能存在缓存的有趣问题,比如浏览器不会缓存POST、PUT、DELETE等等,但如果响应头不禁止的话,浏览器会缓存GET——这可能会对客户端应用程序产生严重的副作用。我建议您看一下这个:HTTP GET请求体获取更多信息,以及关于这个主题的一些有用链接。

Equally, when using jQuery - you don't need to convert the object to JSON either - just pass the javascript object in the data member of the options and jQuery turns it into the correct format.

同样,在使用jQuery时——也不需要将对象转换为JSON——只需在选项的数据成员中传递javascript对象,jQuery将其转换为正确的格式。

Or should that be, Web API understands the format the jQuery passes it as.

或者,如果是这样,Web API理解jQuery传递给它的格式。

#1


6  

You almost got there :)

你差点就成功了

When you use [FromUri] (which you have to use for 'complex' objects because by default Web API doesn't 'bind' complex objects, it's always looking to deserialize them from the body) you don't need to pass param= in the Uri - you just pass the members of the value as query string parameters. That is 'member1=value&member2=value' - where member1 and member2 are members of the Foo.

当您使用[FromUri](你必须使用复杂的对象,因为默认Web API并不“绑定”复杂的对象,它总是要反序列化从身体里)你不需要通过Uri参数=——你只是传递的成员值作为查询字符串参数。这是'member1=value&member2=value'——其中member1和member2是Foo的成员。

Note there is no 'bug' in jQuery - while the HTTP spec doesn't prohibit a request body, it's likely that the browser does (and if that's the case, the jQuery can't send it), and it's more than likely that a server will never read it anyway. It's just not accepted practise. It also has interesting issues with caching potentially, as well, in that a browser won't cache a POST, PUT, DELETE etc, but will cache a GET if the response headers don't prohibit it - that could have serious side effects for a client application. I recommend you look at this SO: HTTP GET with request body for more information and some useful links on this subject.

请注意,jQuery中没有“bug”——尽管HTTP规范没有禁止请求主体,但浏览器很可能会这样做(如果是这样,jQuery就不能发送),而且很可能服务器永远也不会读取它。这是不被接受的练习。它还可能存在缓存的有趣问题,比如浏览器不会缓存POST、PUT、DELETE等等,但如果响应头不禁止的话,浏览器会缓存GET——这可能会对客户端应用程序产生严重的副作用。我建议您看一下这个:HTTP GET请求体获取更多信息,以及关于这个主题的一些有用链接。

Equally, when using jQuery - you don't need to convert the object to JSON either - just pass the javascript object in the data member of the options and jQuery turns it into the correct format.

同样,在使用jQuery时——也不需要将对象转换为JSON——只需在选项的数据成员中传递javascript对象,jQuery将其转换为正确的格式。

Or should that be, Web API understands the format the jQuery passes it as.

或者,如果是这样,Web API理解jQuery传递给它的格式。