Awesomium Wpf WebControl read json response from w

2019-09-04 22:31发布

问题:

What I want to do is simply serve the Json response from a Wcf service to the Wpf WebControl. I have tested the Wcf service as working and I can see the Json response in the REST client.

I have basically tried two approaches (thanks to the generous developers who share their code here):-

  • Resource Interceptor How to hide the cursor in Awesomium

Below is how my ResourceInterceptor constructing the ResourceResponse. From the docs ResourceResponse is simply a wrapper around a raw block of data and a specified mime-type. That should mean I should be able to pass in my response along with contentType and awesomium should recognize. But my ajax request all land up in "Error" with no content in the jqXHR :-

private ResourceResponse readWebResponse(HttpWebRequest webreq)
    {
        HttpWebRequest.DefaultMaximumErrorResponseLength = 1048576;
        HttpWebResponse webresp = null;// = webreq.GetResponse() as HttpWebResponse;
        var memStream = new MemoryStream();
        Stream webStream;
            try
            {
                webresp = (HttpWebResponse)webreq.GetResponse();
                webStream = webresp.GetResponseStream();
                byte[] readBuffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = webStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
                    memStream.Write(readBuffer, 0, bytesRead);
            }
            catch (WebException e)
            {
                var r = e.Response as HttpWebResponse;
                webStream = r.GetResponseStream();
                memStream = Read(webStream);
                var wrongLength = memStream.Length;
            }


            memStream.Position = 0;
            StreamReader sr = new StreamReader(memStream);
            string webStreamContent = sr.ReadToEnd();

            byte[] responseBuffer = Encoding.UTF8.GetBytes(webStreamContent);

            // Initialize unmanaged memory to hold the array.
            int responseSize = Marshal.SizeOf(responseBuffer[0]) * responseBuffer.Length;
            IntPtr pointer = Marshal.AllocHGlobal(responseSize);
            try
            {
                // Copy the array to unmanaged memory.
                Marshal.Copy(responseBuffer, 0, pointer, responseBuffer.Length);
                return ResourceResponse.Create((uint)responseBuffer.Length, pointer,webresp.ContentType);
            }
            finally
            {
                // Data is not owned by the ResourceResponse. A copy is made 
                // of the supplied buffer. We can safely free the unmanaged memory.
                Marshal.FreeHGlobal(pointer);
                webStream.Close();
            }
    }

My Ajax request is simple as below:-

   $.ajax({
   url:urlBase+'/list'
   ,success: function(dt){deferred.resolve(dt);alert('hurray')},
   error: function(jqXHR, textStatus, errorThrown ){
   alert('oyei oyei something went wrong'+JSON.stringify(jqXHR));
   var err = eval('(' + xhr.responseText + ')');
   alert(err.Message);}
   });

What I get is:-

{"readyState":0,"responseText":"",status:0,"statusText":"error"}

  • I've also tried using the Userscripts approach from here:- http://answers.awesomium.com/questions/2289/can-i-use-userscripts-or-greasemonkey-scripts-in-a.html

In my Javascript request I simply called above utility like this:-

uScriptHelper.xmlHttpRequest({url:urlBase+'/list', onload=function(){return(this.responseText);}});

I can see the responseText is being set by the Userscripts. But my ajax response is still all the same - error result with all empty parameters. What am I doing wrong here?

回答1:

Phew, I managed to finally get it work after putting in almost 4 days of trying various stuff. I will add the answer here hopefully it will help someone at some point of time.

First thing is :-

  • The Resource Interceptor approach doesn't work for Json response for Awesomium WebControl. No-matter what I tried applying all the mime types to ResourceResponse of Awesomium WebControl it didn't take me anywhere. The code above is there for anybody who would want to explore it further. I'm not very sure what header I am missing here. Moreover the good news is:-

  • The Awesomium JSObject approach as mentioned in above post works. So all we need to do here is create custom JSObject emulating the xmlHttpRequest object as in above post. As long as Javascript is talking to Javascript we are fine. (ResourceResponse seems to be hostile to ajax requests). So here is finally how I managed to get it work.

Here's my Factory - uses Jquery promise and calls the xmlHttpRequest emulation object as we created above:-



    todoFactory.getTodos = function () {
    var deferred = $.Deferred();
        uScriptHelper.xmlHttpRequest({ 
            url: urlBase + '/list', method: 'get', 
            onload: function (obj) {deferred.resolve(JSON.parse(obj.responseText)); } 
        });
    return(deferred.promise());
    };

And here's my Controller calling the above factory :-



    var promise=  todoFactory.getTodos();
        promise.then(function (data) {
            setInterval(function () {
                $scope.todos = data;
                $scope.$apply();
            }, 10);
        },function (error) {
            $scope.status = 'Unable to load todo data: ' + error;
            alert('unable to load data '+error);
        }, function (update) {
            alert('Got notification: ' + update);
        });

Hope this helps someone at some point! Happy Coding!