问题
Trying to send a string value to Home controller using Ajax. Following Ajax call gives the error (in Google Chrome developer tool): Failed to load resource: the server responded with a status of 404 (Not Found)
:
$.ajax({
url: 'Home/TestAction',
data: "Test data",
type: 'POST',
success: function (obj) {
alert('Suceeded');
}
});
UPDATE:
After I've tried the url part from all the responses (as of now) to this post, the url turns out to be correct but I'm still getting a warning
and an error
as shown in the image below. NOTE: The names of the controller and action in the image are different but they are in the same default folder called Controllers in VS2015. I've not created any subfolder etc. Also, this is on development machine Win10 with VS2015 ASP.NET Core 1.1, IIS EXPRESS
. Please click on the image to be able to see the message in clear.
UPDATE 2:
To make my question simpler to understand, I've created a test ASP.NET Core app following this official ASP.NET MVC Core tutorial. Please see the error image below.
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,Genre,Price,ReleaseDate,Title")] Movie movie)
{
if (id != movie.ID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(movie);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(movie.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction("Index");
}
return View(movie);
}
View [..\views\movies\Index.cshtml]. NOTE: I've only added an extra button <button type="button" id="testid" class="Savebtn">Test</button>
and the Ajax
call at the end.
@model MovieGenreViewModel
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<form asp-controller="Movies" asp-action="Index" method="get">
<p>
<select asp-for="movieGenre" asp-items="Model.genres">
<option value="">All</option>
</select>
Title: <input type="text" name="SearchString">
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.movies[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.movies[0].Price)
</th>
<th>
@Html.DisplayNameFor(model => model.movies[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.movies[0].Title)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.movies) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
<button type="button" id="testid" class="Savebtn">Test</button>
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
@section scripts
{
<script>
$(document).ready(function () {
$('.Savebtn').click(function () {
$.ajax({
url: '@Url.Action("Edit", "Movies")',
data: "Test data",
type: 'POST', //POST if you want to save, GET if you want to fetch data from server
success: function (obj) {
// here comes your response after calling the server
alert('Suceeded');
},
error: function (obj) {
alert('Something happened');
}
});
});
});
</script>
}
Error [in Google Chrome developer tool]:
回答1:
All of the answers posted before seem to be very unflexible and not working, when the JavaScript code is not defined within the razor template engine, which is counter productive when you bundle/minify your cs/js files.
Try adding this to your _Layout.cshtml
file inside the header section
<head>
...
<base href="~/"/>
</head>
This sets the base url to your application home. All relative urls will be appended to this base url. This should also work with jQuery requests as the newer versions do respect the base-Tag and hence should work well when your JavaScript code is not rendered within the razor (*.cshtml) templates.
Update
Well...
- problem is that your controller action expects a Movie model. You can't send a simple string.
- What you posted is an MVC action, it returns a view, no data. You can't use this for ajax, because it will return HTML Code. For Ajax you need Json object.
Your action should look something like
[Route("api/[controller")]
public class MovieController {
[HttpPost("{id}")]
public async Task<IActionResult> Edit(int id, [FromBody] Movie movie)
{
}
}
Note: Usually for RESTful services you use PUT to update/replace a resource and POST to create it. See Relationships between URL and HTTP Methods.
and your jQuery/Ajax request like
// example movie object, this depends on the definition of your model class on the server
var movie = {
id: 1,
name: "Back to the Future",
genre: "Sci-Fi"
};
$.ajax({
url: 'api/movies/'+movie.id,
data: movie,
type: 'POST',
success: function (obj) {
alert('Suceeded');
}
});
回答2:
change you url to
url: '@Url.Action("TestAction", "Home")'
Always use Url.Action
helper method to Generates a fully qualified URL to an action method. You can check more detail and overload here
回答3:
Is should be (if you in js file):
$.ajax({
url: '/Home/TestAction', //note this line (You get your url from root this way, not relative like you do)
data: "Test data",
type: 'POST',
success: function (obj) {
alert('Suceeded');
}
});
Or like Stephen Muecke said (if your script on View):
$.ajax({
url: '@Url.Action("TestAction", "Home")', //note this line
data: "Test data",
type: 'POST',
success: function (obj) {
alert('Suceeded');
}
});
来源:https://stackoverflow.com/questions/41712836/asp-net-mvc-core-posting-just-a-string-to-controller-via-ajax-post