I have an ajax call posting to a controller.
When I click on a sell button a prompt allows the user to type in the name of a game they want to sell, which is saved in the Video Game Store database.
When the SellFunction is called, however, I'm getting a 404 error.
Here is the JavaScript Code:
function SellFunction() {
var name = prompt('Please enter the game you are selling us:');
alert("Thank you for your business!");
var RandomID = Math.random
RandomID *= 20;
Math.floor(RandomID);
var GameObject = {VideoID: RandomID, Price: 20, Name: name } //now we have to basically just send something easy
//ajax post store name in video game model for the store
$.ajax({
type: "POST",
data: JSON.stringify(GameObject),
url: "index/videogamesale",
dataType: 'json',
contentType: false,
processData: false,
success: function (response) {
if (response != null && response.success) {
alert(response.responseText);
} else {
// DoSomethingElse()
alert(response.responseText);
}
}
});
}
This is the error I am getting:
404 Error
Here is my controller Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace VideoGameStore.Controllers
{
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult VideoGameSale(VideoGame newgame)
{
using (var db = new VideoGameModel())
{
db.Games.Add(newgame);
db.SaveChanges();
foreach (var VideoGame in db.Games)
{
Console.WriteLine(VideoGame.Name);
}
return Json(new { success = true, responseText = "Your
message successfuly sent!" }, JsonRequestBehavior.AllowGet);
}
}
}
}
Here is the VideoGame Model Code:
using System.Data.Entity;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.Infrastructure;
namespace VideoGameStore
{
public class VideoGameModel : DbContext
{
public DbSet<VideoGame> Games { get; set; }
}
public class VideoGame
{
public int VideoID { get; set; }
public int Price { get; set; }
public string Name { get; set; }
}
}
Here is a picture of the table:dbo.VideoTD
I've searched the web, but the problem remains as elusive as ever. Any help would be greatly appreciated. Thank you.
I believe you should change ajax request to this and it'll work out perfectly
$.ajax({
type: "POST",
data: JSON.stringify(GameObject),
url: "Home/VideoGameSale",
method: "POST",
dataType: 'json',
contentType: false,
processData: false,
success: function (response) {
if (response != null && response.success) {
alert(response.responseText);
} else {
// DoSomethingElse()
alert(response.responseText);
}
}});
And router will map it to Controller Home and action VideoGameSale. And since your action VideoGameSale expects a HTTPPOST request it'll work out cause of method: "POST" statement.
Related
I've an async action method that return a partial view.
this action method called from a function with ajax.
my problem : when this method invoked every thing looks good except returned partial view.
I got error 500.
this is my action method Code :
[HttpPost]
public async Task<ActionResult> ChangeStateGroup(int[] lstCustomerServiceId, int newState)
{
int _counter = 0;
try
{
var _isOk = await CommonFunctions.ChangeState(_customerServiceId, _stateId, string.Empty);
if (_isOk)
{
//------do somthing
}
}
TempData[MyAlerts.SUCCESS] = string.Format("succeed Operation {0}", _counter);
}
catch (Exception ex)
{
TempData[MyAlerts.ERROR] = string.Format("Error: {0}", ex.Message);
}
return PartialView("_AlertsPartial");
}
and this is my jquery Code:
function postCustomerChangeStateGroup(lstCustomersId) {
var arrCustomersId = lstCustomersId.split(',');
$.ajax({
type: "POST",
url: "../Customer/ChangeStateGroup",
data: {
lstCustomerServiceId: arrCustomersId,
newState: $("#fk_state").val()
},
success: function (data) {
if (data.indexOf("error") !== -1) {
$("#inlineAlert_Wrapper").append(data);
}
else {
getCustomerReport();
$('#modal-container').modal('toggle');
$("#alert_Wrapper").append(data);
}
},
failure: function (errMsg) {
alert("An Error Accoured: " + errMsg);
}
});
}
Partial views cannot be asynchronous in ASP.NET pre-Core. You can have asynchronous partial views in ASP.NET Core.
So, your options are:
Update to ASP.NET Core.
Remove the asynchronous code and make it synchronous instead.
Error 500 means the error inside of the action.It maybe because ot the empty input parameters. Check them in debugger and if they are empty,
try to use application/json content type,sometimes it works better
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/Customer/ChangeStateGroup",
data: JSON.stringify( {
lstCustomerServiceId: arrCustomersId,
newState: $("#fk_state").val()
}),
success: function (data) {
....
create viewModel
public class ViewModel
{
public int[] lstCustomerServiceId {get; set;}
public int newState {get; set;}
}
and fix the action
public async Task<ActionResult> ChangeStateGroup([FromBody] ViewModel model)
On click of a button will from a partialview 1 below js function will be called and get the data from the controller and will be redirected to another partialview. Since it the controller is in another project and hosted separately, controller is not returning the partialview hence I am redirecting it if the ajax call is success.
$.ajax({
type: "POST",
url: url,
data: JSON.stringify(paramObj),
contentType: "application/json; charset=utf-8",
traditional: true,
success: function (response) {
var userObject = response.internalObject;
window.location.href = url2;
},
error: function (response, status, error) {
if (response.responseText != undefined) {
const obj = JSON.parse(response.responseText);
fnShowMessage(obj.DisplayMessage);
}
}
});
I have the data in "userObject" from the ajax call which needs to be displayed in partialview, but I cannot access it or not sure how to access it.
The assigned value in OnGet() method in "partialview2.cshtml.cs" is able to retain in "partialview2.cshtml" file. But how to get the values which I got from the ajax call in partialview 1 in code behind of partialview 2.
public class UserModel : PageModel
{
[BindProperty]
public UserObject UserObject { get; set; } = new();
public void OnGet()
{
UserObject.UserName = "man";
}
}
You can try to return JsonResult in OnGet:
ajax:
$.ajax({
type: "POST",
url: "/Home/Test",
data: JSON.stringify(paramObj),
contentType: "application/json; charset=utf-8",
traditional: true,
dataType: "json",
success: function (response) {
var userObject = response;
window.location.href = url2;
},
error: function (response, status, error) {
if (response.responseText != undefined) {
const obj = JSON.parse(response.responseText);
fnShowMessage(obj.DisplayMessage);
}
}
});
OnGet handler:
public class UserModel : PageModel
{
[BindProperty]
public UserObject UserObject { get; set; } = new();
public JsonResult OnGet()
{
UserObject.UserName = "man";
return new JsonResult(UserObject);
}
}
I have 2 tables, one is a one to one or one to zero relationship:
public class ComponentText
{
[Key]
public int ComponentTextId { get; set; }
public string ComponentContent { get; set; }
public ComponentTextSection ComponentTextSection { get; set; }
}
public class ComponentTextSection
{
[Key]
public int ComponentTextId { get; set; }
public string SectionTitle { get; set; }
public ComponentText ComponentText { get; set; }
}
I can add row fine using usual .net core posting using a form, here is code which does this:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
var newComponentText = new ComponentText();
if (await TryUpdateModelAsync<ComponentText>(
newComponentText,
"ComponentText",
i => i.ComponentTextSection, i => i.ComponentContent))
{
_context.ComponentText.Add(newComponentText);
await _context.SaveChangesAsync();
}
return RedirectToPage("./Index");
}
I need to update though via ajax, but I am having issues updating the SectionTitle using this current way. It adds the data to the ComponentText table fine but not the ComponentTextSection table. Here is my ajax code:
function saveWindow() {
var ComponentText = { "ComponentText.ComponentTextSection.SectionTitle": $("#ComponentText_ComponentTextSection_SectionTitle").val(),
"ComponentTextId": $("#ComponentText_ComponentTextId").val(),
"ComponentContent": $("#ComponentText_ComponentContent").val()};
$.ajax({
type: 'PUT',
contentType: 'application/json; charset=utf-8',
headers: {
'RequestVerificationToken': '#AntiForgery.GetAndStoreTokens(HttpContext).RequestToken'
},
data: JSON.stringify(ComponentText),
url: '#Url.Page("Edit", "demo4")',
success: function (result) {
closeWindow();
}
});
}
It must be to do with ComponentText.ComponentTextSection.SectionTitle but I have been trying lots of things to get this to work but failing. Does anyone know how to pass a one to one related data via ajax?
Thanks
For the one-to-one model, if you want to use ajax to transfer the complex nested model to the page, you need to create the same as the ComponentText model structure in saveWindow function of ComponentText variable.
<script>
function saveWindow() {
var ComponentText = {
"ComponentTextSection":
{
"SectionTitle": $("#ComponentText_ComponentTextSection_SectionTitle").val(),
},
"ComponentTextId": 1,
"ComponentContent": $("#ComponentText_ComponentContent").val()
};
$.ajax({
type: 'PUT',
contentType: 'application/json; charset=utf-8',
headers: {
'RequestVerificationToken':
'#AntiForgery.GetAndStoreTokens(HttpContext).RequestToken'
},
data: JSON.stringify(ComponentText),
url: '#Url.Page("Edit", "demo4")',
success: function (result) {
closeWindow();
}
});
}
</script>
Here is the test result:
I am working on an Asp Core Project and trying to Ajax post a filepicker blob Javascript Object back to a action to upload the image to Amazon S3. I have tried several different ways and haven't been able to get this to work. It appears to be a model binding issue.
This functionality worked when I was only posting the image url to the action with a string parameter, but I need the filename also.
Issue: model object in action is null
Ajax Code:
function pickit() {
//Start the filepicker
filepicker.pick(
{
//cropRatio: 4 / 3,
////cropMin: [200, 100],
//cropForce: true,
mimetype: 'image/*',
//services: ['CONVERT', 'COMPUTER', 'FACEBOOK', 'FLICKR', 'DROPBOX', 'INSTAGRAM', 'BOX', 'EVERNOTE', 'GMAIL', 'PICASA', 'IMAGE_SEARCH', 'FTP', 'GOOGLE_DRIVE', 'SKYDRIVE', 'URL', 'WEBCAM', 'CLOUDDRIVE', 'IMGUR', 'CLOUDAPP'],
conversions: ['crop', 'rotate', 'filter', 'scale']
},
function (Blob) {
$("#imagespinner").removeClass("invisible")
$.ajax({
type: "POST",
url: '#Url.Action("CreateImage","Photos")',
contentType: 'application/json',
dataType: "json",
data: JSON.stringify(Blob),
success: function (data, textStatus, jqXHR) {
$("#ImageURL").val(data);
var img = document.getElementById("imgImageURL");
img.src = data;
$("#imagespinner").addClass("invisible")
},
error: function (jqXHR, textStatus, error) {
alertify.alert(jqXHR.responseText);
$("#imagespinner").addClass("invisible")
}
});
setTimeout(function () { $('#image-loading-message').fadeOut() }, 500);
},
function (FPError) {
},
function (FPProgress) {
}
);
};
Controller Action:
[HttpPost]
public async Task<JsonResult> CreateImage(FilePickerViewModel model)
{
if (!String.IsNullOrWhiteSpace(model.url))
{
//Code to Upload to S3
return Json("ImageURL");
else
{
Response.StatusCode = 400;
return Json("Url is needed");
}
}
ViewModel:
public class FilePickerViewModel
{
public Int32 id { get; set; }
public String url { get; set; }
public String filename { get; set; }
public Int32 size { get; set; }
public String client { get; set; }
public String mimetype { get; set; }
public Boolean isWriteable { get; set; }
}
Thank you for any help
I figured out the issue, the controller action needs to have the declaration of [FromBody] since this is coming from an ajax post
on MVC3 Page load i have a String in a Model which is should be the JSONObj.
private string CreateJSONObj(Model model)
{ return "{ name: 'test', Items: [{ test: 1 }, { test: 2 }]"; }
Model.jsonModel = CreateJSONObj(model);
Now i want to implement it in my page:
<script>var jsModel = eval('#Model.jsonModel');
var jsonModel = $.toJSON(jsModel);
$.ajax({
url: 'Page/SetJSON/',
type: "POST",
data: jsonModel,
datatype: "json",
contentType: "application/json; charset=utf-8",
success: function () {
$('#test').html('Saved').fadeIn(),
},
error: function () {
$("#test").html("error"),
}
});</script>
But the Controller gets a null Object. If i write the jsonstring into the script everthing is fine.
Should i use eval? But var jsModel = eval('#Model.jsonModel'); has no effect. What is wrong? :-)
You don't need to use a CreateJSONObj method or a jsonModel property on your model. In order to use it in the view you could simply use the JavaScriptSerializer class which will convert the server side model object into a javascript object:
<script type="text/javascript">
var jsModel = #Html.Raw(new JavaScriptSerializer().Serialize(Model));
$.ajax({
url: '#Url.Action("SetJSON", "Page")',
type: 'POST',
data: JSON.stringify(jsModel),
contentType: 'application/json; charset=utf-8',
success: function () {
$('#test').html('Saved').fadeIn();
},
error: function () {
$('#test').html('error');
}
});
</script>
This will successfully send the model to the following controller action:
[HttpPost]
public ActionResult SetJSON(Model model)
{
...
}
where the Model class contains all the necessary information:
public class Model
{
public string Name { get; set; }
public IEnumerable<Item> Items { get; set; }
}
public class Item
{
public int Test { get; set; }
}
and the controller:
public class PageController: Controller
{
// Used to render the view
public class Index()
{
var model = new Model
{
Name = "Test",
Items = new[]
{
new Item { Test = 1 },
new Item { Test = 2 },
}
};
return View(model);
}
// Used to handle the AJAX POST request
[HttpPost]
public ActionResult SetJSON(Model model)
{
...
}
}