Ok, so I have the service reference in my .NET project. And yes I know that you now have access to proxy classes.
But in the past, I am used to doing this via an HttpWebRequest object using NVP, but never tried using the WSDL and sending a SOAP request this way.
I'm not quite sure which object to use to send the request. Not sure where to start here. I've looked at the docs but seen no good examples out there for .NET and PayPal.
Other than a WSDL vs. sending an HttpWebRequest via a NVP API and querystring params, I really do not understand if there's a difference in how you send the request. It's all just over Http so can't you use HttpWebRequest also over a SOAP API (using WSDL)?
You start by generating a service reference from the metadata: Right click on the project -> Add Service Reference and point to the WSDL url: https://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl
This will generate proxy classes to the current project which could be used to send requests:
using (var client = new PayPalAPIInterfaceClient())
{
var credentials = new CustomSecurityHeaderType
{
Credentials = new UserIdPasswordType
{
Username = "username",
Password = "password"
}
};
var request = new AddressVerifyReq
{
AddressVerifyRequest = new AddressVerifyRequestType
{
Street = "some street",
Zip = "12345"
}
};
var response = client.AddressVerify(ref credentials, request);
}
Related
I am looking for a way to call the appropriate method (get, post etc.) on an ApiController class based on the URL and request type etc. without making a http request.
Background: We have an API application with numerous controllers that needs to also accept requests from a remote server. Due to restrictions I cannot control there is no way to open ports between the two servers to allow the remote server to make the request directly so we decided to forward the data using websockets (SignalR). I can send (within reason) whatever information is required.
I have tried the below:
HttpRequestMessage request = new HttpRequestMessage();
var bld = new UriBuilder
{
Port = 123,
Path = "api/v1/search",
Query = "query=search_string"
};
request.RequestUri = bld.Uri;
var httpCfg = AppConfiguration.Get().HttpConfig; //this is the same config that UseWebApi was called with and contains the routes.
var route = httpCfg.Routes.GetRouteData(request);
var controllerSelector = new DefaultHttpControllerSelector(httpCfg);
var descriptor = controllerSelector.SelectController(request);
route contains the controller name (search) but the call to SelectController throws an exception with a 404 response in it (I presume this indicates I am missing something from the fake request). The same URI works when sent as a direct http request so the routes do work as best I can tell.
Is there a better way to do this, or if not what am I missing from the request that is causing the 404?
Basically my idea is to develop a proxy which will run in windows
I have created windows service application which running successfully and i have integrated a web service code in the windows service application running in windows service.
How to call that web service method when the client hits my url?
How to form the url which can call web service method to get the method return value?
OK, I'll try to answer.
Let's assume you want to call REST web service. What do you need? A HttpClient and (probably) JSON/XML Serializer. You can use built-in .NET classes, or a library like RestSharp
Sample calling REST web service using RestSharp
var client = new RestClient("http://example.com");
// client.Authenticator = new HttpBasicAuthenticator(username, password);
var request = new RestRequest("resource/{id}", Method.POST);
request.AddParameter("name", "value"); // adds to POST or URL querystring based on Method
request.AddUrlSegment("id", 123); // replaces matching token in request.Resource
// easily add HTTP Headers
request.AddHeader("header", "value");
// add files to upload (works with compatible verbs)
request.AddFile(path);
// execute the request
RestResponse response = client.Execute(request);
var content = response.Content; // raw content as string
// or automatically deserialize result
// return content type is sniffed but can be explicitly set via RestClient.AddHandler();
RestResponse<Person> response2 = client.Execute<Person>(request);
var name = response2.Data.Name;
// easy async support
client.ExecuteAsync(request, response => {
Console.WriteLine(response.Content);
});
// async with deserialization
var asyncHandle = client.ExecuteAsync<Person>(request, response => {
Console.WriteLine(response.Data.Name);
});
// abort the request on demand
asyncHandle.Abort();
You are not required to use RestSharp, no. For simple cases HttpWebRequest (+DataContractJsonSerializaer or Xml analogue) will be just perfect
Having SOAP web service?
Follow the instructions provided here
The ServiceStack docs are full of examples on how to use server side implementation of authentication of a user. But how does one set the user credentials on the client side?
I use ServiceStack to consume a JSON REST service like this:
var restClient = new JsonServiceClient (baseUri);
var response = restClient.Get<MyResponse> ("/some/service");
How can I add any form of authentication to the request? The webservice I want to consume uses OAuth 1.0, but I am interested in adding custom authentication, too.
In my code, I have previously performed OAuth token exchange successfully, so I already own a valid access token and need to sign every REST request now using this access token and its token_secret.
ServiceStack's AuthTests shows different ways of authenticating when using the ServiceStack Service Clients. By default BasicAuth and DigestAuth is built into the clients, e.g:
var client = new JsonServiceClient(baseUri) {
UserName = UserName,
Password = Password,
};
var request = new Secured { Name = "test" };
var response = client.Send<SecureResponse>(request);
Behind the scenes ServiceStack will attempt to send the request normally but when the request is rejected and challenged by the Server the clients will automatically retry the same request but this time with the Basic/Digest Auth headers.
To skip the extra hop when you know you're accessing a secure service, you can tell the clients to always send the BasicAuth header with:
client.AlwaysSendBasicAuthHeader = true;
The alternative way to Authenticate is to make an explicit call to the Auth service (this requires CredentialsAuthProvider enabled) e.g:
var authResponse = client.Send<AuthResponse>(new Auth {
provider = CredentialsAuthProvider.Name,
UserName = "user",
Password = "p#55word",
RememberMe = true, //important tell client to retain permanent cookies
});
var request = new Secured { Name = "test" };
var response = client.Send<SecureResponse>(request);
After a successful call to the Auth service the client is Authenticated and if RememberMe is set, the client will retain the Session Cookies added by the Server on subsequent requests which is what enables future requests from that client to be authenticated.
Answering myself, as I've found a nice way to do it using the LocalHttpWebRequestFilter hook in the JsonServiceClient:
For securing a web service with OAuth 1.0a, every http request has to send a special Authorization: header. Within this header field, a hash (signature) must be send that uses some characteristics of the request as input data, like the hostname, request url and others.
Now it seems the LocalHttpWebRequestFilter is called by ServiceStack right before the http request is made, and exposes the underlying HttpWebRequest object, where one can add extra headers and access the required fields of the request.
So my solution is now basically:
var client = new JsonServiceClient (baseUri);
client.LocalHttpWebRequestFilter += (request) => {
// compute signature using request and a previously obtained
// access token
string authorization_header = CalculateSignature (request, access_token);
request.Headers.Add ("Authorization", authorization_header);
};
var response = client.Get<MySecuredResponse> ("/my/service");
Note that I use the Devdefined.OAuth library to do all the heavy stuff in CalculateSignature(). The creation of request token, obtaining user authorization, and exchanging the request token for access token as required by OAuth is done outside of ServiceStack, before the above service calls.
I'm trying to send a new Share on a Linkedin Person. This is my client code:
RestClient client = new RestClient()
{
Authority = "http://api.linkedin.com/v1",
Credentials = this.AccessCredentials(connectionData.ApplicationKey, connectionData.ApplicationSecret, connectionData.AccessToken, connectionData.AccessSecret),
Method = WebMethod.Post,
Encoding = Encoding.UTF8,
};
RestRequest request = new RestRequest()
{
Path = "people/~/shares",
Encoding = Encoding.UTF8,
};
Share share = new Share(socialMessage.Text, socialMessage.Name, socialMessage.Description, VisibilityCode.Anyone);
share.Content.SubmittedImageUrl = socialMessage.PictureLink;
share.Content.SubmittedUrl = socialMessage.Link;
String content = Utilities.SerializeToXml<Share>(share);
client.AddPostContent(System.Text.Encoding.UTF8.GetBytes(content));
client.AddHeader("Content-Type", "text/xml");
request.AddPostContent(System.Text.Encoding.UTF8.GetBytes(content));
request.AddHeader("Content-Type", "text/xml");
RestResponse response = client.Request(request);
I always obtain this error message after the call "Couldn't parse share document: error: Unexpected end of file after null".
Does anyone can tell me how to use Hammock library to send a POST to LinkedIn?
Thanks & Regards
Also there is possible solution here:
https://github.com/danielcrenna/hammock/issues/4
I'm not sure how to use the hammock library, but you can debug API calls for LinkedIn (or any other web service) using the tips at
http://developer.linkedin.com/documents/debugging-api-calls
This will show you how to install an HTTP sniffer and watch the traffic to see what's happening. Once you've done that, if you're still having issues post them and it'll be possible to debug what's going wrong.
How do i set cookie in the request while invoking a java webservice from a windows application using c#. I want to pass the JSESSIONID as cookie in the HttpHeader while invoking a java webservice. I have the JSESSIONID with me. I want to know how to create a cookie and pass the same in the request.
Could someone suggest me. Is it feasible.
If you are using WCF to generate your client proxy (svcutil.exe) you could append a custom http header with your request like this:
// MyServiceClient is the class generated by svcutil.exe which derives from
// System.ServiceModel.ClientBase<TServiceContract> and which allows you to
// call the web service methods
using (var client = new MyServiceClient())
using (var scope = new OperationContextScope(client.InnerChannel))
{
var httpRequestProperty = new HttpRequestMessageProperty();
// Set the header value
httpRequestProperty.Headers.Add("JSESSIONID", "XXXXX");
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
// Invoke the method
client.SomeMethod();
}
If you are using wsdl.exe to generate your client you can take a look here.
UPDATE:
Actually there's no need to cast to HttpWebRequest to add a custom header:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
WebRequest request = base.GetWebRequest(uri);
request.Headers.Add("JSESSIONID", "XXXXX");
return request;
}
This answer is largely based on the answer by Darin Dimitrov - if you find it useful please upvote his answer.
In my case the web service wanted the JSESSIONID value as a cookie, not as a miscellaneous header value.
Also my WCF client was using proxy code generated by Visual Studio's Project - Set Service Reference facility, which I believe is the same as using the wsdl.exe program.
// Session ID received from web service as response to authentication login
private string _sessionId;
// This code needed to add the session ID to the HTTP header as a JSESSIONID cookie value
using (MyServiceClient myServiceClient = new MyServiceClient())
using (new OperationContextScope(myServiceClient.InnerChannel))
{
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers.Add("Cookie", "JSESSIONID=" + _sessionId);
OperationContext.Current.OutgoingMessageProperties.Add(
HttpRequestMessageProperty.Name, httpRequestProperty);
myServiceClient.someMethod();
}