PDA

View Full Version : Connect to .NET WCF web Service



Roby
13 Aug 2009, 5:01 PM
Is Ext GWT can connect to .NET WCF web service? Any code sample if possible?:D

Colin Alworth
13 Aug 2009, 10:34 PM
Its been over a year since I did any WCF, but your easiest bet is going to try the WCF call that the asp.net js calls. Take that url, and break down the inputs, and use the GWT RequestBuilder object, and parse the incoming json using JSONParser.

Roby
14 Aug 2009, 12:12 AM
Thanks Colin,

Actually I am using ExtJs 2.0 now, I am wonder any easiest way to change to Ext GWT.
What I concern most is that, how to adopt Ext GWT without any changes to my WCF webservice and with minimum affort?

The original code using ExtJs for calling my WCF web service will be like this:


var params = new Object();
params.p1 = 'testparam';
Ext.lib.Ajax.defaultPostHeader = 'application/json';
Ext.Ajax.request({
url: 'http://localhost:7899/testing.web.Service.svc/TestFunction',
method: 'POST',
params: Ext.util.JSON.encode(params),
scope: this,
callback: function(options, success, response) {
if (success) {
alert('Great');
} else {
alert('Disappointed');
}
}
})


Another problem is using Store:


store: new Ext.data.GroupingStore({
storeId: 'mygridstore',
proxy: new Ext.data.WCFHttpProxy({ url: this.wsUrl }),
reader: new Ext.data.WCFJsonReader({
root: 'rows',
totalProperty: 'count',
fields:
[
{ name: 'c1', type: 'string' } ]
}),
groupField: 'c1',
sortInfo: {
field: 'c1',
direction: 'ASC'
}
}


Any sample can someone provide for the same code under EXT GWT?
Many thanks in advance!!:D

Colin Alworth
14 Aug 2009, 5:08 AM
Using the RequestBuilder and your url, you should be able to reproduce that first example trivially. The second will take a small amount of extra work, and you could take a few routes. My inclination would be to look into JS overlay types (http://code.google.com/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideOverlayTypes), so that you can treat the js as if it is java objects, but you might be more familiar with the extjs idea of using a JsonReader (com.extjs.gxt.ui.client.data.JsonReader<D>) to get your objects from the call.

Colin Alworth
14 Aug 2009, 5:18 AM
I should clarify - to use the overlay objects in the Grid<D>, you should make the overlay objects implement ModelData - it would probably help to have a abstract base class in your lib that took care of the basic impl of the get and set calls.

Roby
17 Aug 2009, 5:08 PM
Thanks Colin,

I am now successfully connect to my .net webservice.

But another problem from reading the Json response.

My json result string is something like this:


{"customers":
{"customer":[
{"id":1,"name":"John"},
{"id":2,"name":"Alex"}
]}
}


Where the root of the json response is not an array.

GXT breaks if we setRoot to "customer" as the jsonRoot.get(modelType.getRoot()) returns null in JsonReader.java read(Object, object) method.

If we setRoot("customers") it proceeds fine until it tries to Cast into JSONArray when it's not.

In ExtJS we would be able to do something like setRoot("customers.customer"), but I don't find any way to do such a thing in GXT.
Is there any workaround for this?

Thanks in advance!!

Colin Alworth
17 Aug 2009, 8:39 PM
Were your object handled directly in Java, it would be clear why JsonReader is having problems. JsonReader is expecting an object, and is expecting that one of the properties of that object is a list of data members. Instead, you are telling it that a property of a property is a list.


Data d = dataFromServer()...
d.getCustomers();//<-this would make sense to be the List, but instead...
d.getCustomers().getCustomer();//<-this is the list.

As said, I havent worked with WCF in a long time, but if you cannot convince your web service code to use a more sane object structure, like

{"customers":[
{"id":1,"name":"John"},
{"id":2,"name":"Alex"}
]
}then you should look into assisting the reader by removing the first shell of the the object. Can you post the code (or something like it) that passes the json into the JsonReader?

Roby
17 Aug 2009, 10:00 PM
Thanks Colin with your kindly help;)

My code is simply like this:



ModelType Jsontype = new ModelType();


Jsontype.setRoot("GetStatusListResult");

Jsontype.setRecordName("rows");


Jsontype.addField("STATUS", "STATUS");



RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,




http://service/com.web.Service.svc/GetStatusList);
HttpProxy<String> proxy = new HttpProxy<String>(builder);
JsonReader<ListLoadResult<ModelData>> reader = new JsonReader<ListLoadResult<ModelData>>(Jsontype);



final BaseListLoader<ListLoadResult<ModelData>> loader = new BaseListLoader<ListLoadResult<ModelData>>(proxy, reader);




And I the Json respone is:




/*

* {
* "GetStatusListResult":
* "{
* "count":7,
* "rows" :[
* {"STATUS":"Accepted"},
* {"STATUS":"Cancel Do Not Load"},
* {"STATUS":"Do Not Load"}
* ]
* }"
* }


*/


Where WCF have wrap a layer to the standard Json return with "GetStatusListResult".

Colin Alworth
17 Aug 2009, 11:35 PM
Sorry, but you missed the chunk where you actually fire the request and handle the response - the rest of this helps, but that is the crux of it. Something like

builder.sendRequest("dataString", new RequestCallback...

Also, your example array doesnt match the count param - are you anticipating doing paging with that?

Roby
18 Aug 2009, 12:44 AM
Dear Colin,

I have writa new WCFJsonReader for breaking up the Json respone and pass back to the JsonReader. It work fine now!!:)) Thanks so much!!

And now come to the problem similar to what you have concerned: Passing parameter with JSON format...

In ExtJs, there is something like

Ext.util.JSON.encode(params)
to encode the data into Json format. But I am not able to find any API provided in GXT2.0 for the same functionality.

Colin Alworth
18 Aug 2009, 1:03 AM
JSONObject can do what you want - it is a GWT class, and you can put values as needed into it. You might find it easier to start with a GXT Params object, then use that to construct a JSONObject.


Params p = new Params();
p.set("key", "value");

...
JSONObject json = new JSONObject(p.getValues());
String jsonString = json.toString();

Roby
18 Aug 2009, 1:43 AM
Thanks again Colin,

Your suggestion come near the result I want, just one thing can't be resolve.



Params postParams = new Params();
postParams.set("key", "value");
JSONObject json = new JSONObject(postParams.getValues());
jsonParams = json.toString();


The above code cause error when json.toString()
I find that the set() is not working as I want, so I change to use add().



postParams.add("testing");
postParams.add("again");
postParams.add("and again");


But now the json.toString() return such result:
{"0":"testing", "1":"again", "2":"and again"}

I am wonder am I using wrongly?:((

Colin Alworth
18 Aug 2009, 1:45 AM
Add() treats it like an array, puts them like a list of params - look into perhaps building your json directly using the JSONObject and children?

Roby
18 Aug 2009, 5:27 PM
here is the error when I use set:



java.lang.ClassCastException

at java.lang.Class.cast(Unknown Source)
at com.google.gwt.dev.shell.JsValueGlue.get(JsValueGlue.java:122)
at com.google.gwt.dev.shell.ie.SwtOleGlue.convertVariantsToObjects(SwtOleGlue.java:57)
at com.google.gwt.dev.shell.ie.IDispatchImpl.callMethod(IDispatchImpl.java:119)
at com.google.gwt.dev.shell.ie.IDispatchProxy.invoke(IDispatchProxy.java:155)
at com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:294)
at com.google.gwt.dev.shell.ie.IDispatchImpl.method6(IDispatchImpl.java:194)
at org.eclipse.swt.internal.ole.win32.COMObject.callback6(COMObject.java:117)
at org.eclipse.swt.internal.ole.win32.COM.VtblCall(Native Method)
at org.eclipse.swt.internal.ole.win32.IDispatch.Invoke(IDispatch.java:64)
at org.eclipse.swt.ole.win32.OleAutomation.invoke(OleAutomation.java:493)
at org.eclipse.swt.ole.win32.OleAutomation.invoke(OleAutomation.java:417)
at com.google.gwt.dev.shell.ie.ModuleSpaceIE6.doInvokeOnWindow(ModuleSpaceIE6.java:68)
at com.google.gwt.dev.shell.ie.ModuleSpaceIE6.doInvoke(ModuleSpaceIE6.java:153)
at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:453)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:231)
at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
at com.google.gwt.json.client.JSONParser.createObject(JSONParser.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.ie.IDispatchImpl.callMethod(IDispatchImpl.java:126)
at com.google.gwt.dev.shell.ie.MethodDispatch.invoke(MethodDispatch.java:97)
at com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:294)
at com.google.gwt.dev.shell.ie.IDispatchImpl.method6(IDispatchImpl.java:194)
at org.eclipse.swt.internal.ole.win32.COMObject.callback6(COMObject.java:117)
at org.eclipse.swt.internal.ole.win32.COM.VtblCall(Native Method)
at org.eclipse.swt.internal.ole.win32.IDispatch.Invoke(IDispatch.java:64)
at org.eclipse.swt.ole.win32.OleAutomation.invoke(OleAutomation.java:493)
at org.eclipse.swt.ole.win32.OleAutomation.invoke(OleAutomation.java:417)
at com.google.gwt.dev.shell.ie.ModuleSpaceIE6.doInvokeOnWindow(ModuleSpaceIE6.java:68)
at com.google.gwt.dev.shell.ie.ModuleSpaceIE6.doInvoke(ModuleSpaceIE6.java:153)
at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:453)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:231)
at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
at com.google.gwt.json.client.JSONObject.get0(JSONObject.java)
at com.google.gwt.json.client.JSONObject.get(JSONObject.java:89)
at com.google.gwt.json.client.JSONObject.toString(JSONObject.java:183)
at test.app.client.client.WCFJsonProxy.generateJsonParams(WCFJsonProxy.java:85)
at test.app.client.client.WCFJsonProxy.load(WCFJsonProxy.java:29)
at com.extjs.gxt.ui.client.data.BaseLoader.loadData(BaseLoader.java:134)
at com.extjs.gxt.ui.client.data.BaseLoader.load(BaseLoader.java:98)
at test.app.client.client.JsonGridExample$1.componentSelected(JsonGridExample.java:98)
at test.app.client.client.JsonGridExample$1.componentSelected(JsonGridExample.java:1)
at com.extjs.gxt.ui.client.event.SelectionListener.handleEvent(SelectionListener.java:20)
at com.extjs.gxt.ui.client.event.SelectionListener.handleEvent(SelectionListener.java:1)
at com.extjs.gxt.ui.client.event.BaseObservable.callListener(BaseObservable.java:176)
at com.extjs.gxt.ui.client.event.BaseObservable.fireEvent(BaseObservable.java:96)
at com.extjs.gxt.ui.client.widget.Component.fireEvent(Component.java:444)
at com.extjs.gxt.ui.client.widget.button.Button.onClick(Button.java:530)
at com.extjs.gxt.ui.client.widget.button.Button.onComponentEvent(Button.java:277)
at com.extjs.gxt.ui.client.widget.Component.onBrowserEvent(Component.java:760)
at com.google.gwt.user.client.DOM.dispatchEventImpl(DOM.java:1320)
at com.google.gwt.user.client.DOM.dispatchEventAndCatch(DOM.java:1299)
at com.google.gwt.user.client.DOM.dispatchEvent(DOM.java:1262)
at sun.reflect.GeneratedMethodAccessor10.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.ie.IDispatchImpl.callMethod(IDispatchImpl.java:126)
at com.google.gwt.dev.shell.ie.IDispatchProxy.invoke(IDispatchProxy.java:155)
at com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:294)
at com.google.gwt.dev.shell.ie.IDispatchImpl.method6(IDispatchImpl.java:194)
at org.eclipse.swt.internal.ole.win32.COMObject.callback6(COMObject.java:117)
at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:1925)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2966)
at com.google.gwt.dev.SwtHostedModeBase.processEvents(SwtHostedModeBase.java:235)
at com.google.gwt.dev.HostedModeBase.pumpEventLoop(HostedModeBase.java:558)
at com.google.gwt.dev.HostedModeBase.run(HostedModeBase.java:405)
at com.google.gwt.dev.HostedMode.main(HostedMode.java:232)


I am still not able to construct the JSONObject as the put() require JSONValue that I am not able to convert from my Object value.

Roby
18 Aug 2009, 6:28 PM
Thanks so much Colin,

I have solved the case with construct a Json format string myself and call by:


JSONObject json = (JSONObject) JSONParser.parse(jsonStr);
jsonParams = json.toString();


Actually it should be like this:


JSONObject json = new JSONObject();
json.put(key,JSONParser.parse(value));
json.put(key2,JSONParser.parse(value2));


But I found that the Paser doesn't support emty string as value that I may have it. That's why I have to format the whole string and parse at once.
(Stupid that I create the json format string, parse once to JSONObject, and .toString() back to my string:s)

And it will not yet supporting a complex value(array) unless I have to format the complex value by myself. Then I become writing a JSONStringPaser.:((

If any better way to do so, please let me know!:D

Thanks again!

Arno.Nyhm
19 Aug 2009, 5:29 AM
Dear Colin,

I have writa new WCFJsonReader for breaking up the Json respone and pass back to the JsonReader. It work fine now!!:)) Thanks so much!!


can you please post the code of your WCFJsonReader?

nilesh.chavan
19 Sep 2011, 5:42 AM
Hi,

Please post the source code for calling WCF RESTful web service from Sencha touch. This will help us to understand it completely.
Thanks in advance.
Nils

Colin Alworth
19 Sep 2011, 6:49 AM
This is a forum post for Ext GWT, you might have better luck if you ask in the Sencha Touch forums.