how to hit controller action from a-usercontrol-ascx using ajax request - javascript

this is the ascx user control , i am trying to do ajax request then hit the controller but i have a problem and error message i can not find this CreateSubscribe/Create 404 (Not Found) error message.
any advice
<input type="text" id="subscribe-form-email" name="email" class="bg-transparent text-small no-margin border-color-medium-dark-gray" placeholder="Enter your email...">
<button id="button-subscribe-newsletter" type="button" class="btn btn-arrow-small position-absolute border-color-medium-dark-gray">
<i class="fa fa-caret-right no-margin-left"></i></button>
<script type="text/javascript">
$("#button-subscribe-newsletter").click(function () {
debugger
if ($('#subscribe-form-email').val().length > 0)
{
var dataToPost = {
subscriberemail: $("#subscribe-form-email").val(),
}
$.ajax({
dataType: "json",
url: 'CreateSubscribe/Create',
type: 'post',
data: JSON.stringify(dataToPost),
success: function (result) {
if (result) {
$("#Subscribe-Area").hide();
$("#Success-Message").show();
}
else {
$("#Failed-Message").show();
}
},
error:function
(err)
{
alert(err.message);
}
});
}
});
</script>
this is the controller
public class CreateSubscribeController : Controller
{
// GET: CreateSubscribe
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Create(string subscriberemail)
{
var keys = new Dictionary<string, string>() {
{ "Email",subscriberemail }
};
if (SitefinityWebApp.Helpers.SitefinityHelper.CreateSubscriberAndAddToMailingList(MailList.Maillist, subscriberemail))
{
SitefinityWebApp.Helpers.SitefinityHelper.SendEmailByTemplate(EmailTemplates.SubscribeEmail, subscriberemail, keys);
return Json(new { val = true }, JsonRequestBehavior.AllowGet);
}
else
{
return Json(new { val = false }, JsonRequestBehavior.AllowGet);
}
}

Related

Razor autocomplete doesen't work when submitted

I'm having some problem with the autocomplete on my Razor project. Everytime it returns me error/failure. Maybe it could be even a stupid thing but I'm new to ASP so it would be difficult for me to notice.
Javascript Code
$(function () {
$('#searchCliente').autocomplete({
source: function (request, response) {
$.ajax({
url: '/Index?handler=Search',
data: { "term": request.term },
type: "POST",
success: function (data) {
response($.map(data, function (item) {
return item;
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
select: function (e, i) {
$("#idCliente").val(i.item.val);
$("#idFatt").val(i.item.val);
},
minLength: 3
});
});
Page Model Code
public IActionResult OnPostSearch(string term)
{
var clientefatt = (from cliente in this.context.Arc_Anagrafiche
where cliente.RagioneSociale.StartsWith(term)
select new
{
label = cliente.RagioneSociale,
val = cliente.IdAnag
}).ToList();
return new JsonResult(clientefatt);
}
HTML Code
<input asp-for="intervento.Cliente" class="form-control" id="searchCliente" />
<input asp-for="intervento.IdClienteFatturazione" class="form-control" id="idCliente" type="hidden" />
Perhaps the issue is related to the AntiForgeryToken, try to add the XSRF-TOKEN property in the request header before sending the Ajax request.
Please refer to the following samples and modify your code:
Add AddAntiforgery() service in the ConfigureServices method:
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
In the Ajax beforeSend event, get the RequestVerificationToken from the hidden field, and set the request header:
#page
#model RazorPageSample.Pages.AutocompleteTestModel
<form method="post">
#Html.AntiForgeryToken()
<input type="text" id="txtCustomer" name="label" />
<input type="hidden" id="hfCustomer" name="val" />
<br /><br />
<input type="submit" value="Submit" asp-page-handler="Submit" />
<br />
</form>
#section Scripts{
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.10.0.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.ui/1.9.2/jquery-ui.min.js" type="text/javascript"></script>
<link href="https://ajax.aspnetcdn.com/ajax/jquery.ui/1.9.2/themes/blitzer/jquery-ui.css" rel="Stylesheet" type="text/css" />
<script type="text/javascript">
$(function () {
$("#txtCustomer").autocomplete({
source: function (request, response) {
$.ajax({
url: '/AutocompleteTest?handler=AutoComplete',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: { "prefix": request.term },
type: "POST",
success: function (data) {
response($.map(data, function (item) {
return item;
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
position: { collision: "flip" },
select: function (e, i) {
$("#hfCustomer").val(i.item.val);
},
minLength: 1
});
});
</script>
}
Code in the .cshtml.cs file:
public IActionResult OnPostAutoComplete(string prefix)
{
var customers = new List<Customer>()
{
new Customer(){ ID=101, Name="Dillion"},
new Customer(){ID=102, Name = "Tom"},
new Customer(){ ID=103, Name="David"}
};
return new JsonResult(customers.Where(c=>c.Name.ToLower().StartsWith(prefix.ToLower())).Select(c=> new { label = c.Name, val = c.ID }).ToList());
}
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
}
Then, the screenshot as below:
Reference: jQuery AutoComplete in ASP.Net Core Razor Pages
Maybe you shall assign the ajax datatype property, and also change the "type" property from post to get, as below:
$.ajax({
url: '/Index?handler=Search',
data: { "term": request.term },
datatype: 'json'
type: "GET",
success: function (data) {
response($.map(data, function (item) {
return item;
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
Also in the Model code you can try one of the following,
as when returning json the JSONRequestBehavior property shall be specified as AllowGet:
return Json(new {clientefatt = clientefatt}, JsonRequestBehavior.AllowGet);
Change the Model code method's return type to JsonResult, as below
public JsonResult OnPostSearch(string term){
return new JsonResult(clientefatt);
}
Most probably the first options, since you're using .net core, will give you an error "ASP.NET Core - The name 'JsonRequestBehavior' does not exist in the current context"

After 1st json call working but 2nd json call not working till page get refresh

Hi I am working in one application and in that I am using json call to decline the request.
Now when I am going to decline request one by one I find one issue that on single page when I am decline one request it get declined but when I am going to decline 2nd request it is not declining that request.
In case if I need to decline 2nd request in that case 1st I need to refresh that page and then after I am able to decline that 2nd request.
Below is the screen shot
My view page code.
In script tag
function declinestudentrequest() {
var StudentRequestId = document.getElementById('hdstatusstudentrequestid').value;
var StatusId = document.getElementById('hdstatusdecline').value;
$.ajax({
url: '/Account/declinestudentrequest',
type: 'GET', // You can use GET
data: { 'StudentRequestId': StudentRequestId },
dataType: "json",
context: this,
cache: false,
success: function (data) {
if (data == "Success") {
$("#GetStatusMessage_" + StudentRequestId).css({ "display": "block" });
$('#div_p_' + StudentRequestId).text("You have decline for student Response");
$("#GetReqdec_" + StudentRequestId).hide();
}
else { alert('Some Error'); }
},
error: function (request) {
console.log(request);
}
});
}
Design
#if (Convert.ToInt16(item.StatusId) == 1)
{
<div id="GetStatusMessage_#item.StudentRequestId" style="display:none;">
<p id="div_p_#item.StudentRequestId">Waiting for student Response.</p>
</div>
<div id="GetReqdec_#item.StudentRequestId">
#using (Html.BeginForm("TutorDashboard", "AccountController"))
{
#Html.TextAreaFor(model => item.Description, new { #class = "form-control", #placeholder = "Please describe how you can help.", #id = "txtdescription" })
<br />
<span>Hourly rate :</span>
#Html.EditorFor(model => item.Ratedummy, new
{
htmlAttributes = new { #class = "form-control", placeholder = "Price", maxlength = 10, id = "txtrate" }
})
<p class="text-right">
<input type="hidden" id="hdstatusrequest" name="hdstatusrequest" value='2' />
<input type="hidden" id="hdstatusdecline" name="hdstatusdecline" value='3' />
<input type="hidden" id="hdstatusstudentrequestid" name="hdstatusstudentrequestid" value='#item.StudentRequestId' />
<input type="button" onclick="return declinestudentrequest();" class="btn btn-default btn-hire decline_btn" value="Decline" />
</p>
}
</div>
}
My Account controller Side code
public ActionResult declinestudentrequest(string StudentRequestId)
{
string result = "";
try
{
if (User.Identity.IsAuthenticated)
{
TutorStudentRequest tsr = new TutorStudentRequest();
tsr.StudentRequestId = Convert.ToInt32(StudentRequestId);
tsr.Rate = 0;
tsr.StatusId = 3;
db.TutorStudentRequests.Add(tsr);
db.SaveChanges();
result = "Success";
}
else
{
return RedirectToAction("Index", "Home");
}
}
catch (Exception ex)
{
result = "Error";
throw ex;
}
return Json(result, JsonRequestBehavior.AllowGet);
}
Why my second request for decline is not working ?
The issue is resolved as there was an issue of id getting conflicting so I have tried some thing like.
On view page I made changes as
<input type="hidden" id="hdstatusstudentrequestid_#item.StudentRequestId" name="hdstatusstudentrequestid" value='#item.StudentRequestId' />
<input type="button" onclick="return declinestudentrequest('#item.StudentRequestId');" class="btn btn-default btn-hire decline_btn" value="Decline" />
and in script
function declinestudentrequest(id) {
var StudentRequestId = document.getElementById('hdstatusstudentrequestid_'+id).value;
var StatusId = document.getElementById('hdstatusdecline').value;
$.ajax({
url: '/Account/declinestudentrequest',
type: 'GET', // You can use GET
data: { 'StudentRequestId': StudentRequestId },
dataType: "json",
context: this,
cache: false,
success: function (data) {
if (data == "Success") {
$("#GetStatusMessage_" + StudentRequestId).css({ "display": "block" });
$('#div_p_' + StudentRequestId).text("You have decline for student Response");
$("#GetReqdec_" + StudentRequestId).hide();
}
else { alert('Some Error'); }
},
error: function (request) {
console.log(request);
}
});
}
Here I am making uniqueness from while passing studentrequestid as unique

How to know if Ajax Post was a success?

Current Code Example:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ActionName(ViewModel model)
{
if (!ModelState.IsValid)
{
return PartialView(model);
}
var result = //something
if (result.Succeeded)
{
return PartialView(model);
}
AddErrors(result);
return PartialView(model);
}
Form Html
#model ViewModel
#using (Html.BeginForm("ChangePassword", "Manage", FormMethod.Post, new { #id = "Form"}))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary("", new { #class = "text-danger" })
//Controls
<div class="form-group">
<input type="submit" value="Save" data-loading-text="Loading..." class="btn btn-default" />
</div>
}
JQuery code Template:
$("#Form").on('click', ".btn", function (e) {
e.preventDefault();
$.ajax({
url: "Something/ActionName",
//datatype: "text",
data: $('#Form').serialize(),
type: "POST",
success: function (data) {
$("#Form").html(data);
},
error: function (result) {
alert(result);
}
});
});
Now how can I know if an AJAX POST was a success and at the same time also returning the Partial View? Return PartialView to reset Form controls and clear error incase there were on the last post.
We can create a Json result with a var and RenderPartialView as string value. Please see MVC Return Partial View as JSON :
if (data.Result == "Success") {
alert("Data Saved");
}
$("#Form").html(data);
However, is there an easier option I am missing?

Return javascript to view from controller

I am returning javascript from controller to view through ajax. but it gives me failure message, my code is given below.
My controller is
public ActionResult GetJava()
{
if (Request.IsAjaxRequest())
{
return JavaScript("<script>alert(\"some message\")</script>");
}
else
{
return View();
}
}
and view is
#{
ViewBag.Title = "GetJava";
Scripts.Render("~/bundles/jquery");
}
<h2>GetJava</h2>
<div><input type="button" value="GetJava" onclick="Getjavascript()" /></div>
<script type="text/javascript">
function Getjavascript() {
$.ajax({
url: '#Url.Action("GetJava","BindingJson")',
dataType: 'applicaiton/javascript;charset=utf-8',
type: 'Get',
data: 'script',
success: function (status) { status.value },
error: function (status) { alert("failure") }
});
}
</script>
What could be the possible issue?
You can create a script with src to your action, as suggested in this answer: https://stackoverflow.com/a/6778069/4251546
var script = $('<script />', {src: '#Url.Action("GetJava","BindingJson")'});
$(document).append(script)

ASP.NET MVC: Redirecting errors in partial to main view

I have a partial that I refresh via Ajax.
View Javascript:
$("#SelectedId").change(function () {
var id = $("#SelectedId").val();
if (id > 0) {
$.ajax({
url: "/Home/Refresh",
data: { id: id },
type: "POST",
success: function (result) {
$('#partialHolder').html(result);
}
});
}
});
Refresh action:
[HttpPost]
public ActionResult Refresh(int id)
{
HomeViewModel model = new HomeViewModel();
model.id = id;
ViewBag.id = model.id;
PrepareModel(ref model);
return PartialView("~/Views/PartialView.cshtml", model);
}
This works well, except that when an error (such as an HTTP exception) occurs, the error view is sent to the partial when I want it to be shown as the main view.
Error action:
public ActionResult Error(string message)
{
ViewBag.Message = message;
return View();
}
I have tried using Javascript (both in the view and returned by the controller) to redirect the browser, however both are buggy and I assume bad practice.
Try as
$("#SelectedId").change(function () {
var id = $("#SelectedId").val();
if (id > 0) {
$.ajax({
url: "/Home/Refresh",
data: { id: id },
type: "POST",
success: function (result) {
$('#partialHolder').html(result);
},
error: function(result){
//call new action
}
});
}
});
Assuming Error() returns a complete view (with layout and script/css), you could always try completely overwriting your document:
success: function (result) {
$('#partialHolder').html(result);
},
error: function(xhr) {
if(xhr.responseText) {
var newDoc = document.open("text/html", "replace");
newDoc.write(xhr.responseText);
newDoc.close();
}
}
This will effectively overwrite your entire dom and will cause you to lose everything that was on the page.
Credits for document rewrite to this answer
Try something like this
in your action
[HttpPost]
public ActionResult Refresh(int id)
{
try
{
HomeViewModel model = new HomeViewModel();
model.id = id;
ViewBag.id = model.id;
PrepareModel(ref model);
return PartialView("~/Views/PartialView.cshtml", model);
}
catch
{
return PartialView("~/Views/PartialView.cshtml", null);
}
}
so in your ajax success
if (result != null) {
//do your stuff
} else {
// the controller action returned a partial
$('#divInYourMain').html("Error 123");
}
I managed to solve this in a similar way to theLaw's answer, by using a try/catch block and the Content helper method to return a simple string which triggers a redirect.
Refresh Action:
[HttpPost]
public ActionResult Refresh(int id)
{
try
{
HomeViewModel model = new HomeViewModel();
model.id = id;
ViewBag.id = model.id;
PrepareModel(ref model);
return PartialView("~/Views/PartialView.cshtml", model);
}
catch
{
return Content("error");
}
}
View Javascript:
$("#SelectedId").change(function () {
var id = $("#SelectedId").val();
if (id > 0) {
$.ajax({
url: "/Home/Refresh",
data: { id: id },
type: "POST",
success: function (result) {
if (result == "error") {
location.replace("#Url.Action("General", "Error")");
}
else {
('#partialHolder').html(result);
}
}
});
}
});

Categories