How to get UriTemplate of a Rest Services - web-services

I am trying to make a web service testing tool in C# 4.0,
For RestFull Services When the URI template is same as that of parameter name then I am able to hit the service
eg,
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "JSONDate/{id}"
)]
string JSONDate(string id);
Note: here method name and Uri template are same.
But if URI template is not same as the method name and parameter then I am not able to hit the services,
eg
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "myXMLData/{id}/{id2}/{value}")]
string XMLData(string Id,string id2,string value);
Also the fact that URI template can be designed in multiple ways possess a challenge in setting up the request string.
Is there any way that I can get the URI template so that I can design my request string by parsing the URI template.

Related

AWS Cognito TOKEN endpoint fails to convert authorization code to token

My app first uses the Cognito LOGIN endpoint to obtain an Authorization Code. It then uses the TOKEN endpoint to try and obtain tokens (id_token, access_token, refresh_token) but that fails with unauthorized_client.
I do not understand why, the same client is used to access the LOGIN, and that succeeded in returning an authorization code. I'm following the documentation for the TOKEN endpoint
string clientId = ...
string clientSecret = ...
Uri redirectUri = new Uri("myapp://myhost");
string authorization_code = ... // obtained via HTTP GET on LOGIN endpoint
string accessTokenUrl = "https://<domain>.auth.<region>.amazoncognito.com/oauth2/token";
var queryValues = new Dictionary<string, string>
{
{ "grant_type", "authorization_code" },
{ "code", authorization_code },
{ "redirect_uri", redirectUri.AbsoluteUri },
{ "client_id", clientId},
};
using (HttpClient client = new HttpClient())
{
// Authorization Basic header with Base64Encoded (clientId::clientSecret)
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}",
clientId,
clientSecret))));
// Url Encoded Content
var content = new FormUrlEncodedContent(queryValues);
// HTTPS POST
HttpResponseMessage response = await client.PostAsync(accessTokenUrl, content).ConfigureAwait(false);
string text = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
// test = {"error" : "unauthorized_client"}
}
The problem is two-fold:
1- System.Uri.AbsoluteUri adds a trailing / in the returned string so that my redirectUri becomes myapp://myhost/ instead of myapp://myhost
2- AWS Cognito TOKEN endpoint does not accept trailing / in a redirectURI.
The solution:
I now call redirectUri.OriginalUri instead of redirectUri.AbsoluteUri where I build the query to preserve the redirectUri as it was when I built it.
(I don't really have control over this since in my case Xamarin.Auth.OAuthAuthenticator2 calls Uri.AbsoluteUri on my behalf and transforms the redirectUri string I gave it, so I'm going to have to fix Xamarin.Auth).

Moodle rest post returning error with feature core_user_get_users_by_field

Hi I'm new with moodle and I'm getting an error when calling the webservice.
Currently I'm trying to retrieve a user from moodle with the following function core_user_get_users_by_field and I'm using rest service to do so. I already managed to create a user thus I am authenticated to use the service.
the error that I'm receiving is
Missing required key in single structure: field
The bellow is the code was used to create a User. the issue that I got from the error is that the parameter that I need to send for the post is not formatted well. Does anyone know how to search correctly with this method or any other method.
String token = "token";
String postData = "username=username";
string createRequest = string.Format("http://domain/webservice/rest/server.php?wstoken={0}&wsfunction={1}&moodlewsrestformat=json", token, "core_user_get_users_by_field");
// Call Moodle REST Service
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(createRequest);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
// Encode the parameters as form data:
byte[] formData =
UTF8Encoding.UTF8.GetBytes(postData);
req.ContentLength = formData.Length;
// Write out the form Data to the request:
using (Stream post = req.GetRequestStream())
{
post.Write(formData, 0, formData.Length);
}
// Get the Response
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream resStream = resp.GetResponseStream();
StreamReader reader = new StreamReader(resStream);
string contents = reader.ReadToEnd();
// Deserialize
JavaScriptSerializer serializer = new JavaScriptSerializer();
if (contents.Contains("exception"))
{
// Error
MoodleException moodleError = serializer.Deserialize<MoodleException>(contents);
}
else
{
// Good
}
The webservice core_user_get_users_by_field needs an associative array given as parameter with the following key:values
'field': 'id'
'values': array of integers (must be an array, possibly with just one value)
In PHP it would be, for example:
$parameters = array('field' => 'id', 'values' => array(13));
It means: the user whose 'id' has the value of 13. Of course, you can use other parameters as well: ('field'=>'lastname', 'values'=> array('Smith'))
The parameters you can choose are the fields of the Moodle 'user' table.
Try to build these parameters in your postData variable.
Here's URL that work with my put this url in postman and set http method to post method
hostname/webservice/rest/server.php?wstoken=any_token&wsfunction=core_user_get_users_by_field&field=email&values[0]=h#fci.com
&moodlewsrestformat=json

How can I get this working with a GET or should it be a POST with REST Service in Spring

I am working on some web servers and I have to sent some data to the web service and get back a status code.. I am thinking maybe this should be a POST and not a GET but I would like to hear from all the pros out on the internet.
Here is my client code using Spring RESTTemplate
vars.put("lastName", "JOHN");
vars.put("firstName", "SMITH");
vars.put("middleInitial", "");
vars.put("socialSecurityNumber", "111-11-1111");
vars.put("Type","A");
vars.put("FileNumber","");
vars.put("EISNumber","");
String jsonreturn = restTemplate.getForObject("http://" + mRESTServer.getHost() + ":8080/services/api/checkstatus", String.class, vars);
Now here is my service side code (Spring MVC RESTful service). I would think all the fields I entered in the client would be in the ModelMap object but its not
#RequestMapping(value = "/checkstatus", method = RequestMethod.get)
#ResponseBody
public ResponseEntity<String> getCheckEnrollStatus(ModelMap model) throws ResourceNotFoundException
{
logger.debug("Looking for Status: " + model.toString());
}
So I have two questions:
1) Should I change the GET to a POST due to senting alot of data to the server?
2) If I leave it as a get why is my ModelMap emply?
Please help me out
For your ModelMap to be populated you probably need to annotate it with #RequestBody.
As the comment has pointed out you can't have a request body with a GET as per the specification. So you would either need to make the parameters part of the URL and use get or convert to POST.
Though POST seems to not fit with the purpose of your call.
Normally I'd say this should be a GET, but I noticed you have socialSecurityNumber as one of your parameters. You definitely do NOT want that to be part of your URL. Check out RFC 2616 section 15.1.3
Authors of services which use the HTTP protocol SHOULD NOT use GET based forms for the submission of sensitive data, because this will cause this data to be encoded in the Request-URI. Many existing servers, proxies, and user agents will log the request URI in some place where it might be visible to third parties. Servers can use POST-based form submission instead
Do a POST.
get as it is not changing anything onserver just returning data here is the spec.
Use request parameters like this
#RequestMapping(value = "/checkstatus", method = RequestMethod.get)
#ResponseBody
public ResponseEntity<String> getCheckEnrollStatus(#RequestParam final Long id)
or uri parameters, like
#RequestMapping(value = "/checkstatus/{id}", method = RequestMethod.get)
#ResponseBody
public ResponseEntity<String> getCheckEnrollStatus(#PathVariable final Long id) throws ResourceNotFoundException
{

Pass Entire InfoPath Form to Web Service (Not Submitting)

I have an InfoPath 2010 form that queries a web service. The web service is expecting the entire InfoPath form as an XML string parameter. By an XML string I mean the string on the format
<my:myFields xmlns:my=...>
<my:Name>UserName</my:Name>
...
</my:myFields>
The web service will then process the string and return a result to the InfoPath form.
I have tried to pass the root element, ".", but at the web service end I am receiving the values only formatted by \r\n and \t. Any idea on how to pass the XML tags and the values.
I have found a workaround by passing the list name and the form name to a web service. The web service, which is hosted in SharePoint, will then get the XML of the form.
Here is the code for reference:
public class InfoPathHelper
{
private string _listName;
private string _fileUrl;
public InfoPathHelper(string listName, string fileName)
{
_listName = listName;
_fileUrl = string.Format("{0}/{1}.xml", listName, fileName);
}
public string GetFormXml()
{
using (SPWeb web = SPContext.Current.Web)
{
SPList lib = web.Lists[_listName];
SPFile file = lib.RootFolder.Files[_fileUrl];
XmlDocument doc = new XmlDocument();
doc.Load(file.OpenBinaryStream());
return doc.OuterXml;
}
}
}

Alternative to .NET WSE 3.0

I'm using .NET 2.0. There are any alternative to .NET WSE 3.0?
Is it possible to pass username and password in soap header without any toolkit, only using code?
Thanks
(This suggestion might be way off, since I'm not sure if you mean some special WS.* headers, or just any custom header... and I've never heard of WSE)
I call a webservice with user/pass in a header as follows. It's not production code, but the snippets should illustrate it.
On the client:
string userName = "someusername";
string password = "somepass";
//create the custom header object
MyService.AuthHeader authHeader = new MyService.AuthHeader();
authHeader.UserName = userName;
authHeader.Password = password;
//create the WS-proxy
MyService.SomeWebservice someWS = new MyService.SomeWebservice();
//set headers
someWS.AuthHeaderValue = authHeader;
someWS.SomeMethod();
The webservice:
public class SomeWebservice : System.Web.Services.WebService
{
public AuthHeader Authentication = null; //For receiving the authentication header from the SOAP client (you will never assign this property in user code, .NET handles the plumbing based on the [SoapHeader("Authentication")] attribute
[WebMethod(Description = "Some webservice method")]
[SoapHeader("Authentication")]
public void SomeMethod()
{
string suppliedUserName = Authentication.UserName;
string suppliedPassword = Authentication.Password;
}
}
The AuthHeader class: (defined at the "WS end")
public class AuthHeader : SoapHeader
{
public string UserName = null;
public string Password = null;
}
It's possible to alter the SOAP Message using SOAP Extensions including the required SOAP Header