AJAX AntiForgery Token not calling controller method - json

I am struggling to call my controller method with [ValidateAntiForgeryToken] attribute.
My cshtml/js code :
var wizardRegisterJsonRequest = {
Email: email,
Password: password,
ConfirmPassword: confirmPassword,
Name: name
};
$.ajax({
type: 'POST',
dataType: "html",
url: 'http://localhost:50209/GetAllFonts/WizardRegister',
data: AddAntiForgeryToken(wizardRegisterJsonRequest),
beforeSend: function () {
$('#create_account_form').data('busy', true);
$('#create_account_busy').show();
},
success: function (data) {
if (data.Success === true) {
// all good here
}
$('#create_account_validation_summary').text(data.Message);
$('#create_account_validation_summary').show();
},
complete: function () {
$('#create_account_form').data('busy', false);
$('#create_account_busy').hide();
}
});
AddAntiForgeryToken = function (data) {
alert("adding anti forgery");
data.__RequestVerificationToken = $('#anti_forgery_token').val();
return data;
};
Controller code :
[ValidateAntiForgeryToken]
[HttpPost]
public JsonResult WizardRegister(User usrDetails)
//public JsonResult WizardLogOn(User usr)
{
// string test = ""; // this method WizardRegister is not getting called
}
User model :
public class User
{
public string Email { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string __RequestVerificationToken { get; set; }
}
I am not sure if I need __RequestVerificationToken in the User model. I am using AntiForgery for the first time.
Please let me know where I am going wrong ...
Thanks,
Rohan.
Update :
View / form code :
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "create_account_form" }))
{
#Html.AntiForgeryToken()
<fieldset>
<div class="input-fixed">
<span class="mandatory_wizard">* </span>
<input type="text" id="registrName" name="registrName" value="rohan" class="name" placeholder="Name">
</div>
<div class="input-fixed">
<span class="mandatory_wizard">* </span>
<input type="text" id="registrEmail" name="registrEmail" class="email" value="rohanskosht#gmail.com" placeholder="Email">
</div>
<div class="input-fixed">
<span class="mandatory_wizard"> </span>
<input type="text" class="phone" placeholder="Phone Number">
</div>
<div class="input-fixed">
<span class="mandatory_wizard">* </span>
<input type="password" id="registerPassword" name="registerPassword" value="12345678" class="password" placeholder="Password: Must be longer than 8 characters.">
</div>
<div class="input-fixed">
<span class="mandatory_wizard">* </span>
<input type="password" id="registerConfirmPassword" name="registerConfirmPassword" value="12345678" class="confirm-password" placeholder="Confirm Password">
</div>
<input type="submit" class="btn-modal-login" value="Create your account >>">
<img id="create_account_busy" style="display: none;" src="./Launch Campaign _ Teeyoot_files/busy.gif" alt="Loading...">
</fieldset>
}

#Html.AntiForgeryToken() generates a hidden input with name="__RequestVerificationToken". (it does not have an id attribute so $('#anti_forgery_token').val(); will return undefined.
You can access the value using
var token= $('[name=__RequestVerificationToken]').val();
However, I strongly suggest you generate the inputs for your properties using the HtmlHelper methods (#Html.TextBoxFor(m => m.Name), #Html.PasswordFor(m => m.Password) etc) rather than generating manual html and then you can simply use
data: $('form').serialize()
in the ajax call (and you can then delete most of your script). You should also not be hard coding the url (it will fail as soon as you put it into production). Your script simply needs to be
$.ajax({
type: 'POST',
dataType: "html",
url: '#Url.Action("WizardRegister", "GetAllFonts")',
data: $('form').serialize(),
beforeSend: function () {
....
You should also be including #Html.ValidationMessageFor() for each property to get client side validation so invalid forms are not submitted.
Side note: Its not clear from your code why you would use ajax. If the user is registering, then you would want to redirect if successful (and display validation errors if not), so ajax is pointless

Related

Activating separate functions based on the result of a function that posts information from a Form

I'm a bit of a novice with the implementation of multiple functions. However, I have a form where people can enter information which when submitted is posted to where I am collating the information. My code at the moment is:
component.html
<form name="hello"(ngSubmit)="onSubmit(helloForm); helloForm.reset();closeModal('custom-modal-2');openModal('custom-modal-3')" #helloForm="ngForm">
<input type="text" class = "box" placeholder="Name" name="name" ngModel required #name="ngModel"><br>
<input type="text" class = "box" placeholder="Email" email name="email" ngModel required #email="ngModel">
<re-captcha (resolved)="resolved($event)" siteKey="key"></re-captcha>
<br><input class="submit" type="submit" value="Submit">
</form>
component.ts
export class HelloDetailsComponent {public pageTitle = 'Contact Me';
constructor(private modalService: ModalService, private http: HttpClient) {}
resolved(captchaResponse: string) {
console.log(`Resolved captcha with response: ${captchaResponse}`);
}
openModal(id: string) {
this.modalService.open(id);
}
closeModal(id: string) {
this.modalService.close(id);
}
onSubmit(helloForm: NgForm) {
if (helloForm.valid) {
const email = helloForm.value;
const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
this.http.post('formsent',
{Name: email.name, Email: email.email},
{ 'headers': headers }).hello(
response => {
console.log(response);
}
);
}
}
At the moment, when I press the submit button without filling out the form, the openModal('custom-modal-3') appears.
I would like to change this so that it only appears when the form is submitted and implement a separate modal for when the form is incomplete. Does anyone have any ideas?

Input fields as lists in Angular

I want to take inputs from the user and append them to a list I have in my typescript. Here's what I have tried so far.
Here's the code:
<input type="text" id="course" name="course" class="form-control"[(ngModel)]="institutes.course">
institutes={course:''}
Use a function to add a new course and trigger it using a button.
app.component.html :
<!-- Input field -->
<input type="text" id="course" name="course" class="form-control" [(ngModel)]="newCourse">
<!-- Add button -->
<button (click)="addCourse()">Add</button>
app.component.ts :
newCourse : string = '';
allCourses : string[] = [];
// Function to add course
addCourse(){
this.allCourses.push(this.newCourse);
//Reset input
this.newCourse = '';
}
Demo : https://stackblitz.com/edit/angular-hzh42b
Write the following method in your component -
constructor(private url: string, private http: HttpClient) {}
posts: any;
createPost(input: HTMLInputElement) {
const post = { title: input.value };
this.posts.splice(0, 0, post);
input.value = "";
this.service.create(post).subscribe(
newPost => {
post.id = newPost;
},
(error: AppError) => {
this.posts.splice(0, 1);
if (error instanceof BadInput) {
// this.form.setErrors(error.originalError);
} else {
throw error;
}
}
);
}
Include this method in your service -
constructor(private url: string, private http: HttpClient) {}
create(resource) {
return this.http.post(this.url, JSON.stringify(resource)).pipe(
map(response => response),
catchError(this.handleError)
);
}
write the following code in your HTML -
<input
(keyup.enter)="createPost(title)"
#title
type="text"
class="form-control"
/>
You are good to go now!
The following code will help you to add a course into a list, which will be displayed in the web page.
.ts
courseList contains a list of all the added courses
course is the current course that you are adding.
addCourse is a method which will add a course into the list, and clear the course string.
public courseList = [];
public course;
addCourse() {
this.courseList.push(this.course);
console.log(this.courseList);
this.course = '';
}
.html
There is an input field which will take in course name.
And an add course button which will add the entered course name into the list and display the course list in the web page.
<ul>
<li *ngFor="let course of courseList">
{{course}}
</li>
</ul>
<input type="text" id="course" name="course" class="form-control" [(ngModel)]="course">
<button (click)="addCourse()">Add Course</button>

pass a list of objects via ajax to a MVC controller always sends null

I am probably missing something very simple. I have been working on this for a day and an half now and can not get it to work. I am looping through a table and creating a list of objects to send back to my controller. For some reason I am always receiving a null value in my controller. Here is the java script.
var items = [];
$('#grid tr').each(function () {
var item = {};
item.numReceived = $(this).find("input[id*='NumReceived']").val();
/*skip the header row*/
if (item.numReceived !== null) {
item.transactionID = $(this).find("input[id*='item_TransactionID']").val();
items.push(item);
}
});
$.ajax({
url: './ReceivePOLines',
type: "Post",
cache: false,
data: JSON.stringify(items),
dataType: "json",
contentType: 'application/json; charset=utf-8',
success: function () {
window.location.replace("../Home/Index");
},
error: function (request) {
alert("error");
}
});
here is the method signature in the controller
[HttpPost]
public void ReceivePOLines(List<RecievedTransactions> inTransactions)
And here is the class ReceivedTransactions
public class RecievedTransactions{
public int numReceived { get; set; }
public int transactionID { get; set; }
}
Here are the results from Fiddler showing what was passed
[{},{"numReceived":"10000","transactionID":"10661768"},{"numReceived":"10000","transactionID":"10661769"},{"numReceived":"2000","transactionID":"10661770"},{"numReceived":"2500","transactionID":"10661771"},{"numReceived":"2500","transactionID":"10661772"},{"numReceived":"2000","transactionID":"10661773"},{"numReceived":"10000","transactionID":"10661774"}]
Any and all help appreciated.
cheers
bob
This is a new answer. Originally, I was getting null, like you. But, now it works the way you want (array of complex objects). Please get this to work for you. If you can't get it to work, although it should, I can create an ASP.NET Fiddle.
public class RecievedTransactions
{
public int numReceived { get; set; }
public int transactionID { get; set; }
}
public class HomeController : Controller
{
[HttpPost]
public void ReceivePOLines(List<RecievedTransactions> inTransactions) // MyArray MyArray
{
return;
}
//you use your own action name
public ActionResult Tut133()
{
return View();
}
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Tut132</title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(function () {
var items = [];
$('#grid tr').each(function () {
var item = {};
item.numReceived = $(this).find("input[id*='NumReceived']").val();
/*skip the header row*/
if (item.numReceived !== null) {
item.transactionID = $(this).find("input[id*='item_TransactionID']").val();
items.push(item);
}
});
$.ajax({
//!!changing your url
//url: './ReceivePOLines',
url: "/Home/ReceivePOLines",
type: "Post",
cache: false,
//data: JSON.stringify({ MyArray: items }),
data: JSON.stringify(items),
//expecting back from server-need to remove since we are not getting back data from server
//dataType: "json",
contentType: 'application/json; charset=utf-8',
success: function () {
//alerting success instead of opening window
alert("success");
//window.location.replace("../Home/Index");
},
error: function (request) {
alert("error");
}
});
})
</script>
</head>
<body>
<table id="grid">
<tr>
<td><input type="text" id="NumReceived1" value="10000" /></td>
<td><input type="text" id="item_TransactionID1" value="10661768" /></td>
</tr>
<tr>
<td><input type="text" id="NumReceived2" value="10000" /></td>
<td><input type="text" id="item_TransactionID2" value="10661769" /></td>
</tr>
</table>
<input type="button" id="theButton" value="Go" />
</body>
</html>

can't create new performance in mvc [duplicate]

I have this form:
#model CupCakeUI.Models.CupCakeEditViewModel
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "createFrm" }))
{
<div class="form-group">
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
<input type="text" id="Name" name="Name" value="#Model.Name" />
</div>
<div class="editor-label">
#Html.LabelFor(model => model)
</div>
<div class="editor-field">
<input type="text" id="Price" name="Price" value="#Model.Price" />
</div>
<div class="col-md-offset-2 col-md-10">
<input type="button" id="btnCreate" value="Create" class="btn btn-default" />
</div>
</div>
}
I am trying to use ajax post to send data to the Action Method, however its always receiving empty object. I have done that several times in the past, and now i tried different ways which not working, The code:
$(document).ready(function () {
$("#btnCreate").click(function () {
var name = $("#Name").val();
var price = $("#Price").val();
var cupCakeEditModel = { "CupCakeId": 0, "Name": name, "Price": price };
var json = JSON.stringify(cupCakeEditModel);
$.ajax({
type: 'POST',
url: "/CupCake/Create",
data: JSON.stringify(cupCakeEditModel),
contentType: 'application/json',
success: function () {
alert("succes");
},
error: function () {
alert("error");
}
});
})
})
Its showing this in the console when logging:
This is the Action Method and Class used:
[HttpPost]
public JsonResult Create (CupCakeUI.Models.CupCakeEditViewModel cupCakeEditModel)
{
var cupCake =
CupCakeData.Save(cupCakeEditModel);
return Json("cupCake",
JsonRequestBehavior.AllowGet);
}
This the class:
public class CupCakeEditViewModel
{
public int CupCakeId;
[Display(Name = "CupCake Name")]
public string Name;
public string Price;
}
I have also used this, but not working:
$("#btnCreate").click(function () {
var cupCakeEditModel =
$("#createFrm").serialize();
$.ajax({
url: "/CupCake/Create",
type: "POST",
data: cupCakeEditModel,
success: function (response) {
alert("Success");
},
error: function (response) {
}
});
})
And several answers i found on the forum, but it seems something weird!
You model contains only fields, and the DefaultModelBinder does not bind fields, only properties. Change the model to
public class CupCakeEditViewModel
{
public int CupCakeId { get; set; }
[Display(Name = "CupCake Name")]
public string Name { get; set; }
public string Price { get; set; }
}

How to Update data in Modal using Angular2?

This is My Angular2 part.Here Updateuser function for update data in database
export class UserprofileComponent
{
getdata : string;
public data;
Username : any ;
Firstname :any;
updateuser(){
let re = /[?&]([^=#&]+)=([^&#]*)/g;
let match;
let isMatch = true;
let matches = {};
while (isMatch)
{
match = re.exec(window.location.href);
if (match !== null)
{
matches[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
if (match.index === re.lastIndex)
{
re.lastIndex++;
}
}
else {
isMatch = false;
}
}
console.log(matches);
var headers= new Headers({'Content-Type' : 'application/x-www-form-urlencoded '});
var body = JSON.stringify({
username1 : this.user.Username,
firstname1 : this.user.Firstname,
})
this.http.post('../widgets/Update.php?ID='+matches['ID'],body, {
headers:headers; })
.map(res => res.json())
.map(res => {
if(res.success)
{
this.m=res.Message;
}
else{
this.m="wrong";
}
})
.subscribe(
data =>this.getdata = JSON.stringify(data),
err => console.error(err),
() => console.log('done'));
}
}
This is My html part:
<ngl-modal header=" Edit Profile" [(open)]="opened" [size]="size">
<div body>
<div class="form-horizontal" style="margin:auto;" id="editForm" *ngFor="#user of getdata">
<div class="form-group">
<label class="col-md-3 control-label">Username:</label>
<div class="col-md-8">
<input type="text" class="form-control" id="cname" [(ngModel)]="user.Username" />
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Firstname:</label>
<div class="col-md-8">
<input type="text" class="form-control" id="ads" [(ngModel)]="user.Firstname"/>
</div>
</div>
<span>{{m}}</span>
<button class="slds-button slds-button--neutral" (click)="cancel()">Cancel</button>
<button class="slds-button slds-button--neutral slds-button--brand" (click)="updateuser()">Save</button>
</ngl-modal>
Here I'd use modal for displaying the data which is display by ngFor.But I want to update this display data so how to do it?Because data is display by ngModel and when I'm taking the whole ngModel value for example if [(ngModel)]="user.name" then it showing the error that user is not define so what to do in this case??
My first guess would be trying let user of getdata instead of #user of getdata.
My second guess would be creating an Array of users getdata: Array<any> as a property of your class, instead of getdata:string, then assign to it.
My third guess: before you get the data, there are no users, so:
<div *ngIf='getdata' class="form-horizontal" style="margin:auto;" id="editForm" *ngFor="#user of getdata"> to make sure you don't try to access the object before it's there.
Before you call updateUser() there are no objects you could show, that's why users are undefined, as far as I can see.
Hope some of this helps, good luck.