asp.net web api server side talking back to angularjs - c#

I am developing web site in angular js, .net web api 2, visual studio 2013, and c#.
My url navigation is purely driven by angularjs.
Upon password reset, I email a link to the user that looks like this:
http://localhost:3458/api/Account/ResetPasswordEmail?userId=xxxxxxxxxxxxxxxx9049a8e3-fb90-400a-b73e-78cadc16ae40&code=BVEssssssssssssssssssswT9FsJ3QncMLaPclhLZVUHpHifX8wmG7f3ZrlxDlwkkmcMNccdXz8jdEuGdHM1FJ4WdBu9Yxu9VG43DxamBrasdfasdfasdfbdasdfvgGrqwJxRoJ%2FSCDkOrbV3RupmUaoTgRmebwb1ymBZwkd891G3q6SW%2F%2FTDwOQ7qrkzkAUYtjcwd%2FTH4jNNCzIYmMXF%2BkMF26mBM4Osgc%2Bi%2BO0So41%2Fpp3yK%2BDvEtNCPA%3D%3D&newPassword=xxxxxxxxxx
User receives the email and clicks on the link..
On the server side, following code is executed:
//
// GET: /Account/ResetPasswordEmail
// GET api/Account/ResetPasswordEmail
[Route("ResetPasswordEmail", Name = "ResetPasswordEmail")]
[AllowAnonymous]
public HttpResponseMessage GetResetPasswordEmail(string userId, string code, string newPassword)
{
string errmsg = string.Empty;
try
{
if (userId == null || code == null)
{
errmsg = "Either email address or other necessary parameter is null.";
throw new Exception(errmsg);
}
var result = UserManager.ResetPasswordAsync(userId, code, newPassword);
var response = Request.CreateResponse(HttpStatusCode.Moved);
string fullyQualifiedUrl = Request.RequestUri.GetLeftPart(UriPartial.Authority);
response.Headers.Location = new Uri(fullyQualifiedUrl);
return response;
}
catch(Exception ex)
{
return null;
}
}
The password is reset successfully...
However ...
I want to give visual feedback on the web page that password was or was not reset successfully. In other words, in this situation how would my web api talk back to the angular js code to render a UI. Would I resort to some sort of asp.net mvc type of code?

In your website project's controller folder need to add action which where user will land from email
Then call api from that action if success then return success view in that action

Related

How can I control this response coming from C# backend project?

This is my first question here so I am very excited. :)
I am developing a car rental project with C# for backend and Angular for front end. When I try to register a new user with data of an existing user, I get attached response in Postman. The controller in backend sends a Badrequest with a message "User already exists!". I tried to control this at Front End side in Angular. What I would like to do is, just to recognize this error with an IF statement and show this message "User already exists!" on the web page with a toastr service. However, I can not detect it in Angular at all. Can you please help me? How can I take this backend response into control in Angular? Thanks in advance for your help!
Code in Controller:
[HttpPost("register")]
public ActionResult Register(UserForRegisterDto userForRegisterDto)
{
var userExists = _authService.CheckIfUserExists(userForRegisterDto.Email);
if (!userExists.Success)
{
return BadRequest(userExists.Message);
}
var registerResult = _authService.Register(userForRegisterDto, userForRegisterDto.Password);
var result = _authService.CreateAccessToken(registerResult.Data);
if (result.Success)
{
return Ok(result.Data);
}
return BadRequest(result.Message);
}
To return a specific response code with a message from backend:
return new HttpStatusCodeResult(errorCode, "Message");
Make sure the method in the controller is type ActionResult, not ViewResult.

"An item with the same key has already been added." while adding "/&output=embed"

Implementing a MVC application in C# with Evernote API. I am using the AsyncOAuth.Evernote.Simple nuget package. Receiving and error of Refused to display in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN', when trying to navigate to URL that fires off the OAuth process.
There is an iframe that is surrounding my code (which can not be altered). After implementing the code an error is generated: "An item with the same key has already been added". This error occurs when requestToken is hit for the first time.
Below is my EvernoteProviderController.cs
public class EvernoteProviderController : Controller
{
// Initialize Oauth call, pulling values from web.config
EvernoteAuthorizer EvernoteAuthorizer = new EvernoteAuthorizer(ConfigurationManager.AppSettings["Evernote.Url"] + "&output=embed", ConfigurationManager.AppSettings["Evernote.Key"], ConfigurationManager.AppSettings["Evernote.Secret"]);
// This method makes the original call to Evernote to get a token so that the user can validate that they want to access this site.
public ActionResult Authorize(bool reauth = false)
{
// Allow for reauth
if (reauth)
SessionHelper.Clear();
// First of all, check to see if the user is already registered, in which case tell them that
if (SessionHelper.EvernoteCredentials != null)
return Redirect(Url.Action("AlreadyAuthorized"));
// Evernote will redirect the user to this URL once they have authorized your application
var callBackUrl = Request.Url.GetLeftPart(UriPartial.Authority) + Url.Action("ObtainTokenCredentials");
// Generate a request token - this needs to be persisted till the callback
var requestToken = EvernoteAuthorizer.GetRequestToken(callBackUrl);
// Persist the token
SessionHelper.RequestToken = requestToken;
// Redirect the user to Evernote so they can authorize the app
var callForwardUrl = EvernoteAuthorizer.BuildAuthorizeUrl(requestToken);
return Redirect(callForwardUrl);
}
// This action is the callback that Evernote will redirect to after the call to Authorize above
public ActionResult ObtainTokenCredentials(string oauth_verifier)
{
// Use the verifier to get all the user details we need and store them in EvernoteCredentials
var credentials = EvernoteAuthorizer.ParseAccessToken(oauth_verifier, SessionHelper.RequestToken);
if (credentials != null)
{
SessionHelper.EvernoteCredentials = credentials;
return Redirect(Url.Action("Authorized"));
}
else
{
return Redirect(Url.Action("Unauthorized"));
}
}
// Show the user if they are authorized
public ActionResult Authorized()
{
return View(SessionHelper.EvernoteCredentials);
}
public ActionResult Unauthorized()
{
return View();
}
//Redirects user if already authorized, then dump out the EvernoteCredentials object
public ActionResult AlreadyAuthorized()
{
return View(SessionHelper.EvernoteCredentials);
}
public ActionResult Settings()
{
return View();
}
}
Has anyone had this issue with iframes before or knows in what direction I should go? I am trying to embed my URL endpoint so I can get around the iframe error.
Solved the error.
A bit of back story:
The purpose of this application was to provide the OAuth page where a user can sign up which will generate a AuthToken and NotebookURL, (both are needed with Evernote API to pull read/write Notes - which is Evernote's object).
The previous behavior (before I changed it), was when a user clicked on the link - they will be redirected (in the same window) to the Evernote OAuth page.
This caused issues for me, because I had another wrapper around my code (iframe). So in non-technical terms, I had a iframe within an iframe within an iframe.
Workaround
Created a JavaScript code which would add an click event listener, which would then create a popup using window.open.
$("#btnStart").click(function () {
myWindow = window.open(baseUrl + "/EvernoteProvider/Authorize", '_blank', 'width=500,height=500, scrollbars=no,resizable=no');
myWindow.focus();
});

"Cannot redirect after http headers have been sent", but Response.Redirect doesn't work if I remove RedirectToAction

So I'm trying to recycle some code that was for a 'code behind' patterned .NET app for my MVC app and the Authenticate class they used. How the SignInController's Index method based on the code they gave me is supposed to work is to call an Authenticate class method in the else if which gets a token and redirects back to the Index method at which point since the app now has a token, it goes into the first if conditional and a different method in the aforementioned Authenticate validates the token. Since users will not start out with a token, the else if will always be dove into first.
In order to soothe the "Not all code paths return a value" error I have to add a return statement at the end of the else if clause and an else clause. However, if I return null Index doesn't get redirected to as confirmed by breakpoints. However, if I do return RedirectToAction("Index", "SignIn"); I get an error about "Cannot redirect after HTTP headers have been sent" which I suspect is because the Redirect call from the Authenticate class hasn't been completed yet. However I'm at odds as to how to remedy situation as either return value fails to redirect the web app back to Index...
Original "look behind" styled .NET code that I'm trying to recycle from a colleague's app:
if (string.IsNullOrEmpty(HttpContext.Current.User.Identity.Name) && HttpContext.Current.Request.QueryString["Token"] != null)
{
// we’ve got a token, they must have logged in .. double-check the token
string ssoToken = HttpContext.Current.Request.QueryString["Token"].ToString();
string userRoles = string.Empty;
if (Authenticate.ValidateSSOToken(ssoToken, out userRoles))
{
string userName = HttpContext.Current.User.Identity.Name;
((BaseApplicationPage)(this.Page)).CurrentSecurity.SetUser(userName, "", userRoles);
RedirectOnSuccess();
}
else
{
RedirectToForbiddenPage();
}
}
else if(string.IsNullOrEmpty(HttpContext.Current.User.Identity.Name))
{
// no user data..go ask them to get SSOToken from service
Authenticate.isUserAuthenticated();
}
My attempt to repurpose it into a MVC styled .NET app:
public ActionResult Index()
{
if (string.IsNullOrEmpty(System.Web.HttpContext.Current.User.Identity.Name) && System.Web.HttpContext.Current.Request.QueryString["Token"] != null)
{
// we’ve got a token, they must have logged in ... double-check the token
string ssoToken = System.Web.HttpContext.Current.Request.QueryString["Token"].ToString();
string userRoles = string.Empty;
if (Authenticate.ValidateSSOToken(ssoToken, out userRoles))
{
string userName = System.Web.HttpContext.Current.User.Identity.Name;
//((BaseApplicationPage)(this.Page)).CurrentSecurity.SetUser(userName, "", userRoles);
//RedirectOnSuccess();
// TODO: Not sure what the MVC equivalent would be for commented out code above
return RedirectToAction("Index", "Checklist");
}
else
{
//RedirectToForbiddenPage();
HttpStatusCodeResult(HttpStatusCode.Forbidden);
}
}
else if (string.IsNullOrEmpty(System.Web.HttpContext.Current.User.Identity.Name))
{
// no user data...go ask them to get SSOToken from service
Authenticate.isUserAuthenticated();
return null; // Screwed if I don't return anything because of build error, screwed if I do return something because it messes with the redirect
}
else
{
return null;
}
}
Authenticate class snippet at the end of isUserAuthenticated that gets the token:
//string RedirectURL = GetBaseVirtualDirectory() + "/SignIn/Index";
string RedirectURL = "https://localhost:XXXX1/SignIn/Index";
HttpContext.Current.Response.Redirect(authServiceURL + "/Windows/Auth?RedirectURL=" + RedirectURL, true);
The problem is that your Authenticate.ValidateSSOToken method already called HttpContext.Current.Response.Redirect, which, as error message confirms, added a redirect header (Location) to the response.
You might be able to clear the response before calling RedirectToAction.
But a method called ValidateSSOToke probably should not do any redirects itself. It should return a status and you should do any redirects outside of it based on that status.
And doing all that validation inside your Action is probably not a good practice to begin with.

angular to webapi httppost call sends user object,Once they reach the webapi service properties under the user obj are becoming null(usrnm/pswd)

Hi i am new to Angular,
Now i started with a sample login page which passes userEntity that contains username and password.
userEntity is a object/entity is webapi.
Issue:
When i make a http Post call for login button click i find the angular calling the webapi2 service where userEntity is not null but the parameters of the object i.e username and password are becoming null.
Individually the web Api2 works when i try to post the data from Postman /fiddler.
Not sure whats the issue when called from angular.
Any help would be much appreciated. thanks in advance.
WEB API2 Code below:
[AllowAnonymous]
[HttpPost]
[Route("AuthenticateUser", Name = "AuthenticateUser")]
public HttpResponseMessage AuthenticateUser([FromBody]userEntity userentity)
{
string username = userentity.username;
string password = userentity.password;
return Request.CreateResponse(HttpStatusCode.OK, userLibraryService.AuthenticateUser(username, password));
}
Angular Code below:
factory.login = function (email, password) {
return $http.post(serviceBase + 'AuthenticateUser', { userentity: { username: ’testuser#test.com', password : 'pass1335' } }).then(
function (results) {
var loggedIn = results.data.status;;
return loggedIn;
});
};
Output:
I see the userEntity is not null but username and password are null once the request reaches the webapi2 service
Try send an object with just the username and password properties:
return $http.post(serviceBase + 'AuthenticateUser', { username: 'testuser#test.com', password: 'pass1335' }).then(
function (results) {
var loggedIn = results.data.status;;
return loggedIn;
});
};
also your example had ’ instead of ', not sure if it's a typo.

Is is possible to send information and receive a response through wcf/webservice to a website from a wpf app

I want to send some data to my mvc4 website from my wpf app and received data back from the website back to my wpf application. I tried to find a solution before coming here and people were saying something about a web service should be able to do that, but I dont know if i need to make a web service in my mvc4 website or if I need to make a wcf project in my wpf app.
Any guides or tutorials about this would be greatly appreciated.
EDIT:This is what I ended up with after seeing the first solution it does not work at the moment, I am not sure why im not getting a proper response back.
public bool GetData(LoginObj loginObj)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:12611/");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.PostAsJsonAsync("Home/VerifyLogin",loginObj).Result;
if (response.IsSuccessStatusCode)
{
var users = response.Content;
if (users.ToString() == "true")
return true;
else
return false;
}
return false;
}
this is in the home controller below
public class LoginObj
{
public string username { get; set; }
public string password { get; set; }
public LoginObj(string username, string password)
{
this.username = username;
this.password = password;
}
}
public JsonResult VerifyLogin(LoginObj loginObj)
{
bool isValid = true;
isValid = System.Web.Security.Membership.ValidateUser(loginObj.username, loginObj.password);
return Json(isValid,JsonRequestBehavior.AllowGet);
}
I'm not sure what you are trying to do, but normally a web application (mvc4) calls the service. Whatever to send, receive or both.
There you have your web app call the wcf requesting data and if it's changed elsewhere it will be returned from the wcf no matter what. When you need to save data you just send it to the wcf.
If you need some notification/chat-like app so a WCF can push data to your web app, seems like you are looking for SignalR.
If you can, please expand or explain better your question/need.
UPDATE:
You can create a 'web service' (wcf or webapi) or using the already mvc application and return a json response to act like a web service.
The simple you can get is something like :
A new action in your mvc app
public JsonResult CanLogin(string username, string password){
bool isValid = true; // check if username & password are ok and return True or False
return Json(isValid);
}
then on your wpf create an httpclient and call /application/CanLogin with user and password
you can allowGet on the json response for testing in your browser.
return Json(isValid, JsonRequestBehavior.AllowGet);

Categories