Asp.net controller recieving null - javascript

My ASP.net controller is receiving null instead of passed in parameters :(
Js function:
function SendFormToController() {
var username = document.getElementById("UsernameField").value;
var email = document.getElementById("EmailField").value;
var password = document.getElementById("PasswordField").value;
var SendJson = {
Username: username,
Email: email,
Password: password
};
console.log(JSON.stringify(SendJson));
$.ajax({
type: "POST",
data: JSON.stringify(SendJson),
url: "Register/Register",
contentType: "application/json"
});
}
Data is present when I console log it. But in the controller, I get - https://prnt.sc/u2mpa6
And it is for every field here

First; Did you add the [HttpPost] attribute on top of your controller method?
Second; If you submit it in 'querystring' format: Username=xx&Password=yy&... and use (HttpGet). Does that work?
If you need to do a POST (and not want to use GET) you can create an object with all your current arguments and use the [FromBody] attribute:
[Route("Register")]
[HttpPost]
public ResultData Register([FromBody] RegisterRequest data) {
//Your logic...
}
And client (JavaScript) side:
let url = 'http://...';
$.post(url, { Username: name, Password: pass, What: ever }, function (result) {
//Do some nice stuff
})
.fail(function (error) {
//Oh no! Show error.statusText
});

Related

Ajax POST an object with javascript, but the value in backend is null, why?

So on button click there is a function sendEmail(). Alert is working fine, I can see my datas there. But on backend I can't see anything, just everything is null.
function sendEmail() {
var datas = new Object();
datas.mail = $('#contactDropdownList').val();
datas.mailobject = $('#emailObject').val();
datas.text = $('#emailText').val();enter code here
alert(datas.mail + datas.mailobject + datas.text);
$.ajax({
type: "POST",
dataType: "json",
url: "/Email/sendEmail",
contentType: 'application/json; charset=UTF-8',
data: JSON.stringify({ items: datas }),
success: function (data) {
console.log(data);
//do something with data
},
error: function (jqXHR, textStatus, error) {
//log or alert the error
console.log(error);
}
});
}
C# code:
public class MyClass
{
public string Email { get; set; }
public string Object { get; set; }
public string Text { get; set; }
}
[HttpPost]
public IActionResult sendEmail(MyClass items)
{
return Json(new { data="Ok" });
}
items.Email, items.Object and items.Text are null.
And the return valu is null as well, because in javascript success: function (data) { console.log(data);
is empty string.
What can be the problem? Thank you!
Model binder expects json content to match C# class. Your datas object should look like that
var datas = {
email: $('#contactDropdownList').val(),
object: $('#emailObject').val(),
text: $('#emailText').val()
}
Since you wrapped your object ({ items: datas }), you may think it will be mapped to sendEmail(MyClass items), but in reality items name does not matter, you can change variable name to any other name you like
Make sure you apply [FromBody] attribute to your parameter like that
[HttpPost]
public IActionResult sendEmail([FromBody]MyClass items)
Complete demo:
<script>
function sendSmth() {
var data = {
Email: 'email',
Object: 'object',
Text: 'text'
};
$.ajax({
type: "POST",
dataType: "json",
url: "/home/index",
contentType: "application/json",
data: JSON.stringify(data),
success: function (datas) {
console.log(datas)
}
})
}
</script>
And controller
[HttpPost]
public IActionResult Index([FromBody]MyClass obj)
{
return View();
}
As someone has noted, you have a mismatch between what you're sending to the controller and what the model the modelbinder is expecting. You can also vastly simply your AJAX code:
function sendEmail() {
var data = {
Email: $('#contactDropdownList').val(),
Object: $('#emailObject').val(),
Text: $('#emailText').val()
};
$.post("/Email/sendEmail", data)
.done(function (response) {
console.log(response);
//do something with response
})
.fail(function (jqXHR, textStatus, error) {
//log or alert the error
console.log(error);
});
}
You don't really need to specify the content type or data type - the $.post helper's defaults work just fine for what you've shown.

Argument 1 passed to Illuminate\Database\Eloquent\Builder::create() must be of the type array, null given .. Error to post data

I am getting error saying create() must be array in my store function. I am litte confuse how to change it/correct this error. Anyone could suggest me ? I am using vue js. I used formdata append and axios to post the data in database.
public function store(Request $request)
{
$requestJob = $request->get('UserApplyJob');
$requestJob = UserApplyJob::create($requestJob);
}
data function
data(){
return{
UserApplyJob:{
name:"",
email:"",
telephone:"",
pitch:"",
expectedSalary:"",
resume: null
},
error:{}
}
this is the method function
methods:{
validate: function(){
let valid = true;
if (!this.UserApplyJob.name){
this.$set(this.error, 'name' , 'Name is required');
valid=false;
}
return valid;
},
getFile(event){
this.UserApplyJob.resume = event.target.files[0];
},
submit(){
let formData = new FormData();
formData.append('name',this.UserApplyJob.name);
formData.append('email',this.UserApplyJob.email);
formData.append('expectedSalary',this.UserApplyJob.expectedSalary);
formData.append('pitch',this.UserApplyJob.pitch);
formData.append('telephone',this.UserApplyJob.telephone);
formData.append('resume',this.UserApplyJob.resume);
axios({
method: 'POST',
url: '/applyJob',
data: formData,
headers: {'Content-Type': 'multipart/form-data' }
})
.then(function (response) {
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
}
}
Please change to:
$requestJob = $request->all();
$requestJob = UserApplyJob::create($requestJob);
What you are doing in store controller method is using the form field which it doesn't have (formData doesn't have any UserApplyJob field).
I suppose you want to create UserApplyJob model with the formData. For that you would need to use all the request data:
public function store(Request $request)
{
$requestJob = UserApplyJob::create($request->all());
}

Persist data across multiple controllers

I have a login form (created with Html.BeginForm()) with an email field, password field, and a "Forgot Password?" link within it. Originally, it was a submit button within the login form, and it would intercept the SignIn action. I wanted to abstract the Forgot Password functionality from the SignIn action.
In doing so, I noticed that it was set up this way in order to pass the email field value to the Forgot Password page (so the user wouldn't have to re-enter it). That was placed into TempData.
My thought was to have an AJAX call to a new controller action:
[HttpPost]
[AllowAnonymous]
public ActionResult ToForgotMyPassword(string email)
{
TempData["signInEmail"] = email;
return Json(new { redirectUrl = Url.Action("ForgotMyPassword"), TempData = TempData, email = email });
}
But my problem I've found is the TempData doesn't persist to the next action, ForgotMyPassword. On my view, I have the following JS:
$('#forgotPassword').click(function (e) {
var forgotMyPasswordUrl = $(this).attr('href');
e.preventDefault();
$.ajax({
type: "POST",
url: '#Url.Action("ToForgotMyPassword")',
data: { email: $('#Email').val() },
dataType: "json",
beforeSend: function (xhr) {
console.log(xhr);
},
success: function (result) {
//alert('Success');
console.log(result);
window.location = result.redirectUrl;
},
error: function (result) {
alert('Error');
console.log(result);
//window.location = forgotMyPasswordUrl;
}
});
});
How would I go about persisting this TempData to the redirect page? Is the way I'm going about this just not suited for an AJAX call? Should I just make a new model and new form within the Login form?
I tried to repeat your problem. And here what I done:
Controller:
[HttpPost]
[AllowAnonymous]
public ActionResult ToForgotMyPassword(string email)
{
TempData["signInEmail"] = email;
return Json(new { redirectUrl = Url.Action("ForgotMyPassword")});
}
[HttpGet]
[AllowAnonymous]
public ActionResult ForgotMyPassword()
{
var email = TempData["signInEmail"];
return View("Index", email);
}
View:
#model string
<html>
<head>
<title>#Model</title>
</head>
<body>
<div>
<input id="email" value="test#test.com"/>
<button id="forgotPassword">forgotPassword</button>
</div>
</body>
</html>
<script>
$('#forgotPassword').click(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: '#Url.Action("ToForgotMyPassword")',
data: { email: $('#email').val() },
dataType: "json",
beforeSend: function (xhr) {
console.log(xhr);
},
success: function (result) {
console.log(result);
window.location = result.redirectUrl;
},
error: function (result) {
alert('Error');
console.log(result);
}
});
});
</script>
And all this stuff works fine, so i checked two theories:
1) If you try to send TempData ("TempData = TempData" in next code fragment)
Json(new { redirectUrl = Url.Action("ForgotMyPassword"), TempData = TempData, email = email });
TempData will be cleared, it will not have any element in it's collection
2) if you input id="email" and in script you use $("#Email").val() - you will got nothing. name should be equals
I hope it helps.

Ajax call failing to get the return message from web api service

I am making a simple ajax call to the web api service that serves an authentication routine.
My problem is the ajax call can make a request to the service but errors out once the service returns a boolean value.
WHAT I WANT:
All i want to do is check if the returned boolean is true or false. If true i want to redirect the user to another page.
Could somebody please help me out on this?
JQUERY CODE:
<script type="text/javascript">
$(document).ready(function () {
$('#submitButton').click(function () {
var name = $(userNameTextBox).val);
var pass = $(passwordTextBox).val();
if (name.length == 0 || pass.length == 0) {
alert("Please enter your credentials");
}
else {
$.ajax({
url: "http://localhost:50503/api/Authentication/Authenticate",
data: { userName: name, passWord: pass },
cache: false,
type: 'GET',
dataType: 'json',
success: function (msg) {
alert(msg);
},
error: function (msg) {
alert("Error Message: "+msg);
}
});
}//end of else
});
});
</script>
Here is my webapi service
public class AuthenticationController : ApiController
{
[HttpGet]
[Route("api/Authentication/Authenticate")]
public bool Authenticate(string userName,string passWord)
{
if (userName.ToLower().Equals("username") && passWord.ToLower().Equals("password"))
{
return true;
}
else
{
return false;
}
}
}
You can try replace your ajax call by this maybe, remove the dataType:
var request = $.ajax({
url: "http://localhost:50503/api/Authentication/Authenticate",
cache: false,
type: 'POST',
data: { userName: userName, passWord: passWord }
});
request.done(function (msg) {
//check the boolean and redirect user to another page.
if(msg) window.location.href = "http://nextpage.com";
});
i also change the method to POST. More appropriate in your case.
If all else fails, put a debugger breakpoint (e.g., via the debugger directive in your error callback to $.ajax and run your code in the browser's debugger (i.e. Chrome dev tools). Then, after the breakpoint is hit, you should be able to determine (by walking the stack) why the error callback is invoked.
My Test
I've tried to reproduce your case, and for me it doesn't fail. I've defined a test controller in the following way:
using System.Web.Http;
namespace Test
{
public class TestController : ApiController
{
[HttpGet]
public bool Authenticate(string username, string password)
{
return username == "user" && password == "pass";
}
}
}
And I make an AJAX call to it from JavaScript like so:
$.ajax({url: 'http://localhost:59900/api/test', type: 'get', dataType: 'json', cache: false, data: { userName: 'user', passWord: 'pass' }}).done(function () {console.log("Success", arguments);}).fail(function () { console.log("Error", arguments); });
The AJAX call invokes the success callback (done) with true as its result, so no issues at all.
Parser Error
It appears that jQuery can't parse the JSON sent from Web API (true). To return valid JSON, return an object of the following type from your controller:
public class Result
{
public bool Result { get;set; }
}
This should result in the following JSON being sent to your client:
{ "Result": true }
Updated controller:
namespace Test
{
public class TestController : ApiController
{
[HttpGet]
public Result Authenticate(string username, string password)
{
return new Result { Result = username == "user" && password == "pass" };
}
}
}
Try to use (worked for me, check responseJSON.Message of first parameter object):
$.post(url, jsonData).
done(function (data) {}).
fail(function (xhr, status, err) {
alert("Error " + err + ". " + xhr.responseJSON.Message);
});

Browser tries to open application/json as a file

I'm having a problem with my JSON response in my MVC 3 application. When JSON is responding, my browser cannot handle application/json and tries to open it as a file. However, I'm recieving the correct data in the file.
I've added this to my Global.asax file:
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
This is my javascript code:
$('#register).submit(function () {
if ($(this).valid()) {
var ai = {
Firstname: $("#Firstname").val(),
Lastname: $("#Lastname").val(),
Email: $("#Email").val()
};
var json = $.toJSON(ai);
$.ajax({
url: '/Person/Create',
type: 'POST',
dataType: 'json',
data: json,
contentType: 'application/json; charset=utf-8',
success: function (data) {
alert("Success");
},
error: function (data) {
alert("Error");
}
})
}
});
And this is my ActionResult method:
[HttpPost]
public ActionResult Create(Person person)
{
if (ModelState.IsValid)
{
db.Personer.Add(person);
db.SaveChanges();
}
return Json(new { Success = person.ID > 0, Firstname = person.Firstname, Lastname = person.Lastname });
}
I've also added .json (application/json) to the MIME-list in IIE.
If you're trying to access a file with JSON headers in Firefox directly (meaning: you're entering the URL into the address bar), Firefox will download it as a file. However, when you call your JSON in an AJAX request, it'll work the way you want it to.

Categories

Resources