cefsharp / CefSharp

.NET (WPF and Windows Forms) bindings for the Chromium Embedded Framework
http://cefsharp.github.io/
Other
9.89k stars 2.92k forks source link

Can't access PostData info using ajax requests #1288

Closed CheloXL closed 7 years ago

CheloXL commented 9 years ago

I'm implementing a custom IResourceHandler that I will be calling from ajax. Basically, it will be a RPC channel so I can call methods from js through my handler.

The thing is, that I need to access the posted data (that it is not in form-encoding, but in json). PostData.Elements is throwing an Ex, so I can't use that, and I don't see a way to read the raw data from the request.

I'm using CefSharp.43 in a WPF app. In the previous version I was being able to read the raw data from the request. It is possible to do the same now in any way?

amaitland commented 9 years ago

What is the exception? Can you provide a sample to reproduce the problem?

If you can fork https://github.com/cefsharp/CefSharp.MinimalExample that would be fantastic.

In the previous version I was being able to read the raw data from the request.

So it worked correctly in 41.0.1?

CheloXL commented 9 years ago

The error is "Object reference not set to an instance of an object". Inspecting the non-public members, I see that the MCefRefPtr pointer is set to 0x0.

In v41, I can read the stream directly, didn't have to access the data via PostData.Elements (don't remember now how, as I upgraded my project and changed that :( ).

It seems that PostData.Elements works only with form-encoding data, as if I send some test data as form-urlencoded, I correctly get the Elements collection filled.

I will try to fork and create a test case, but that would take me a couple of days, as I'm currently having some time off and will not be able to do so at least until next Wednesday.

Edit: In V41, I read the data via request.Body.

amaitland commented 9 years ago

The error is "Object reference not set to an instance of an object". Inspecting the non-public members, I see that the MCefRefPtr pointer is set to 0x0.

Can you be more specific? StackTrace? Which file are you actually referring to?

In v41, I can read the stream directly, didn't have to access the data via PostData.Elements

I don't believe there's ever been access to a Stream in the context of PostData.

https://github.com/cefsharp/CefSharp/blob/cefsharp/41/CefSharp.Core/Internals/CefRequestWrapper.cpp

(don't remember now how, as I upgraded my project and changed that :( ).

Look in your source control?

I will try to fork and create a test case, but that would take me a couple of days, as I'm currently having some time off and will not be able to do so at least until next Wednesday.

Ok cool :+1:

CheloXL commented 9 years ago

request.PostData.Elements is the one that throws the NRE.

The stacktrace doesn't has anything interesting:

at CefSharp.Internals.CefPostDataWrapper.get_Elements()
   at DDS.Synchronizer.DesktopClient.SchemeHandlers.AsyncCallSchemeHandler.<>c__DisplayClass8_0.<<ProcessRequestAsync>b__0>d.MoveNext() in D:\\Users\\CheloXL\\Documents\\Visual Studio 2015\\Projects\\2DSoluciones\\Synchronizer\\DDS.Synchronizer.DesktopClient\\SchemeHandlers\\AsyncCallSchemeHandler.cs:line 241

Unfortunately, no source control for this project, but as I mentioned, I read the value from the .Body property.

amaitland commented 9 years ago

request.PostData.Elements is the one that throws the NRE.

What is the value of IsDisposed?

Edit: In V41, I read the data via request.Body.

Better to post a new comment. There's no notification on GitHub to say a post has been updated.

CheloXL commented 9 years ago

IsDisposed is false. IsReadOnly also throws NRE.

amaitland commented 9 years ago

IsDisposed is just a bool, IsReadOnly actually makes a call to the underlying Cef object.

master has a very simple post data example, see https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Example/CefSharpSchemeHandler.cs#L58

Maybe you can modify it quickly to demo/debug your problem?

CheloXL commented 9 years ago

I already created a test case, available at https://github.com/CheloXL/CefSharp.MinimalExample

When you run it, you will be presented with two buttons, both calls the same resourcehandler. The one done in a form, works fine. The second one, that sends the same data via ajax, doesn´t work.

Not sure if you need a pull request or you can simply download the case from my repository.

amaitland commented 9 years ago

Not sure if you need a pull request or you can simply download the case from my repository.

Nope, that's fine.

For reference there are some limitations when posting data using XHR and a custom scheme handler, see https://bitbucket.org/chromiumembedded/cef/issues/404#comment-16410248

CheloXL commented 9 years ago

Ok, but if I read it correctly... "does not pass POST data to the request for synchronous XHRs executed on non-HTTP schemes"

Key here is synchronous. I'm not doing sync requests, but async. Anyways, thanks for the link. It's a bit late now and I'm taking a plane so I can't do any more tests, but I will try the suggestions there when I'm back.

amaitland commented 9 years ago

does not pass POST data to the request for synchronous XHRs executed on non-HTTP schemes"

As I said, provided as a reference. I am well aware of the sync vs async difference.

The CefRequest->GetPostData() returns null for whatever reason. I don't believe there's a problem with CefSharp, more likely something has changed with the newer version of CEF.

Workaround is to use a standard scheme e.g. http

I have made one change, so IRequest.PostData returns null if no post data. See https://github.com/cefsharp/CefSharp/commit/5e2546067bfbea524de77c3e7fa439249a36bf88

(Will probably backport to 43.0.1)

CheloXL commented 9 years ago

I found here http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=774 that in that old version of Cef you could register a scheme for a specific domain.. can that be done in CefSharp? In that way I would be able to use my handler for a specific domain, but let Cef access standard internet resources for any other domain..

amaitland commented 9 years ago

Yes you can specify a domain name for a scheme