Calling an ASP.Net web api from a ASP.Net MVC web app. MVC web client is not building the URL properly so getting not found - asp.net-mvc

When I run my web api method using Postman passing in my URL, it works fine - it returns the value of '5' which I expect since the call returns just a single integer. Also at the very bottom I include another method of my web api that I run using Postman and it too works just fine.
http://localhost:56224/api/profileandblog/validatelogin/DemoUser1/DemoUser1Password/169.254.102.60/
However, in the client - an Asp.Net MVC method, when building the URL, it is DROPPING the "/api/profileandblog" part. Note: I'm using "attribute routing" in the web api.
Here is the Asp.Net MVC method to call the web api:
I stop it on this line so I can see the error details: if (result1.IsSuccessStatusCode)
It's INCORRECTLY building the URL as: http://localhost:56224/validatelogin/DemoUser1/DemoUser1Password/169.254.102.60/
It's dropping the: "/api/profileandblog" part that should follow 56224.
So it give's me the Not found.
Why does it drop it? It has the localhost:56224 correct.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SignIn(SignInViewModel signInViewModel)
{
int returnedApiValue = 0;
User returnedApiUser = new User();
DateTime currentDateTime = DateTime.Now;
string hostName = Dns.GetHostName();
string myIpAddress = Dns.GetHostEntry(hostName).AddressList[2].ToString();
try
{
if (!this.IsCaptchaValid("Captcha is not valid"))
{
ViewBag.errormessage = "Error: captcha entered is not valid.";
}
else
{
if (!string.IsNullOrEmpty(signInViewModel.Username) && !string.IsNullOrEmpty(signInViewModel.Password))
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56224/api/profileandblog");
string restOfUrl = "/validatelogin/" + signInViewModel.Username + "/" + signInViewModel.Password + "/" + myIpAddress + "/";
// Call the web api to validate the sign in.
// Sends back a -1(failure), -2(validation issue) or the UserId(success) via an OUTPUT parameter.
var responseTask1 = client.GetAsync(restOfUrl);
responseTask1.Wait();
var result1 = responseTask1.Result;
if (result1.IsSuccessStatusCode)
{
var readTask1 = result1.Content.ReadAsAsync<string>();
readTask1.Wait();
returnedApiValue = Convert.ToInt32(readTask1.Result);
if (returnedApiValue == -2)
{
ViewBag.errormessage = "You entered an invalid user name and/or password";
}
else
{
// I have the 'user id'.
// Continue processing...
}
}
else
{
ModelState.AddModelError(string.Empty, "Server error on signing in. 'validatelogin'. Please contact the administrator.");
}
}
}
}
return View(signInViewModel);
}
catch (Exception)
{
throw;
}
}
Per the suggestion about not having headers, I used another tutorial (https://www.c-sharpcorner.com/article/consuming-asp-net-web-api-rest-service-in-asp-net-mvc-using-http-client/) and it has the code for defining the headers. But it is coded slightly different - using async Task<> on the method definition. I was not using async in my prior version.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SignIn(SignInViewModel signInViewModel)
{
int returnedApiValue = 0;
User returnedApiUser = new User();
DateTime currentDateTime = DateTime.Now;
string hostName = Dns.GetHostName();
string myIpAddress = Dns.GetHostEntry(hostName).AddressList[2].ToString();
try
{
if (!this.IsCaptchaValid("Captcha is not valid"))
{
ViewBag.errormessage = "Error: captcha entered is not valid.";
}
else
{
if (!string.IsNullOrEmpty(signInViewModel.Username) && !string.IsNullOrEmpty(signInViewModel.Password))
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56224/api/profileandblog");
string restOfUrl = "/validatelogin/" + signInViewModel.Username + "/" + signInViewModel.Password + "/" + myIpAddress + "/";
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Call the web api to validate the sign in.
// Sends back a -1(failure), -2(validation issue) or the UserId(success) via an OUTPUT parameter.
HttpResponseMessage result1 = await client.GetAsync(restOfUrl);
if (result1.IsSuccessStatusCode)
{
var readTask1 = result1.Content.ReadAsAsync<string>();
readTask1.Wait();
returnedApiValue = Convert.ToInt32(readTask1.Result);
if (returnedApiValue == -2)
{
ViewBag.errormessage = "You entered an invalid user name and/or password";
}
else
{
// I have the 'user id'.
// Do other processing....
}
}
else
{
ModelState.AddModelError(string.Empty, "Server error on signing in. 'validatelogin'. Please contact the administrator.");
}
}
}
}
return View(signInViewModel);
}
catch (Exception)
{
throw;
}
}
It now has a header but still NOT building the URL properly as it is not including the "/api/profileandblog" part.
Here is the web api and the method being called:
namespace GbngWebApi2.Controllers
{
[RoutePrefix("api/profileandblog")]
public class WebApi2Controller : ApiController
{
[HttpGet]
[Route("validatelogin/{userName}/{userPassword}/{ipAddress}/")]
public IHttpActionResult ValidateLogin(string userName, string userPassword, string ipAddress)
{
try
{
IHttpActionResult httpActionResult;
HttpResponseMessage httpResponseMessage;
int returnValue = 0;
// Will either be a valid 'user id" or a -2 indicating a validation issue.
returnValue = dataaccesslayer.ValidateLogin(userName, userPassword, ipAddress);
httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK, returnValue);
httpActionResult = ResponseMessage(httpResponseMessage);
return httpActionResult;
}
catch (Exception)
{
throw;
}
}
}
}
Here's the network tab of the client browser before I hit the button to fire of the Asp.Net MVC method.
The network tab of the client browser after I hit the button to fire of the Asp.Net MVC method and it fails.
Here's another example of Postman executing another method of my api just fine.

I got it to work by setting this as: client.BaseAddress = new Uri("localhost:56224"); and setting the string restOfUrl = "/api/profileandblog/validatesignin/" + signInViewModel.Username + "/" + signInViewModel.Password + "/" + myIpAddress + "/";

Related

Consuming a Web API in ASP.NET MVC using HttpClient. The response message is not what is sent back to the client from the web api

To consume a Web API in ASP.NET MVC server side I am using 'HttpClient'. HttpClient sends a request to the Web API and receives a response. Then I convert the response data that came from the Web API to a model and then render it into a view.
The problem is when there is an error in the web api, my client is not receiving the custom error message that was sent.
The web api sends a status code = 400 and a ReasonPhrase with my custom message, but when it gets to the client, it is a status code = 500 and the ReasonPhrase = 'Internal Server error'.
Why?
Web api code - the WebApi2Controller method called by the client which calls a data access layer then sends result back to client:
[HttpPost]
[Route("getbloggersinfo/{argsData}/")]
public IHttpActionResult GetBloggersInfo(ArgsToPassToApi argsToPassToApi)
{
IHttpActionResult httpActionResult;
HttpResponseMessage httpResponseMessage;
try
{
BloggerInfoResults bloggerInfoResults = new BloggerInfoResults();
bloggerInfoResults = dataAccessLayer.GetBloggersInfo(argsToPassToApi.UserName, argsToPassToApi.IpAddress);
httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK, bloggerInfoResults);
}
catch (Exception ex)
{
httpResponseMessage = Request.CreateResponse(HttpStatusCode.BadRequest);
httpResponseMessage.ReasonPhrase = ex.Message;
}
httpActionResult = ResponseMessage(httpResponseMessage);
return httpActionResult;
}
The web api code - the data access layer method called by the WebApi2Controller:
public BloggerInfoResults GetBloggersInfo(string userName, string ipAddress)
{
string userFriendlyMessage = "Unable to get the Blogger's info. We have been notified and are working to resolve this. Please do not continue.";
BloggerInfoResults bloggerInfoResults = new BloggerInfoResults();
SqlDataReader bloggerInfoDataReader = null;
try
{
dbFunc.OpenDB();
SqlCommand cmd = new SqlCommand("dbo.GetBloggersInfo", dbFunc.objConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#a_UserName", userName);
cmd.Parameters.AddWithValue("#a_IpAddress", ipAddress);
bloggerInfoDataReader = cmd.ExecuteReader();
while (bloggerInfoDataReader.Read())
{
bloggerInfoResults.UserId = Convert.ToInt32(bloggerInfoDataReader["UserId"]);
bloggerInfoResults.UserName = bloggerInfoDataReader["UserName"].ToString();
bloggerInfoResults.HasProfileSwitch = Convert.ToBoolean(bloggerInfoDataReader["HasProfileSwitch"]);
}
return bloggerInfoResults;
}
catch (SqlException sqlex)
{
if (sqlex.Message.Contains("Critical"))
{
// A "critical" error coming from the stored procedure.
currentDateTime = DateTime.Now;
sendAlertEmailResult = SendAlertEmailToStaff(currentDateTime, userName, ipAddress);
if (sendAlertEmailResult == "")
{
// The alert email was sent successfully.
// Throw - for setting the UI. Send a user friendly message.
throw new Exception(userFriendlyMessage);
}
else
{
// Not sent successfully. I have no choice but to send the verbose message as it was NOT stored in the error log and I will need to see it
// when debugging.
// Throw - for setting the UI.
throw new Exception(criticalErrorPrepend + "Error in DataAccessLayer/GetBloggersInfo(). Sending an alert email for the initial sql exception error: " + sqlex.Message + ". Now getting this error: " + sendAlertEmailResult);
}
}
else
{
// Not coming from the stored procedure. Like if the stored procedure above was not named properly, does not exist, parameter missing, etc.
errorMessage = "Sql Exception Error in DataAccessLayer/GetBloggersInfo(). Using 'GetBloggersInfo' s/p. Error: " + sqlex.Message;
// Log the error and send an alert email.
currentDateTime = DateTime.Now;
processErrorLogAndSendAlertEmailResult = ProcessErrorLogAndSendAlertEmail(currentDateTime, userName, errorMessage, additionalInfoForLog, ipAddress);
if (processErrorLogAndSendAlertEmailResult != "")
{
// Throw - for setting the UI.
throw new Exception(criticalErrorPrepend + "Error in DataAccessLayer/GetBloggersInfo(). Using 'GetBloggersInfo' s/p. Logging the initial sql exception error: " + sqlex.Message + ". Now getting this error: " + processErrorLogAndSendAlertEmailResult);
}
else
{
// Throw - for setting the UI. Send a user friendly message.
throw new Exception(userFriendlyMessage);
}
}
}
catch (Exception ex)
{
errorMessage = "Error in DataAccessLayer/GetBloggersInfo(). Using 'GetBloggersInfo' s/p. Error: " + ex.Message;
// Log the error and send an alert email.
currentDateTime = DateTime.Now;
processErrorLogAndSendAlertEmailResult = ProcessErrorLogAndSendAlertEmail(currentDateTime, userName, errorMessage, additionalInfoForLog, ipAddress);
if (processErrorLogAndSendAlertEmailResult != "")
{
// Throw - for setting the UI.
throw new Exception(criticalErrorPrepend + "Error in DataAccessLayer/GetBloggersInfo(). Using 'GetBloggersInfo' s/p. Logging the initial error: " + ex.Message + ". Now getting this error: " + processErrorLogAndSendAlertEmailResult);
}
else
{
// Throw - for setting the UI. Send a user friendly message.
throw new Exception(userFriendlyMessage);
}
}
finally
{
if (bloggerInfoDataReader != null)
{
// Close the reader.
bloggerInfoDataReader.Close();
}
// Close the database.
dbFunc.CloseDB();
}
}
The custom message being thrown (throw new Exception (....)) from the data access layer method back to the WebApi2Controller method (my custom message):
The error being sent to the client from the WebApi2Controller (a status code = 400 and ReasonPhrase with my custom message):
The client code which calls the web api controller method using httpclient:
public async Task<BloggerInfoResults> GetBloggersInfo(string userName, string webApiUrl, string myIpAddress)
{
try
{
BloggerInfoResults bloggerInfoResults = new BloggerInfoResults();
ArgsToPassToApi argsToPassToApi = new ArgsToPassToApi();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(webApiUrl);
argsToPassToApi.UserName = userName;
argsToPassToApi.IpAddress = myIpAddress;
string restOfUrl = "/api/profileandblog/getbloggersinfo/" + argsToPassToApi + "/";
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string payLoad = JsonConvert.SerializeObject(argsToPassToApi);
HttpContent argsData = new StringContent(payLoad, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(restOfUrl, argsData);
if (response.IsSuccessStatusCode)
{
var entry = response.Content.ReadAsStringAsync().Result;
bloggerInfoResults = JsonConvert.DeserializeObject<BloggerInfoResults>(entry);
}
else
{
// The web api sent an error response.
bloggerInfoResults.ApiErrorMessage = "Web api error. Reason: " + response.ReasonPhrase;
}
// Return the model.
return bloggerInfoResults;
}
}
catch (Exception)
{
throw;
}
}
The error being received (a status code = 400 and the ReasonPhrase = 'Internal Server error'.):

MVC: how to call a non-async method from within a method that has async Task<ActionResult> as the return type

MVC web app calling methods in a MVC web api.
I have an async method which executes another async method - GetMultiSelections(...).
Both call out to a web api.
They work fine.
However, I added in some new code - the foreach after the 1st method - GetMultiSelections(...).
I encountered an error. So I now want to call another web api method to write the error to a log. It's a non-async method that does not return anything as I don't want anything coming back. (or should I?)
I do this in the 1st Catch. It executes the non-async method but does not go into the web api. I step threw it but it never actually goes into the web api method. I have a break point in the web api and it does not get there.
Is the async preventing it? If so, how to I get the non-async to be executed?
In the non-async method and does the call to the web api - just does not get in there:
The api method - it does not get here:
Returned from the non-async method - and throws the error as expected:
The async method which executes another async method. The both do a call to the web api.:
[HttpGet]
public async Task<ActionResult> GetUserProfile()
{
UserProfileForMaintVM userProfileForMaintVM = new UserProfileForMaintVM();
try
{
List<UserProfileHoldMulti> userProfileHoldMulti = new List<UserProfileHoldMulti>();
// Get all the user's multi-selections and the ones he/she did not select.
userProfileHoldMulti = await GetMultiSelections(Session["UserName"].ToString(), Convert.ToInt32(Session["UserId"]));
foreach (var hold in userProfileHoldMulti)
{
switch (hold.ProfileCategoryId)
{
case 25:
// Instantiate a new UserProfileMulti25.
UserProfileMulti25 userProfileMulti25 = new UserProfileMulti25
{
SelectionId = hold.SelectionId,
ProfileCategoryId = hold.ProfileCategoryId,
Description = hold.Description,
SelectedSwitch = hold.SelectedSwitch
};
// Add the multi list to the model's multi list.
userProfileForMaintVM.UserProfileMultiList25.Add(userProfileMulti25);
break;
}
}
}
catch (Exception ex)
{
// Call the web api to process the error.
ProcessClientError(Session["UserName"].ToString(), ex.Message, "From method: GetUserProfile. processing multi-selections");
throw;
}
if ((string)#Session["HasProfileSwitch"] == "False")
{
return View("UserProfileMaint", userProfileForMaintVM);
}
else
{
try
{
string hostName = Dns.GetHostName();
string myIpAddress = Dns.GetHostEntry(hostName).AddressList[2].ToString();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56224");
string restOfUrl = "/api/profileandblog/getuserprofile/" + Session["UserName"] + "/" + myIpAddress + "/" + Session["UserId"];
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage result = await client.GetAsync(restOfUrl);
if (result.IsSuccessStatusCode)
{
var userResponse = result.Content.ReadAsStringAsync().Result;
userProfileForMaintVM.UserProfileSingleVM = JsonConvert.DeserializeObject<UserProfileSingleVM>(userResponse);
}
else
{
ViewBag.errormessage = "Server error on getting the active userProflie. UserId: " + Session["UserId"] + ". Method: 'GetUserProfile'. Please contact the administrator.";
}
return View("UserProfileMaint", userProfileForMaintVM);
}
}
catch (Exception)
{
throw;
}
}
}
The non-async method:
public void ProcessClientError(string userName, string errorMessage, string additionalInfo)
{
try
{
string hostName = Dns.GetHostName();
string myIpAddress = Dns.GetHostEntry(hostName).AddressList[2].ToString();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56224");
string restOfUrl = "/api/profileandblog/processclienterror/" + Session["UserName"] + "/" + errorMessage + additionalInfo + myIpAddress + "/";
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.GetAsync(restOfUrl);
}
}
catch (Exception)
{
throw;
}
}
GetAsync/PostAsync doesn't necessarily need to call an async method. The GetAsync/PostAsync are the actual async methods wherein once it is called, you have the option to wait for it to finish.
The error I'm seeing is you're calling the webapi with GetAsync but in your screenshot the web method ProcessClientError is [HttpPost].
Change ProcessClientError data annotation to [HttpGet].
Hmm, upon checking again, the url you're trying to access might not match the one you provided in your route. It's missing some slashes /.
your current:
string restOfUrl = "/api/profileandblog/processclienterror/" + Session["UserName"] + "/" + errorMessage + additionalInfo + myIpAddress + "/";
possible fix:
string restOfUrl = "/api/profileandblog/processclienterror/" + Session["UserName"] + "/" + errorMessage + "/" + additionalInfo + "/" + myIpAddress + "/";
If that still doesnt work, try to url encode the parameters with slashes /.
string restOfUrl = "/api/profileandblog/processclienterror/" + Session["UserName"] + "/" + errorMessage + "/" + additionalInfo + "/" + Url.Encode(myIpAddress) + "/";

How to get oauth access token in console without authentication prompt

I want to oauth authentication like
Login using Google OAuth 2.0 with C#
But i don't want to authentication prompt popup
i want to get token directly without popup..
public ActionResult CodeLele()
{
if (Session.Contents.Count > 0)
{
if (Session["loginWith"] != null)
{
if (Session["loginWith"].ToString() == "google")
{
try
{
var url = Request.Url.Query;
if (url != "")
{
string queryString = url.ToString();
char[] delimiterChars = { '=' };
string[] words = queryString.Split(delimiterChars);
string code = words[1];
if (code != null)
{
//get the access token
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
webRequest.Method = "POST";
Parameters = "code=" + code + "&client_id=" + googleplus_client_id + "&client_secret=" + googleplus_client_sceret + "&redirect_uri=" + googleplus_redirect_url + "&grant_type=authorization_code";
byte[] byteArray = Encoding.UTF8.GetBytes(Parameters);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = byteArray.Length;
Stream postStream = webRequest.GetRequestStream();
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
WebResponse response = webRequest.GetResponse();
postStream = response.GetResponseStream();
StreamReader reader = new StreamReader(postStream);
string responseFromServer = reader.ReadToEnd();
GooglePlusAccessToken serStatus = JsonConvert.DeserializeObject<GooglePlusAccessToken>(responseFromServer);
if (serStatus != null)
{
string accessToken = string.Empty;
accessToken = serStatus.access_token;
if (!string.IsNullOrEmpty(accessToken))
{
// This is where you want to add the code if login is successful.
// getgoogleplususerdataSer(accessToken);
}
else
{ }
}
else
{ }
}
else
{ }
}
}
catch (WebException ex)
{
try
{
var resp = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
dynamic obj = JsonConvert.DeserializeObject(resp);
//var messageFromServer = obj.error.message;
//return messageFromServer;
return obj.error_description;
}
catch (Exception exc)
{
throw exc;
}
}
}
}
}
return Content("done");
}
public ActionResult JeClick()
{
var Googleurl = "https://accounts.google.com/o/oauth2/auth?response_type=code&redirect_uri=" + googleplus_redirect_url + "&scope=https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile&client_id=" + googleplus_client_id;
Session["loginWith"] = "google";
return Redirect(Googleurl);
}
The credentials window (popup) is how you ask the user if you can access their data. There is no way to get access to a users data without asking the user first if you may access their data. That is how Oauth2 works.
If you are accessing your own data then you can use something called a Service account. Service accounts are pre authorized. You can take the service account and grant it access to your google calendar, you could give it access to a folder in Google drive. Then you can authenticate using the service account. Service accounts are like dummy users.
My article about service accounts: Google Developer service account

Create to database using web api

I am trying to insert a new entry in my database using web api. I have two web projects: one is a UI project where all the user interaction will occur and the other is a services project which will handle all interactions with my database.
Below is my post method that will take in form data for creating a new team.
// POST: Api/Team/Create
[HttpPost]
public ActionResult Create(Team team)
{
try
{
if (ModelState.IsValid)
{
HttpEndPointContext httpEndPoint = new HttpEndPointContext()
{
AuthenticationMethod = HttpAuthenticationMethods.None,
Ssl = false,
HttpMethod = HttpMethod.Post,
Path = "localhost:32173/api/team/",
QueryStrings = null,
PayloadData = SerializationHelper.Current.Serialize(team.ToString(), SerializationTypes.Xml)
};
IProcessResult result = HttpConnectionManager.Current.SendMessage(httpEndPoint);
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
And this is my method for dealing with my PayloadStream/PayloadData attribute in the above method:
private void StreamPayload(HttpWebRequest webRequest, HttpEndPointContext httpEndPointContext)
{
if (httpEndPointContext.HttpMethod == new HttpMethod("GET"))
return;
//TODO: FIX MAYBE .... sometimes we want to post body with GET.
//Stream vs string
if (httpEndPointContext.PayloadStream == null)
{
//Wrap with SOAP Envelope and method if defined in SoapDefinition
string data = httpEndPointContext.PayloadData ?? String.Empty;
if (httpEndPointContext.SoapDefinition != null)
{
//If parameters is set, clear existing payload data.
data = String.Empty;
if (httpEndPointContext.SoapDefinition.Parameters != null)
foreach (var parameter in httpEndPointContext.SoapDefinition.Parameters)
{
data += String.Format("<{0}>{1}</{0}>", parameter.Key, parameter.Value);
}
data = String.Format("<s:Envelope xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'>" +
"<s:Body><{0} xmlns='{2}'>" +
"{1}</{0}></s:Body></s:Envelope>",
httpEndPointContext.SoapDefinition.SoapMethod, data,httpEndPointContext.SoapDefinition.SoapGlobalKey);
}
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(data);
httpEndPointContext.PayloadStream = new MemoryStream(byteArray);
}
using (Stream requestStream = webRequest.GetRequestStream())
{
StreamHelper.Current.CopyStreams(httpEndPointContext.PayloadStream, requestStream);
requestStream.Close();
}
}
And the code for getting the server response. I'm currently getting an Internal Server (500) Error. Not sure why.
public IProcessResult SendMessage(HttpEndPointContext httpEndPointContext)
{
HttpWebRequest webRequest = CreateWebRequest(httpEndPointContext);
StreamPayload(webRequest, httpEndPointContext);
IProcessResult result = GetWebResponse(webRequest, httpEndPointContext);
return result;
}
private IProcessResult GetWebResponse(HttpWebRequest webRequest, HttpEndPointContext httpEndPointContext)
{
//Get Response
WebResponse response;
IProcessResult result = new ProcessResult(Statuses.Success);
try
{
response = webRequest.GetResponse();
}
catch (System.Net.WebException ex)
{
//Do exception handling. Still get the response for 500s etc.
result.Error.Exception = ex;
result.Status = Constants.Statuses.FailedUnknown;
result.ResponseCodeDescription = ex.Status.ToString();
result.ResponseCode = ex.Status.ToString();
result.Error.ErrorCode = ex.Status.ToString();
response = ex.Response;
//The error did not have any response, such as DNS lookup.
if (response == null)
return result;
}
try
{
//Get the response stream.
Stream responseData = response.GetResponseStream();
if (responseData == null)
throw new CoreException("No Response Data in GetWebResponse.",
"No Response Data in GetWebResponse. EndPoint:{0}", httpEndPointContext.ToString());
// Open the stream using a StreamReader for easy access.
var reader = new StreamReader(responseData);
// Read the content.
result.ResponseData = reader.ReadToEnd();
}
finally
{
response.Close();
}
result.ResponseCode = ((int)((HttpWebResponse)response).StatusCode).ToString();
result.ResponseCodeDescription = ((HttpWebResponse) response).StatusDescription;
return result;
}
And finally, my method for inserting to the database, found in my services project:
//POST api/controller/5
public IProcessResult Insert(Team team)
{
return TeamBusinessManager.Current.Insert(SecurityManager.Current.ConnectionContext, new Team());
}
I'm confused as to why I'm getting the 500 error. I'm not sure if it's the PayloadData attribute in my POST method or is it something wrong with my method in my services project.

Post message from ASP.NET app to Twitter

I am using very simple code to post message in twitter. The code is as given below:
public void UpdateStatus(string username, string password, string tweetMsg)
{
byte[] bytes = System.Text.Encoding.ASCII.GetBytes("status=" + tweetMsg);
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://twitter.com/statuses/update.xml");
request.Credentials = new NetworkCredential(username, password);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ServicePoint.Expect100Continue = false;
string statusUpdate = string.Empty;
using (StreamWriter sw = new StreamWriter(request.GetRequestStream()))
{
statusUpdate = "status=" + System.Web.HttpUtility.UrlEncode(tweetMsg);
sw.Write(statusUpdate);
}
using (HttpWebResponse resp = (HttpWebResponse) request.GetResponse())
{
// Handle response here
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
Console.WriteLine(sr.ReadToEnd());
}
}
}
catch (WebException ex)
{
Console.WriteLine("Web Error: {0}", ex.Message);
if (ex.Response != null)
{
HttpWebResponse r = (HttpWebResponse)ex.Response;
using (StreamReader esr = new StreamReader(r.GetResponseStream()))
{
Console.WriteLine("Error: {0}", esr.ReadToEnd());
}
}
}
catch (IOException ex)
{
Console.WriteLine("I/O Error: {0}", ex.Message);
}
}
I am not sure why this code is not working. I am getting the exception
The remote server returned an error: (401) Unauthorized.
But, whichever site I am referring, everywhere I find that people are able to post their messages using the same code.
Can anybody please tell me what I am missing in this code? The site that I referred for this code is http://www.dreamincode.net/forums/topic/120468-twitter-api-posting-status/
Thanks in advance....
Hari
The Twitter API no longer supports Basic Auth for authentication. You need to switch to OAuth which uses tokens instead of passwords.
Twitter's guide to transitioning from Basic Auth to OAuth
OAuth homepage

Resources