calling RESTful WCFservice method with object as parameter from java
문제
i have a RESTful WCF service and one of its methods use an Object as parameter
[WebInvoke(UriTemplate = "save", Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat= WebMessageFormat.Xml), OperationContract]
public SampleItem Create(SampleItem instance)
{
return new SampleItem() { Id = 1, StringValue = "saved" };
// TODO: Add the new instance of SampleItem to the collection
//throw new NotImplementedException();
}
I am trying to call this method from my eclipse android project. i am using these lines of codes
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost post=new HttpPost("http://10.0.2.2:2768/Service1.svc/save");
ArrayList<NameValuePair> nvp= new ArrayList<NameValuePair>();
nvp.add(new BasicNameValuePair("Id", "1"));
nvp.add(new BasicNameValuePair("StringValue", "yolo"));
post.setEntity(new UrlEncodedFormEntity(nvp));
HttpResponse httpResponse = httpClient.execute(post);
HttpEntity httpEntity = httpResponse.getEntity();
String xml = EntityUtils.toString(httpEntity);
Every time i get this error Method not allowed.
in the XML that is returned by the service method.
i have tried invoking it from the browser, but encountered the same error there.
please tell me what i am doing wrong and what i can do instead.
thanks in advance to anyone who can help.
note: other methods which do not use object as parameter are working fine.
EDIT: tried Fiddler2 with success. but stalled again.
i have tried invoking the method SampleItem Create(SampleItem instance)
with the url http://localhost:2768/Service1.svc/save
and it works. the method returns the object in XML format.
in fiddler i added the request body as
<SampleItem xmlns="http://schemas.datacontract.org/2004/07/WcfRestService1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Id>1</Id><StringValue>saved</StringValue></SampleItem>
but the problem is that i can not find any way to add this xml string to the HttpPost or HttpRequest as the requestbody eclipse android project.
note: passing the xml string as Header or UrlEncodedFormEntity did not work.
해결책
First, you should get the Web Service method working from the browser - I recommend using Fiddler2 - its easier to construct the request body with your object and also to set the request headers when doing a post. It will show you the response so should help with debugging. As for your code, I'm doing a POST to a WCF service and instead of doing
post.setEntity(new UrlEncodedFormEntity(nvp));
I'm simply doing:
HttpPost request = new HttpPost(url);
// Add headers.
for(NameValuePair h : headers)
{
request.addHeader(h.getName(), h.getValue());
}
(I am using JSONObjects and I have RequestFormat = WebMessageFormat.Json in my WebInvoke parameters.
Also, check your using the correct UriTemplate name in your url as they are case sensitive.
다른 팁
finally i have succeeded to send a json object over to my WCF Service here's my code
URI uri = new URI("http://esimsol.com/droidservice/pigeonlibrary.service1.svc/save");
JSONObject jo1 = new JSONObject();
jo1.put("Id", "4");
jo1.put("StringValue", "yollo");
HttpURLConnection conn = (HttpURLConnection) uri.toURL().openConnection();
conn.setRequestProperty("Content-Type","application/json; charset=utf-8");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("User-Agent", "Pigeon");
conn.setChunkedStreamingMode(0);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.write(jo1.toString().getBytes());
out.flush();
int code = conn.getResponseCode();
String message = conn.getResponseMessage();
InputStream in = conn.getInputStream();
StringBuffer sb = new StringBuffer();
String reply;
try {
int chr;
while ((chr = in.read()) != -1) {
sb.append((char) chr);
}
reply = sb.toString();
} finally {
in.close();
}
SampleItem SI = new SampleItem();
SI=new Gson().fromJson(reply, SampleItem.class);
Toast.makeText(getApplicationContext(), SI.getStringValue(),Toast.LENGTH_LONG).show();
conn.disconnect();
thanks to StackOverFlow. i had to combine a number of code snippets to achieve this.