500 Interval Error MVC - c#

i want to send my data from view to controller using ajax but I can't send the data to controller.
Thanks for your help.
That's my View code,
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>SignUp</title>
<link href="../../css/bootstrap.min.css" rel="stylesheet">
<link href="../../css/signin.css" rel="stylesheet">
<script type="text/javascript" src="../../js/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
$(document).on("click", "#btnSignUp", function () {
var tcNo = document.getElementById('inputTcn').value;
var nameSurname = document.getElementById("Name").value;
var eMail = document.getElementById('Email').value;
var number = document.getElementById("PhoneNumber").value;
var secretQuestionAnswer = document.getElementById("inputSecretQuestionAnswer").value;
var password = document.getElementById('inputPassword').value;
var passwordVerify = document.getElementById("passwordVerify").value;
//var stateValue = document.getElementById("viewStates").value;
$.ajax({
type: 'POST',
url: '/Home/SignUp',
dataType: 'json',
data: {
'tcNo': tcNo,
'nameSurname': nameSurname,
'eMail': eMail,
'number': number,
'secretQuestionAnswer': secretQuestionAnswer,
'password': password,
'passwordVerify': passwordVerify,
'stateValue': stateValue
},
success: function (msg) {
alert("bsg");
},
error: function (msg) {
alert("2");
}
});
});
</script>
</head>
<body>
<div class="container">
<form class="form-signin">
<h2 class="form-signin-heading"></h2>
<input id="inputTcn" class="form-control" placeholder="T.C. NO GİRİNİZ" required="" autofocus="">
<input id="Name" class="form-control" placeholder="ADINIZI SOYADINIZI GİRİNİZ" required="">
<input id="Email" class="form-control" placeholder="E-MAIL GİRİNİZ" required="">
<input id="PhoneNumber" class="form-control" placeholder="GSM NUMARANIZI GİRİNİZ" required="">
<input id="inputSecretQuestionAnswer" class="form-control" placeholder="ÖZEL SORUNUZUN CEVABINI GİRİN">
<input type="password" id="inputPassword" class="form-control" placeholder="ŞİFRENİZİ GİRİNİZ" required="">
<input type="password" id="passwordVerify" class="form-control" placeholder="ŞİFRENİZİ TEKRAR GİRİNİZ" required="">
#Html.DropDownList("viewStates")
<a id="btnSignUp" class="btn btn-lg btn-primary btn-block btn-danger">KAYIT OL</a>
</form>
</div>
</body>
</html>
and here that's my Controller,
[HttpPost]
public ActionResult SignUp(string tcNo, string nameSurname, string eMail, string number,
string secretQuestionAnswer, string password, string passwordVerify, string stateValue)
{
return View();
}
and I add data to my Dropdownlist at here,
[HttpGet]
public ActionResult SignUp()
{
var database = new KargoDB();
List<SelectListItem> stateList = (from s in database.States
select new SelectListItem
{
Text = s.Description,
Value = (s.State_id).ToString()
}).ToList();
ViewBag.viewStates = stateList;
return View();
}

500 error code means Internal server error. That means your server side code is crashing in the HttpPost Signup method.
If you open the network tab of your browser,and click on the response of the request you made, you will be able to see the response (Exception details returned by asp.net mvc). That will help you to identify the issue.
In your HttpPost action method, you called return View() ,which is going to return the Signup.cshtml razor view. But in the signup view, similar to our GET action, It is going to look for ViewBag.viewStates to render the state dropdown. But we did not set that in our HttpPost Signup method. So it will end up with a null reference exception when razor tries to render the view.
Remember, Http is stateless. One request does not have no idea what happened in the previous request. That means, the request for HttpPost action does not have any idea of the ViewBag items you set in the previous request(GET request).
Typically, for action methods which serves ajax posts, It is good to return a JSON response.
So instead of return View(), return a json structure.
[HttpPost]
public ActionResult SignUp(string tcNo, string nameSurname, string eMail,
string number,string secretQuestionAnswer, string password,
string passwordVerify, string stateValue)
{
return Json(new {status = "success"});
}
This is going to return a json structure like
{"status" : "success"}
And you can read that in your success event handler
success: function (msg) {
console.log(msg);
if(msg.status==="success")
{
alert("Saved");
}
}
Also, looks like you have a lot of parameters being posted to the Signup method, instead of writing so many params, you should use a view model.
Here is an example on how to do that.

Instead of returning a view from the controller return a JSON result and parse the result and bind it to the dropdown.
Since you are trying to retrieve data from the HTTPGet controller, you should be using the HTTP method of Get.
[HttpGet]
public JSONResult SignUp()
{
return Json(resultset, JsonRequestBehavior.AllowGet);
}
success: function (msg) {
// parse msg and bind to dropdown
},
Try using JSON.NET
For a detailed read

As mentioned above, http 500 is because of an exception in .Net code.Are you getting this in development. If so give the details of exception. You may attached to W3Wp.exe if you are doing it in some different way.
If this is hosted in dev / QA servers, use remote debugging mechanism. In production look at windows eventviewer. Sometimes you will see what is the exception. Once the exception is visible, just google or post it here.
http://www.codeproject.com/Articles/38132/Remote-IIS-Debugging-Debug-your-ASP-NET-Applicatio

Related

POST JSON object to C# ASP.NET WEB API

I'm unable to post JSON object in the body of my HTTP message.
I have even tried this
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
but it still didn't work
Here is my code:
<!DOCTYPE html>
<html lang="en">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="formCtrl">
<form novalidate>
type:<br>
<input type="number" ng-model="config.type"><br>
Id:<br>
<input type="text" ng-model="config.Id">
<br><br>
<button ng-click="submit()">Submit</button>
</form>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope,$http) {
$scope.config = {type:0, Id:"786"};
$scope.submit = function() {
var data = $scope.config;
//$http.post("http://localhost:8612/api/values/", data);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://localhost:8612/api/values/", true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send(JSON.stringify(data));
alert("Done");
};
});
</script>
</body>
</html>
I am getting an error that is my object is empty in this method
// POST api/values
[HttpPost]
public IActionResult Post([FromBody]object c)
So the deserialization is failing probably. having the request model as object type is wrong; instead you should define a proper request model and use that rather like
public class ApiRequestModel
{
// define all your required properties client going to send
}
[HttpPost]
public IActionResult Post([FromBody] ApiRequestModel c)

Dropzone on razor Page returns 400 status code

I am using DropZone on a RAZOR page in ASP.NET core 2.0 with other form inputs like this -
DzDemo.cshtml Page -
<form method="post" enctype="multipart/form-data">
<input type="text" id="Username" name="Username" />
<div class="dropzone" id="my-dropzone" name="mainFileUploader">
<div class="fallback">
<input name="file" type="file" multiple />
</div>
</div>
</form>
<div>
<button type="submit" id="submit-all"> upload </button>
</div>
JS:-
Dropzone.options.myDropzone = {
url: "/DzDemo?handler=Upload",
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
acceptedFiles: "image/*",
// paramName: myParamName,
init: function () {
var submitButton = document.querySelector("#submit-all");
var wrapperThis = this;
submitButton.addEventListener("click", function () {
wrapperThis.processQueue();
});
this.on('sendingmultiple', function (data, xhr, formData) {
formData.append("UserName", $("#Username").val());
});
this.on('error',
function (file, response) {
console.log(response);
alert(response);
});
}
};
DzDemo.cshtml.cs Page:-
[HttpPost]
public IActionResult OnPostUpload()
{
var data = Request.Form; //This is
return Page();
}
but I get 400 response from server and I am not able to process uploaded file server side Also it wont hot the Upload method on server side. Please help
One thing that will result in 400 using dropzone.js together with Razor Pages is if the AntiforgeryToken is missing from the form.
This is normally injected automatically but removing _viewimports or its taghelpers will prevent this.
To verify just add this line inside the <form/> element or look at the debug console for error messages.
#Html.AntiForgeryToken()
I got it working by setting the headers options
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() }
Certainly, you need to have either at <form /> element or explicitly adding the #Html.AntiForgeryToken() in your page
Add this line in sendingmultiple, it will resolve your pb:
this.on('sendingmultiple', function (data, xhr, formData) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
});

Get the raw values (not html) from AntiForgeryToken()

This beautiful abstraction lets you place #Html.AntiForgeryToken() in cshtml file which is magically expanded to something like;
<input name="__RequestVerificationToken" type="hidden" value="JjMHm5KJQ/qJsyC4sgifQWWX/WmADmNvEgHZXXuB07bWoL84DrmQzE6k9irVyFSJ5VSYqeUIXgl4Dw4NHSotLwflGYTyECzLvrgzbtonxJ9m3GVPgUV7Z6s2Ih/klUB78GN7Fl4Gj7kxg62MEoGcZw175eVwTmkKJ0XrtEfD5KCVvYIMHNY8MT2l+qhltsGL87c9dII42AVoUUQ2gTvfPg==" />
By mvc before the page is served. However my page has some JavaScript making ajax calls which don't include the token even though it's been added to the form. They are currently getting the expected [HttpAntiForgeryException]: A required anti-forgery token was not supplied or was invalid. because they don't have the token. I'm aware I could parse the value out of the DOM but I shouldn't have to. Are there other ways of accessing/getting this value? To be clear, I mean I'd like an overload of the method that returns just the value as a string or some kind of object that has the name and value both.
To provide a bit more context my form and the relevant JS looks a little like this;
<form action="/settings" method="post"><input name="__RequestVerificationToken" type="hidden" value="JjMHm5KJQ/qJsyC4sgifQWWX/WmADmNvEgHZXXuB07bWoL84DrmQzE6k9irVyFSJ5VSYqeUIXgl4Dw4NHSotLwflGYTyECzLvrgzbtonxJ9m3GVPgUV7Z6s2Ih/klUB78GN7Fl4Gj7kxg62MEoGcZw175eVwTmkKJ0XrtEfD5KCVvYIMHNY8MT2l+qhltsGL87c9dII42AVoUUQ2gTvfPg==" /> <fieldset>
<h3>User Settings</h3>
<ul>
<li>
label for="password">Password</label>
Edit
<div id="password_section" class="inlineedit">
<div>
<span for="existing_password">Current password</span> <input autocomplete="off" class="required" id="existing_password" name="existing_password" type="password" />
</div>
<div>
<span for="new_password">New password</span> <input autocomplete="off" class="required" id="new_password" name="new_password" type="password" />
<span id="password_strength" />
</div>
<div>
<span for="confirm_password">Confirm password</span> <input autocomplete="off" class="required" id="confirm_password" name="confirm_password" type="password" />
</div>
<div class="inlinesave">
<input type="button" value="Change" onclick="onPostChangePassword();"/>
Cancel
</div>
</div>
</li>
// a bunch more of these that call their own onPostChangeSetting method
onPostChangePassword() does some input validation then;
if(validPWD && validNewPWD && validConfirmPWD && current_pwd != new_pwd){
// Post the password change
var currentAjaxRequest = $.ajax({
type: "POST",
url: "/settings/preferences/changepassword",
cache: false,
data: {password: $('#new_password').val(), current: $('#existing_password').val(),confirm: $('#confirm_password').val()},
success: password_success,
error: password_error,
dataType: "json"
});
return true;
}
Which ideally (since this is verbatim in a cshtml file) would be modified with something like this;
data: {password: $('#new_password').val(), current: $('#existing_password').val(),confirm: $('#confirm_password').val(),
__RequestVerificationToken:#Html.AntiForgeryValue() }
tl;dr is there a way to interact with the AntiForgeyToken before it's turned into an string of html?
You can use code like this (in for example _Layout.cshtml) to add the AntiForgery header to all Ajax POST requests, or you could adapt it for a specific request. (Code assumes you are using jQuery)
#functions{
private static string TokenHeaderValue()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}
<script type="text/javascript">
$(document).ajaxSend(function (event, jqxhr, settings) {
if (settings.type == "POST") {
jqxhr.setRequestHeader('#ValidateHttpAntiForgeryTokenAttribute.RequestVerificationTokenName',
'#TokenHeaderValue()');
}
});
</script>
On the server side for these Ajax calls, you then want to call the overload of AntiForgery.Validate that takes the cookie and form token, which you would enable by adding this attribute to the action methods called via Ajax (explicitly, or by parent controller, or via a filter)
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,
AllowMultiple = false, Inherited = true)]
public sealed class ValidateHttpAntiForgeryTokenAttribute
: FilterAttribute, IAuthorizationFilter
{
public const string RequestVerificationTokenName = "RequestVerificationToken";
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
ValidateRequestHeader(filterContext.HttpContext.Request);
}
else
{
AntiForgery.Validate();
}
}
private static void ValidateRequestHeader(HttpRequestBase request)
{
string cookieToken = string.Empty;
string formToken = string.Empty;
var tokenValue = request.Headers[RequestVerificationTokenName];
if (string.IsNullOrEmpty(tokenValue) == false)
{
string[] tokens = tokenValue.Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
AntiForgery.Validate(cookieToken, formToken);
}
Look at the Html.AntiForgeryToken() in ILSpy and copy out the code that builds an input tag and create your own extension method that returns only the token string.
Short answer: there is not a native way to do what you're trying to, but as a previous answer states, you can create an HTML helper method.
This guy seems to have a working solution: https://stackoverflow.com/a/16057568/724222

How to use textbox event

I have a registration form and i want to do some thing like this: When user register and enter the username then check on database that this user is already in database or not.That's why when user enter username and move to another field then check it.
So please help me how to solve this and how use textbox events.
As you have not provided any markup i'm assuming the markup like this.
<form id="form1" action="~/something.aspx" method="post">
<label>Username</label>:
<input type="text" id="username" name="username" onblur="validate();"/>
<br/>
<label>Password:</label>
<input type="text" id="password" name="password"/><br/>
<input type="submit" value="submit"/>
</form>
The basic idea is that you need to write some javascript for username field when the focus is out(onblur event)
Here is the javascript for the above piece of code.
<script type="text/javascript">
function validate()
{
//make an ajax call to retrieve the username
$.ajax({
url:'validate.aspx/ValidateUsername',
dataType: 'json',
//... make necessary adjustments in ajax call so as to
//call the web method in validate.aspx page
success: function(data){
if(!data.d){
alert('username already exists !');
document.getElementById('username').focus();
}
}
});
}
</script>
Now defined your webmethod for the ajax call defined.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string ValidateUsername()
{
//Now query the database to check if the username exists.
//If the username exists return 'true' other wise return 'false'
}
Hope this helps.
This is best done using AJAX rather than server-side events, this means you can POST asynchronously for a better UX e.g.
<script type="text/javascript">
var lookupTimer;
$('#username').change(function() {
clearTimer(lookupTimer); // cancel previous lookup if user types again
lookupTimer = setTimeout(function() {
$.post("myServer/checkUsername", { data: $(this).val() }, function(result) {
// handle result
});
}, 1000); // send query after 1 second when user finished typing
});
</script>
<input id="username" type="text" />

mvc PartialView with Dialog Partial View showing html

What I am trying to do is to open up a jquery dialog.
What is happening is that I see the following html text vs the rendering of the form when it tries to open up the PartialView:
<form action="/Plt/FileUpload" method="post"><input data-val="true" data-val-number="The field PlNum must be a number." data-val-required="The PlNum field is required." id="PlNum" name="PlNum" type="hidden" value="36028" /> <div id="errMsg" >
</div>
<p>File upload for Pl# 36028</p>
<input type="file" name="file" />
<input type="submit" value="OK" />
</form>
Here is the controller action:
public ActionResult FileUpload(int id)
{
var model = new FileUpload { PlNum = id };
return PartialView(model);
}
This is what the view looks like for the PartialView:
#model Ph.Domain.Lb.Models.FileUpload
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
#using (Html.BeginForm("FileUpload", "Plts", FormMethod.Post, null))
{
#Html.HiddenFor(a => a.PlNum)
<div id="errMsg" >
#if (TempData["ErrMessage"] != null)
{
#TempData["ErrMessage"]
}
</div>
<p>File upload for Pl# #Model.PlNum</p>
<input type="file" name="file" />
<input type="submit" value="OK" />
}
This is what my ajax call looks like:
var url = '#Url.Action("FileUpload", "Plt")' + '?id=' + encodeURIComponent(rowid);
$.ajax({
url: url,
type: 'GET',
success: function(result) {
if (result.success) {
$('#dialog').dialog('close');
} else {
// refresh the dialog
$('#dialog').html(result);
}
}
To recap, the ajax call does reach the ActionResult but not sure when it tries to show the partial view it shows HTML vs the rendered html.
The issue here is that you are trying to load razor view which has not been rendered into the dialog's innerHTML. Instead what you should be doing is setting href property of the dialog to the URL.Action link, when creating the dialog. See the link below for an example.
http://www.matthidinger.com/archive/2011/02/22/Progressive-enhancement-tutorial-with-ASP-NET-MVC-3-and-jQuery.aspx
The other option, which is not very maintainable IMO, but which will work with way you are currently doing, is to return the raw HTML from the action method.
I think the first solution is better because the controller is not polluted with HTML string concatenation.
jQuery won't let you use a script inside .html(). You can do this by two ways:
Native DOM HTML injection instead:
$('#dialog')[0].innerHTML = result;
.
Or, setting it as a data attribute and loading it manually:
In view:
<form action="/Plt/FileUpload" ...
data-script="#Url.Content("~/Scripts/jquery.validate.min.js")"
... />
In JS:
$('#dialog').html(result);
var dialogScript = $('#dialog').children().first().data("script");
if(!!dialogScript) { $.getScript(dialogScript); };
Reference: http://api.jquery.com/jQuery.getScript/
.
Another way is use the load method, as in:
$("#dialog").load(url, null, function() {
// on a side note, put $("#dialog") in a variable and reuse it
$("#dialog").dialog();
});
Reference: http://api.jquery.com/load/
.
In the very case of jQuery validation, I'd consider adding it to the parent page itself. You'd expect it to be used in fair number of situations.

Categories

Resources