I purchased a SMS gateway for which they gave me only HTTP and XML API but I need ASP.NET API to work on my project. Can anybody help me how to convert the below API to ASP.NET(c#) API.
HTTP API
http://indiansms.smsmaker.in/api/sendmsg.php?user=*********&pass=********&sender=Sender ID&phone=Mobile No&text=SMS&priority=Priority&stype=smstype
XML API
$data="<?xml version='1.0' encoding='utf-8'?>
<MESSAGE>
<USERNAME>username</USERNAME>
<PASSWORD>password</PASSWORD>
<TEXT>Hi, this is a test message</TEXT>
<PRIORITY>ndnd</PRIORITY>
<SENDER>SenderId</SENDER>
<MSGTYPE>normal</MSGTYPE>
<ADDRESS>*********</ADDRESS>
<ADDRESS>*********</ADDRESS>
</MESSAGE>";
How to convert this API to ASP.NET API.
I know that this question is unqualified to post it here. But I need it immediately.
I have done something similar from an .Net application where we used the http api to send sms. We used the webclient in .net to send messages.
using (var client = new WebClient())
{
client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR1.0.3705;)");
client.QueryString.Add("user", "username");
client.QueryString.Add("pass", "password");
// Add all the parameters you need
using (Stream stream = client.OpenRead("http://indiansms.smsmaker.in/api/sendmsg.php"))
{
// Do something with the response..
}
}
Related
I've created an ASP.NET Core web application, and installed + used the Swashbuckle.AspNetCore version 6.1.5 Nuget package. This hosts the following openapi document on https://example.com/swagger/v1/swagger.json.
Also my API supports content-negotiation.
When sending no Accept header, or Accept: text/xml header, the api will return an XML string
When sending an Accept: application/json header, the api will return a JSON string
Now I've tried consuming my api through the swagger document:
Create a new .NET Core console application
Right-click the project file → Add → Service Reference
OpenAPI
URL: https://example.com/swagger/v1/swagger.json
Namespace: Example.Api
Class name: ExampleClient
You can then write a Main like this:
static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
var httpClient = new System.Net.Http.HttpClient();
// httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
var mintPlayerClient = new MintPlayer.Api.MintPlayerClient("https://mintplayer.com", httpClient);
var artists = await mintPlayerClient.ApiArtistListAsync(false);
}
Now when you debug the console app
navigate to the ApiArtistListAsync method in the swaggerClient class
put a breakpoint at the client_.SendAsync call
you can now inspect what the swaggerClient is sending to the webservice
Usually it's like this:
SOAP = XML
REST = JSON
Even when adding a DefaultRequestHeader on the HttpClient the response from the HttpClient is an XML, because it's explicitly added inside the SwaggerClient method:
And here is how the code is generated + the line where the Accept header is explicitly set (swaggerClient:430). This is auto-generated code from adding the service-reference.
So why is the Accept header in the generated code explicitly set to text/plain? Why isn't the default accept header value application/json, since this is a REST service?
I think you might want to check this on both side, client(your console) and server(your api project).
We all know that usually
SOAP = XML
REST = JSON
But you're coding the whole things, total in-control of what being send and what being response.
Let's assume you client send Accept-Header which support both text/xml and text/plain (which as i understand here, you expect a response as text/plain).
Then the server realize that your console is happy with either text/xml and text/plain, and the server itself support all kind of common format.
So it'll have to electing the most convenient format to response to the client.
Which in this case is text/xml.
That's so, the console received and happy with text/xml response format either way
And if that's the case, that I get you right, you want to receive text/plain on the console, then make sure the only Accept header sending out is text/plain or do some custom logic on your API to choose the text/plain format over others when sending response.
I'm attempting to download an HTML response from a website but I keep getting the following response: The security settings for your Internet browser or device appear to be out of date. Please upgrade now.
I've attempted to use every User-Agent setting I could find but I'm still receiving the same error. I've also tried the HTTPWebRequest method and received the same error.
The request works fine when I open IE or Chrome and type URL.
Here is my code:
string url = #"https://www.royalmail.com/track-your-item?trackNumber=" + track.TrackingNumber;
WebClient client = new WebClient();
client.Headers.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)");
string content = client.DownloadString(url);
Example of URL that I'm trying to call: https://www.royalmail.com/track-your-item?trackNumber=FP065628015GB
You should use TLS1.2 as your security protocol for this site.
This line should fix your problem.
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
I have a project in Angular 2.4.0 where I want to call endpoints from a Symfony 3 REST API. Both projects are launched locally. To get rid of CORS errors in Http calls in Angular, I set some proxy rules as follows :
{
"/api/*": {
"target": "http://myapi.dev:8000",
"secure": false,
"changeOrigin": true,
"pathRewrite": {"^/api" : ""},
"logLevel": "debug"
}
}
The first step is the authentication with Google OAuth, so I open a new popup window (in my Angular project) :
window.open('api/connect/google', '_blank', 'location=yes,height=570,width=520,scrollbars=yes,status=yes');
Then I chose a Google account to authenticate with, then the API close the popup window automatically when successfully authenticated.
Then I call the API again to get the current logged-in user :
get(): Observable<User> {
return this.http.get('api/user')
.map((response: Response) => response.json())
.catch((error: any) => Observable.throw(error));
}
The problem is that the API throws the following :
Request URL:http://localhost:2222/api/user
Request Method:GET
Status Code:302 Found
Remote Address:127.0.0.1:2222
Access-Control-Allow-Origin:*
cache-control:no-cache, private
connection:close
content-type:json
date:Wed, 22 Mar 2017 10:20:32 GMT
location:http://myapi.dev:8000/login
server:nginx/1.11.10
transfer-encoding:chunked
x-debug-token:128b90
x-debug-token-link:http://myapi.dev:8000/_profiler/128b90
x-powered-by:PHP/7.1.3
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:no-cache
Connection:keep-alive
Cookie:PHPSESSID=18c73caec383e91904dfd239d1a95faa
Host:localhost:2222
Pragma:no-cache
Referer:http://localhost:2222/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
It seems the API don't know I'm already authenticated and tries to redirect me to the /login route for every other Http calls I want to make.
The API works as following :
/login is a twig page with a link to /connect/google (the Google OAuth)
/connect/google allows you to choose one Google Account to authenticate with
If you call any API endpoint without being authenticated, it redirects you to /login
If you're authenticated, you can call every API endpoint
If I try all above Angular Http calls directly into the browser (eg: http://myapi.dev:8000/connect/google, http://myapi.dev:8000/user) everything works well.
I really have no idea where this issue comes from.
As you said in comments, Angular app is hosted on http://localhost:2222/, but api is hosted on http://myapi.dev:8000. Those two origins are completely different. It means that when myapi.dev will begin session, set cookie, it will be unavailable on localhost. Browser is not allowed to send cookies from different origins (due to CORS). That's why api doesn't see your session id key.
Possible ways to overcome problem:
Store both apps (angular and api) on the same origin (it means same domain, same protocol, and same port) - it's the easiest way.
Catch session ID cookie value (just after it will be set) and store it inside sessionStorage. Next, create Angular's request interceptor which will add SESSION cookie to all requests which're going to myapi.dev
I'm trying to log in and register with external authentication using MVC5, web api 2 and templates from it.
I don't know how to do it. I read
asp.net web api 2: how to login with external authentication services?.
When I call
GET /api/Account/ExternalLogins?returnUrl=%2F&generateState=true
response is
{
"Name": "Facebook",
"Url": "/api/Account/ExternalLogin?provider=Facebook&
response_type=token&
client_id=self&redirect_uri=http%3A%2F%2Flocalhost%3A6685%2F&
state=Yj1...hU1",
"State": "Yj1...hU1"
}
(I don't know what is State for)
Then i can use the Url above (authentication is with cookies) and response is OK html status and some html page (i dont know why)
This call
GET /api/Account/UserInfo
response info with null loginProvider.
I want to register user with FB or Google, so i need token, but i don't know whitch access_token and how can i get it. In example (link above) is this:
POST /api/Account/RegisterExternal
Authorization: Bearer VPcd1RQ4X... (access_token from url)
Content-Type: application/json
{"UserName":"myusername"}
but what is
access_token from url ?
So, my questions are:
How can I external register / login with web api 2 templates?
What is State for? (seems like useless)
External login is Web Api is supported out of the box and can be easily plugged in using the Owin pipeline. Gettting the access token and performing all the oauth related calls are done by the Facebook Owin Provider.
You can find a sample of facebook login with a web site here
How do I get a WCF client to process server responses which have been GZipped or Deflated by IIS?
On IIS, I've followed the instructions here on how to make IIS 6 gzip all responses (where the request contained "Accept-Encoding: gzip, deflate") emitted by .svc wcf services.
On the client, I've followed the instructions here and here on how to inject this header into the web request: "Accept-Encoding: gzip, deflate".
Fiddler2 shows the response is binary and not plain old Xml.
The client crashes with an exception which basically says there's no Xml header, which ofcourse is true.
In my IClientMessageInspector, the app crashes before AfterReceiveReply is called.
Some further notes:
(1) I can't change the WCF service or client as they are supplied by a 3rd party. I can however attach behaviors and/or message inspectors via configuration if this is the right direction to take.
(2) I don't want to compress/uncompress just the soap body, but the entire message.
Any ideas/solutions?
* SOLVED *
It was not possible to write a WCF extension to achieve these goals. Instead I followed this CodeProject article which advocate a helper class:
public class CompressibleHttpRequestCreator : IWebRequestCreate
{
public CompressibleHttpRequestCreator()
{
}
WebRequest IWebRequestCreate.Create(Uri uri)
{
HttpWebRequest httpWebRequest =
Activator.CreateInstance(typeof(HttpWebRequest),
BindingFlags.CreateInstance | BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance,
null, new object[] { uri, null }, null) as HttpWebRequest;
if (httpWebRequest == null)
{
return null;
}
httpWebRequest.AutomaticDecompression =DecompressionMethods.GZip |
DecompressionMethods.Deflate;
return httpWebRequest;
}
}
and also, an addition to the application configuration file:
<configuration>
<system.net>
<webRequestModules>
<remove prefix="http:"/>
<add prefix="http:"
type="Pajocomo.Net.CompressibleHttpRequestCreator, Pajocomo" />
</webRequestModules>
</system.net>
</configuration>
What seems to be happening is that WCF eventually asks some factory or other deep down in system.net to provide an HttpWebRequest instance, and we provide the helper that will be asked to create the required instance.
In the WCF client configuration file, a simple basicHttpBinding is all that is required, without the need for any custom extensions.
When the application runs, the client Http request contains the header "Accept-Encoding: gzip, deflate", the server returns a gzipped web response, and the client transparently decompresses the http response before handing it over to WCF.
When I tried to apply this technique to Web Services I found that it did NOT work. Although the helper class was executed in the same was as when used by the WCF client, the http request did not contain the "Accept-Encoding: ..." header.
To make this work for Web Services, I had to edit the Web Proxy class, and add this method:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.HttpWebRequest rq = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
rq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
return rq;
}
Note that it did not matter whether the CompressibleHttpRequestCreator and block from the application config file were present or not. For web services, only overriding GetWebRequest in the Web Service Proxy worked.
Thanks for your WCF tip! We're going to be enabling IIS compression for services at my shop, and I'm hoping your solution will work.
By "To make this work for Web Services" - did you mean old school SoapHttpProtocol clients?
Because the SoapHttpProtocol class has a built-in EnableDecompression property, which will automatically handle the Compression header and response handling.
Here's an answer I gave to another question on the subject. That questio was asked from the perspective of ADO.NET Data Services, but my answer was purely about WCF.