Jquery Post & ASP.NET MVC Anti-ForgeryToken Validation - c#

In my controller,
[HttpPost]
[OutputCache(CacheProfile = "Short", VaryByParam = "id", VaryByCustom = "none")]
[ValidateAntiForgeryToken(Salt = #ApplicationEnvironment.SALT)]
public ActionResult username(string id) {
try {
if (id == null || id.Length < 3)
return Json(false, JsonRequestBehavior.AllowGet);
var member = Membership.GetUser(id);
if (member == null) {
//string userPattern = #"^([a-zA-Z])[a-zA-Z_-]*[\w_-]*[\S]$|^([a-zA-Z])[0-9_-]*[\S]$|^[a-zA-Z]*[\S]$";
string userPattern = "[A-Za-z][A-Za-z0-9._]{5,14}";
if (Regex.IsMatch(id, userPattern))
return Json(true, JsonRequestBehavior.AllowGet);
}
} catch (Exception ex) {
CustomErrorHandling.HandleErrorByEmail(ex, "Validate LogName()");
return Json(false, JsonRequestBehavior.AllowGet);
}
//found e false
return Json(false, JsonRequestBehavior.AllowGet);
}
and in my view I am doing this for post, I was able to retrieve data for getJSON using HTTP Get. The problem is, when the user puts a space in the name, it doesn't validate and gives a 404. So I thought I could do this using the post method, but it seems that I am unable to send my logname because I am sending an Antiforgery token in the data by serializing it ...
Can any one please help? I would be grateful.
#{
string SALT = ApplicationEnvironment.SALT;
}
<script type="text/javascript" defer="defer">
$(function () {
if($("#LogName").length > 0){
$("#LogName").blur(function(){
var logValidate = "/Validation/username/" + $("#LogName").val();
//anti-forgery token works don't need to create the input field here but if I pass the logname into the form as an input then if a user puts double quote/single quote then it will also crash.. so is there any other way around.
var data = $('<form>#Html.AntiForgeryToken(SALT)</form>').serialize();
$.post(logValidate, data, function (json) {
alert(json);
});
});
$("#Email").blur(function(){
var emailValidate = "/Validation/email/" + $("#Email").val();
alert("got it");
});
}
});
</script>

How about you take the value of the antiforgery token by jquery when sending the request?
Generate your antiforgery key as a hidden field:
#Html.AntiForgeryToken()
Look at the sourcecode and adjust the "#__RequestVerificationToken" selector
var antiForgeryVal = $('#__RequestVerificationToken').val();
data["__RequestVerificationToken"] = antiForgeryVal ;
$.post(logValidate, data, function (json) {
alert(json);
});

Related

Execute action without redirecting(Add to wishlist)

So, I have some product cards that I'm displaying with a foreach loop. When I click a link, I want to add that product to my wishlist (Session["wishList"]). That calls a function and redirects me to /product/wishlist/01, where 01 is the product id.
My temporary fix is return Content("<script type='text/javascript'>window.history.back();</script>"); but no reloading would be better.
My code:
<code>
<i class="far fa-heart"></i>
</code>
Controller:
<code>
public ActionResult AddToWishList(int id)
{
if (Session["email"] != null && Session["role"] != null && (WebApplication1.Models.RoleType)Session["role"] == Models.RoleType.User)
{
var wishList = (List<int>)Session["wishList"];
if (wishList.Contains(id))
{
wishList.Remove(id);
}
else
{
wishList.Add(id);
}
Session["wishList"] = wishList;
}
return Content("<script type='text/javascript'>window.history.back();</script>");
}</code>
You can use Ajax in your case which is used to update a portion of the page without reloading the entire page. In your case, you can do something like:
Define a function which will take a the id of the selected element:
<code>
</i>
</code>
Then you need to define a function which will take this id and send it to your Controller via Ajax:
<script>
function addToWishList(id)
{
var json = {
id : id
};
$.ajax({
type: 'POST',
url: "#Url.Action("AddToWishList", "Product")",
dataType : "json",
data: {"json": JSON.stringify(json)},
success: function(data) {
if(data.status=="true")
{
alert(data.msg);
var urlToRedirect= '#Url.Action("Index","Home")';
window.location.href = urlToRedirect; //Redirect here
}
},
error: function(data) {
alert('Some error');
window.location.reload();
}
});
}
</script>
And then finally in your Controller, you can process this id and then return back a result:
using System.Web.Script.Serialization;
[HttpPost]
public ActionResult AddToWishList(string json)
{
var serializer = new JavaScriptSerializer();
dynamic jsondata = serializer.Deserialize(json, typeof(object));
//Get your variables here from AJAX call
var id = Convert.ToInt32(jsondata["id"]);
if (Session["email"] != null && Session["role"] != null && (WebApplication1.Models.RoleType)Session["role"] == Models.RoleType.User)
{
var wishList = (List<int>)Session["wishList"];
if (wishList.Contains(id))
{
wishList.Remove(id);
}
else
{
wishList.Add(id);
}
Session["wishList"] = wishList;
}
return Json(new {status="true", msg= "Successfully processed"});
}
You can tailor the methods as per your requirement.
Implementing callbacks in your page could work:
ASP.Net : https://learn.microsoft.com/en-us/previous-versions/aspnet/ms366518(v=vs.100)
ASP.Net MVC : https://docs.devexpress.com/AspNetMvc/9052/common-features/callback-based-functionality

Cant do redirect (ASP.NET MVC)

I need to do redirect to controller
Here is my controller
[HttpPost]
public ActionResult Index(string question1, string question2, string question3, string question4, string question5, string question6, string question7, string question8, string question9, string question10, Int32 id)
{
QuestionBlock question = new QuestionBlock
{
Question1 = question1,
Question2 = question2,
Question3 = question3,
Question4 = question4,
Question5 = question5,
Question6 = question6,
Question7 = question7,
Question8 = question8,
Question9 = question9,
Question10 = question10,
Interview_Id = id,
};
//TempData["id"] = id;
db.QuestionBlocks.Add(question);
db.SaveChanges();
return Json(new { Result = "Success", Message = "Saved Successfully" }, JsonRequestBehavior.AllowGet);
I try to do it like this
return RedirectToAction("Index", "Questions", new { id = id });
I have this AJAX call in my View. Maybe trouble in it?
<script>
$('.click').on('click', function () {
$('.content').toggle();
});
var counter = 0;
$(document).ready(function () {
$('#save').click(function () {
save();
});
});
function save()
{
$.ajax({
type: 'Post',
dataType: 'Json',
data: {
question1: $('#Question1').val(),
question2: $('#Question2').val(),
question3: $('#Question3').val(),
question4: $('#Question4').val(),
question5: $('#Question5').val(),
question6: $('#Question6').val(),
question7: $('#Question7').val(),
question8: $('#Question8').val(),
question9: $('#Question9').val(),
question10: $('#Question10').val(),
},
url: '#Url.Action("Index", "Questions")',
success: function (da) {
if (da.Result === "Success") {
alert('Вопросы сохранены');
} else {
alert( 'Error'+ da.Message);
}
},
error: function (da) {
alert('Error');
}
});
}
</script>
But redirection not works. Where is my trouble?
Maybe I need to do it not in controller?
Thank's for help
Your current code is returning a JSON response with 2 properties and your main view code is making an ajax call to this action method. So the JSON response returned from the action method will be handled in the success handler of your ajax call. It will not do a redirect unless you explicitly do so.
Even if you replace the return Json with return RedirectToAction, It does not makes sense to use it with the Ajax call. The whole idea of ajaxifying the page is to avoid the traditional page submit - reload experience and replace it with partial page upload behavior (better user experience)
If you absolutely want to redirect to another page, you can do that in the success event handler. But like i mentioned earlier, it does not makes sense to do an ajax post then. Do a normal form post!
if (da.Result === "Success") {
window.location.href="Give the new Url you want to navigate to here";
}
You can use the UrlHelper class to generate the correct url to the other action method and send that as part of your JSON response.
var urlBuilder = new UrlHelper(Request.RequestContext);
var url = urlBuilder.Action("Index", "Questions",new { id= id});
return Json(new { Result = "Success", Message = "Saved Successfully",RedirectUrl=url });
Now in your ajax call , read the RedirectUrl property
if (da.Result === "Success") {
window.location.href=da.RedirectUrl;
}
Have you tried just like this without writing Questions.:
return RedirectToAction("Index", new { id = yourvalue });
EDIT:
Otherwise you can try this:
return RedirectToAction( "Index", new RouteValueDictionary(
new { controller = controllerName, action = "Index", id = id } ) );

MVC 5 c# hide url parameter

$.ajax({
type: "POST",
url: "#Url.Action("SignInUp")",
data: JSON.stringify({ email_add: email_add ,}),
contentType: "application/json; charset=utf-8",
success: function (response) {
if (response.result == 'SignUp') {
alert("Opp`s its look like you dont have an access for this website");
window.location = response.Urls;
}
else
{
alert("Success fully login");
window.location = response.Url;
}
}
});
hi guys I`m new in mvc5 c# and i in counter this problem i want to hide my url parameter. any can help me thank you for advance
this is my code:
public ActionResult SingInUp(string email_add)
{
bool obj = db.tblUsers.Any(x => x.email_add.Equals(email_add));
if (obj)
{
tblUser user = db.tblUsers.Single(x => x.email_add == email_add);
Session["email_add"] = user.email_add;
Session["fname"] = user.fname;
Session["lname"] = user.lname;
return Json(new { result = "Redirect", Url = Url.Action("Check", "ProjectV3") });
}
else
{
return Json(new { result = "SingUp", Urls = Url.Action("SignUp", "ProjectV3", new { email_add = email_add}) });
}
}
This is i want to hide
If you want to effectively hide something from the client Url you will need to find a way to either mask it, or store it somewhere on the server that can be captured on the next request.
There are many places you can store this data on your server but really the obvious ones are.
Cookies
TempData
Now TempData may seem like the obvious choice as it persists across requests and is cleared from the TempData when accessed. Which is also its downfall, lets say you set the TempData in your SingUpIn method, then return the JsonResul which I am assuming is then used via JavaScript for a redirect. Then you redirect to this page and then pull the value of the TempData dictionary it is subsequently removed. So if the person ends up on the SingUp page and for some reasons decides to refresh the page the value in the TempData wont be found again.
Now this can be handled by resetting the TempData property on each read. So basically you read the TempData item then you reassign the TempData entry.
Here is some very basic code that [basically] works and doesnt show the email in the url.
public ActionResult SignUpIn(string email_acct)
{
//pretend i tested for a real user
TempData["email_acct"] = email_acct;
var r = new { result = "SingUp", Urls = Url.Action("SingUp") };
return Json(r);
}
public ActionResult SingUp()
{
if (!TempData.ContainsKey("email_acct"))
{
//no temp data email.. maybe redirect.. who knows!!
return RedirectToAction("Index");
}
//read the temp data entry..
string emailAcct = TempData["email_acct"].ToString();
//reset the temp data entry
TempData["email_acct"] = emailAcct;
return View(new SingUpModel { EmailAccount = emailAcct });
}
Unless you want to go to POST rather than URL parameters you are stuck. If you just want to hide some of the implementation details you could encode the parameter to obfuscate its meaning.
return Json(new { result = "SingUp", Urls = Url.Action("SignUp", "ProjectV3", new { email_add = Base64Encode(email_add)}) })
...
public static string Base64Encode(string plainText) {
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
You would end up with a URL like: http://localhost:1126/ProjectV3/SignUp?email_add=cGtleWJpcmQ5NUBnbWFpbC5jb20=. You could obviously change the name of the parameter to hide its intent.

Redirect to action with JsonResult

I have a view. When user clicks on a button in my view, I am trying to get some data from my view without reloading my view through an AJAX POST to display some data.
This is the method in my controller :
[HttpPost]
public JsonResult GetUserTraj()
{
var userTrajList =
DBManager.Instance.GetUserTraj(Session["UserName"].ToString());
return Json(userTrajList);
}
This returns a Json Result. I am trying to implement session now. So if the session has expired, I want user to be redirected to the Login view. In the above case if the session expires Session["UserName"] becomes null and an exception is raised.
[HttpPost]
public JsonResult GetUserTraj()
{
if (Session["UserName"] != null)
{
var userTrajList =
DBManager.Instance.GetUserTraj(Session["UserName"].ToString());
return Json(userTrajList);
}
else
{
RedirectToAction("Login", "Login");
return Json(null);
}
}
I tried the above code. But it doesn't work. It does not redirect the user to the Login view. I tried return RedirectToAction("Login", "Login");. But that doesn't work since the controller action method cannot return something other than JsonResult. Please help me find a solution for the same.
If you use AJAX to request a page, it's cant redirect in browser.
You should response a status code, and then use javascript to redirect in front, like this
[HttpPost]
public JsonResult GetUserTraj()
{
if (Session["UserName"] != null)
{
var userTrajList =
DBManager.Instance.GetUserTraj(Session["UserName"].ToString());
return Json(userTrajList);
}
else
{
//RedirectToAction("Login", "Login");
return Json(new {code=1});
}
}
You need write this condition Inside of your Ajax success call to reload login screen,
if(result.code ===1){
window.location = 'yourloginpage.html'
}
You can't redirect user to a new page using ajax. For this you have to send some flag at client side and then need to use that flag to identify that session has been expired.
Following code will help you:
[HttpPost]
public JsonResult GetUserTraj()
{
if (Session["UserName"] != null)
{
var userTrajList = DBManager.Instance.GetUserTraj(Session["UserName"].ToString());
return Json(new { Success = true, Data = userTrajList});
}
else
{
return Json(new { Success = false, Message = "Session Expired"});
}
}
jQuery
$.ajax({
url: "any url",
dataType: '',
contentType: "------",
success: function(response){
if(response.Success){
// do stuff
}else{
window.location.href = "/YourLoginURL.aspx"
}
}
});
Just try it
[HttpPost]
public ActionResult GetUserTraj()
{
if (Session["UserName"] != null)
{
var userTrajList =
DBManager.Instance.GetUserTraj(Session["UserName"].ToString());
return Json(userTrajList);
}
else
{
RedirectToAction("Login", "Login");
return Json(null);
}
}
Edit
also your login action should be return json result, if you wont the page reloading
ActionResult is an abstract class that can have several subtypes.
ActionResult Subtypes
ViewResult - Renders a specifed view to the response stream
PartialViewResult - Renders a specifed partial view to the response stream
EmptyResult - An empty response is returned
RedirectResult - Performs an HTTP redirection to a specifed URL
RedirectToRouteResult - Performs an HTTP redirection to a URL that is determined by the
routing engine, based on given route data
JsonResult - Serializes a given ViewData object to JSON format
JavaScriptResult - Returns a piece of JavaScript code that can be executed on the client
ContentResult - Writes content to the response stream without requiring a view
FileContentResult - Returns a file to the client
FileStreamResult - Returns a file to the client, which is provided by a Stream
FilePathResult - Returns a file to the client
Controller
This is a common function may used as a generic one as you wish
public void logoutJson()
{
Response.StatusCode = (int)HttpStatusCode.BadRequest; //Send Error Status to Ajax call
Response.StatusDescription = Url.Action("Index", "Account"); //Url you want to redirect
}
Script
Just paste this code in the View Pages you want to use it. So it will automatically handle All AJAX calls you wanted.
$(document).ready(function () {
$.ajaxSetup({
'complete': function (xhr, textStatus) {
if (xhr.status!="200") {
window.location.replace(xhr.statusText); //Redirect to URL placed in Response.StatusDescription
}
}
});
});
Example
Just call the function for manually fail the AJAX Request and the script in client side handle to redirect to login page.
public JsonResult TestAction()
{
if (null == Session["EmpId"])
{
logoutJson(); //Just call the function
}
}

MVC Jquery POST data, redirect to url from ActionResult

I am currently working with mvc. I have a page with more than one button on, which does complicate things a little. However the button I am using calls a jquery function to post data to the controller. This works as expected and data reaches the action and the action does everything expected except redirect.
The function posts data to the controller, or allows the controller to see the values and build up a url to then redirect to. However the redirect doesnt work, and the function calls a success function as expected. If I put the data return into an alert the code for the page is returned in the alert window not the url.
Here is the code:
<input type="submit" value="Assign" name="Assign" onclick="doRedirect()" />
function doRedirect() {
var action = '#Url.Action("Redirect")';
//alert(action);
var opt = {
type: "POST",
data: {
Team: $('#Team option:selected').val()
},
url: action,
success: RedirectSuccess
};
jQuery.ajax(opt);
}
function RedirectSuccess(data) {
if (data != undefined) {
data;
}
}
public ActionResult Redirect(string Team)
{
var hostName = "http://localhost/test/testpage.aspx?";
var team = "&Team=" + Team;
var filterUrl = Team;
return Redirect(filterUrl);**//this doesnt work**
}
Instead of sending back a redirect result from the action, try sending back the URL you want to redirect to. On the client side, you read the response of the request, and do the redirect by setting window.location.href to the URL you get back from the server.
In your action, you could return the URL as JSON for instance:
return Json(new { url: filterUrl });
And in your success callback, you do this to redirect:
if (data !== undefined && data.url !== undefined) {
window.location.href = data.url;
}
This is what I did instead.
public string Redirect(string Team)
{
var hostName = "http://localhost/test/testpage.aspx?";
var team = "&Team=" + Team;
var filterUrl = hostname + Team;
return filterUrl;
}
function RedirectSuccess(data) {
if (data != undefined) {
window.location = data;
}
}
and on my search success

Categories