How to call web API in WPF 4.0 - asp.net

I wants to call web API in my WPF 4.0 application , where API receive request in JSON format & send response in JSON format.
I got the solution to call web API in WPF 4.5 from here http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-wpf-application
but i want same kind of solution in WPF 4.0
please help me

you have to install the NuGet package manager and the Http client libraries. This should work:
http://www.codeproject.com/Articles/611176/CallingplusASP-NetplusWebAPIplususingplusHttpClien

public T CallWebAPi<T>(string userName, string password, Uri url, out bool isSuccessStatusCode)
{
T result = default(T);
using (HttpClient client = new HttpClient())
{
client.BaseAddress = url;
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password))));
HttpResponseMessage response = client.GetAsync(url).Result;
isSuccessStatusCode = response.IsSuccessStatusCode;
var JavaScriptSerializer = new JavaScriptSerializer();
if (isSuccessStatusCode)
{
var dataobj = response.Content.ReadAsStringAsync();
result = JavaScriptSerializer.Deserialize<T>(dataobj.Result);
}
else if (Convert.ToString(response.StatusCode) != "InternalServerError")
{
result = JavaScriptSerializer.Deserialize<T>("{ \"APIMessage\":\"" + response.ReasonPhrase + "\" }");
}
else
{
result = JavaScriptSerializer.Deserialize<T>("{ \"APIMessage\":\"InternalServerError\" }");
}
}
return result;
}

Related

Sending and getting http headers

I am working on an asp.net Web API and I have an web application that consumes this api.
Right now it is working perfectly since I don't have the [Authorize] part on my api controller.
So, if I want to secure this api, my web application will not be able anymore to fetch data from the API because it is not authorized.
So how can I send the token generated from my API to my web app and to allow it to fetch the needed data?
-I am using postman for testing my app;
-my api return jwt token;
-I am not really familiar with http headers.
My consuming web application controller :
public ActionResult Index()
{
IEnumerable<OperatorClass> OperatorObject = null;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://localhost:44304/api/");
var ApiOpController = client.GetAsync("data");
client.DefaultRequestHeaders.Add("Authorization", "Bearer"+"");
ApiOpController.Wait();
var resultDisplay = ApiOpController.Result;
if (resultDisplay.IsSuccessStatusCode)
{
var readTable = resultDisplay.Content.ReadAsAsync<IList<OperatorClass>>();
readTable.Wait();
OperatorObject = readTable.Result;
}
else
{
OperatorObject = Enumerable.Empty<OperatorClass>();
ModelState.AddModelError(String.Empty, "No records found");
}
return View(OperatorObject);
}
My web API controller
[Authorize]
[HttpGet]
public IHttpActionResult GetOperators()
{
SchoolEntity myEntity = new SchoolEntity ();
IList<OperatorClass> OperatorObject = myEntity.Operator.Include("Operator").Select(x => new OperatorClass()
{
name = x.name,
lastname = x.lastname,
mobile = x.mobile,
username = x.username,
password = x.password
}).ToList<OperatorClass>();
return Ok(OperatorObject);
}
string token = <Your token>
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
this should work for you.
To be able to use your MVC controller, you need to store the token when it returns.
One way to do it is to store it using Session.
Assuming you are using sign in to get the token, anytime you sign in successfully you can store the token using the session. See below.
//For brevity after successful login
string myToken = <token returned from api>
HttpContext.Session.SetString("token", myToken);
//other codes
then you can use this in all of your controllers.
public async Task<ActionResult> Index()
{
IEnumerable<OperatorClass> OperatorObject = null;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://localhost:44304/api/");
//note here
var token = HttpContext.Session.GetString("token");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
//ApiOpController.Wait();
var resultDisplay = await client.GetAsync("data");
if (resultDisplay.IsSuccessStatusCode)
{
var readTable = await resultDisplay.Content.ReadAsAsync<IList<OperatorClass>>();
//readTable.Wait();
OperatorObject = readTable;
}
else
{
OperatorObject = Enumerable.Empty<OperatorClass>();
ModelState.AddModelError(String.Empty, "No records found");
}
return View(OperatorObject);
}

Redirect from one WebAPI to an another WebAPI and getting the response

I want to create lets say a master/core api.Want to check for a certain parameter value and redirect to a an external api hosted in the same server.I have an api with uri http://hello.test.com/auth which takes two auth params Username and Password.Now i add a third parameter lets say Area.
{
"Username":"jason",
"Password":"bourne",
"Area":"mars"
}
Now coming to the master api, if with this uri for example http://master.test.com/v1/mster and i pass Username, Password and Area,and if the Area has value of lets say "mars" it should call the external mars api having uri http://mars.test.com/auth ,do the auth the process and return the response in the master api.is this possible?
With my /auth api i have this controller returning the response :
[HttpPost]
[Route(ApiEndpoint.AUTH)]
public HttpResponseMessage Auth(Login authBDTO)
{
if (!ModelState.IsValid)
return Request.CreateResponse(HttpStatusCode.BadRequest, ModelState);
using (AccountBusinessService accountService = new AccountBusinessService())
{
var result = accountService.Auth(authBDTO);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
}
Any Help Appreciated.Couldnt find this exact scenario in here.Sorry if too naive.
Found a workaround.This did the work.
[Route(ApiEndpoint.SAS)]
public IHttpActionResult esp(Login auth)
{
if (auth.Coop == "PMC")
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:60069/api/v1/auth");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
Username = auth.UserName,
Password = auth.Password
});
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(result);
obj.BaseUrl = "http://localhost:60069/api/v1";
return Ok(obj);
}
}

ASP.NET Boilerplate Auth from Windows Phone 8.1 - bearer token

I'm using asp.net boilerplate for my website. There I have standard authentication from aspnetboilerplate/module-zero(OWIN).
But now I need athentication for my windows phone app(wp8.1)
I was trying configure my application for authorization with bearer but I failed..
How configurate asp.net boilerplate application for my windows phone app auth?
In windows phone app I send post to my web api like this:
public static async Task<TokenResponseModel> GetBearerToken(string siteUrl, string Username, string Password)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(siteUrl);
client.DefaultRequestHeaders.Accept.Clear();
HttpContent requestContent = new StringContent("grant_type=password&username=" + Username + "&password=" + Password, Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage responseMessage = await client.PostAsync("Token", requestContent);
if (responseMessage.IsSuccessStatusCode)
{
string jsonMessage;
using (Stream responseStream = await responseMessage.Content.ReadAsStreamAsync())
{
jsonMessage = new StreamReader(responseStream).ReadToEnd();
}
TokenResponseModel tokenResponse = (TokenResponseModel)JsonConvert.DeserializeObject(jsonMessage, typeof(TokenResponseModel));
return tokenResponse;
}
else
{
return null;
}
}
But what should I do in WebApi? How auth and next response bearer and how auth in next step using bearer when on class i have [AbpAuthorize]?
This now documented and implemented in module zero template
code:
In module WebApi:
Configuration.Modules.AbpWebApi().HttpConfiguration.Filters.Add(new HostAuthenticationFilter("Bearer"));
In controller WebApi:
[HttpPost]
public async Task<AjaxResponse> Authenticate(LoginModel loginModel)
{
CheckModelState();
var loginResult = await GetLoginResultAsync(
loginModel.UsernameOrEmailAddress,
loginModel.Password,
loginModel.TenancyName
);
var ticket = new AuthenticationTicket(loginResult.Identity, new AuthenticationProperties());
var currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
return new AjaxResponse(OAuthBearerOptions.AccessTokenFormat.Protect(ticket));
}
documentation: http://aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template#token-based-authentication

httpclient postasync windows phone 8.1 universal app second call 404 error

I have a problem with httpclient in a universal windows phone 8.1 app.
I've been looking but i have not a valid solution in any post.
the problem is that, when i call to the web service first time runs correctly, but when i call it, second or third time, gives me an error 404.
Until you restart the application will not run again.
i need to send that data in a post function cause i want to send a xml formated to string.
my code is very simple:
var handler = new HttpClientHandler
{
Credentials = new
NetworkCredential("user", "pass", "domain")
};
using (var client = new HttpClient(handler))
{
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("XMLText", XMLText),
new KeyValuePair<string, string>("param1", "textParam1")
});
HttpResponseMessage response = new HttpResponseMessage();
response = await client.PostAsync(URL, formContent);
var responseString = response.Content.ReadAsStringAsync().Result;
MessageDialog msgbox = new MessageDialog(responseString);
await msgbox.ShowAsync();
}
and my web service is even simpler:
[WebMethod]
public String SetEnvioXML(string XMLText, string param1)
{
return XMLText;
}
Any solution?
Sorry for my english and thaks for all!
Any help is welcome!
Try to use the below code may be this will works,
First try to run this on Google Rest Client or Post Man
HttpRequestMessage httpRequest = new HttpRequestMessage();
httpRequest.Method = HttpMethod.Post;
httpRequest.RequestUri = URL;
httpRequest.Content = formContent ;
response =await client.SendAsync(httpRequest);
Finally i found the solution, i changed the autentication from windows autentication, to basic autentication in IIS, setting the domain in it. Then i try that:
client = new HttpClient();
var authHeader = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", "usuario", "contraseƱa"))));
client.DefaultRequestHeaders.Authorization = authHeader;
And it rules. Thanks for all of your answers!

REST WEBAPI POST method with parameters not being called

I have built a REST API with a controller having a POST method with 4 parameters like this-
[HttpPost]
public void SaveSession([FromBody] string userId, [FromBody] DateTime issueDateTime, [FromBody] string browserType, [FromBody] string salt)
{
// Params need to be changed
_sessionService.SaveSession(userId, issueDateTime, browserType, salt);
}
How should I POST data on the client side, I mean what should be the format of the data to be sent?
I tried this format-
"userId=abc&DateTime=someDatetime&browserType=somebrowser&salt=somesalt"
Its not working if I try this, The web service method is not even being called
Could anyone tell me the correct format?
EDIT:
Here is how I am calling the API-
const string endPoint = #"http://localhost:85/session/Test";
var postData = "userId=abc&DateTime=someDatetime&browserType=somebrowser&salt=somesalt"
var request = (HttpWebRequest) WebRequest.Create(EndPoint + parameters);
request.Method = "POST";
request.ContentLength = 0;
request.ContentType = "application/x-www-form-urlencoded";
if (!string.IsNullOrEmpty(postData) && Method == HttpVerb.POST)
{
var encoding = new UTF8Encoding();
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(postData);
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
}
using (var response = (HttpWebResponse) request.GetResponse())
{
var xmlDoc = new XmlDocument();
if (response.StatusCode != HttpStatusCode.OK)
{
var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
throw new ApplicationException(message);
}
// grab the response
var responseStream = response.GetResponseStream();
if (responseStream != null)
{
xmlDoc.Load(responseStream);
}
return (xmlDoc);
}
Thanks!
I assume routing has been properly configured.
Said so.... DateTime parameter in the controller method has been named "issueDateTime" while within the request has been named "DateTime".
I got to know, what mistake I was doing. I was sending 4 parameters in a WebService method. We can only send one parameter while calling a web service method. If you want to send multiple data, just send it as an object. Like this -
[HttpPost]
public void SaveSession([FromBody] Values value)
{
var userId = values.userId,
var issueDateTime= values.issueDateTime,
var browserType= values.browserType,
var salt= values.salt,
_sessionService.SaveSession(userId, issueDateTime, browserType, salt);
}

Resources