首页 文章

ASP.NET MVC Core通过Ajax Post向控制器发布了一个字符串

提问于
浏览
1

尝试使用Ajax将字符串值发送到Home控制器 . 在Ajax调用之后会出现错误(在Google Chrome开发人员工具中): 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 我've tried the url part from all the responses (as of now) to this post, the url turns out to be correct but I'仍然得到 warningerror ,如下图所示 . NOTE :图像中控制器和操作的名称不同,但它们位于VS2015中名为Controllers的默认文件夹中 . 我没有创建任何子文件夹等 . 此外,这是在开发机器 Win10 with VS2015 ASP.NET Core 1.1, IIS EXPRESS . 请点击图片以便能够清楚地看到该消息 .

UPDATE 2

为了使我的问题更容易理解,我在official ASP.NET MVC Core tutorial之后创建了一个测试ASP.NET核心应用程序 . 请参阅下面的错误图片 .

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] . 注意:我最后只添加了一个额外的按钮 <button type="button" id="testid" class="Savebtn">Test</button>Ajax .

@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]

enter image description here

3 回答

  • 2

    如果在剃刀模板引擎中没有定义JavaScript代码,那么之前发布的所有答案似乎都非常不灵活且无法正常工作,这在捆绑/缩小cs / js文件时会产生效果 .

    尝试将此添加到 Headers 部分内的 _Layout.cshtml 文件中

    <head>
        ...
        <base href="~/"/>
    </head>
    

    这会将基本URL设置为您的应用程序主页 . 所有相对网址都将附加到此基本网址 . 这也适用于jQuery请求,因为较新的版本确实尊重base-Tag,因此当您的JavaScript代码不在razor(* .cshtml)模板中呈现时应该可以正常工作 .

    更新

    好...

    • 问题是您的控制器操作需要Movie模型 . 你不能发一个简单的字符串 .

    • 您发布的是MVC操作,它返回一个视图,没有数据 . 您不能将此用于ajax,因为它将返回HTML代码 . 对于Ajax,您需要Json对象 .

    你的行动看起来应该是这样的

    [Route("api/[controller")]
    public class MovieController {
        [HttpPost("{id}")]
        public async Task<IActionResult> Edit(int id, [FromBody] Movie movie)
        {
    
        }
    }
    

    Note: 通常对于RESTful服务,您使用PUT更新/替换资源,使用POST来创建它 . 见Relationships between URL and HTTP Methods .

    和你的jQuery / Ajax请求一样

    // 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

    改变你的网址

    url: '@Url.Action("TestAction", "Home")'
    

    始终使用 Url.Action helper方法生成操作方法的完全限定URL . 你可以查看更多细节并重载here

  • 2

    应该是(如果你在js文件中):

    $.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');
        }
    });
    

    或者像Stephen Muecke说的那样(如果你的脚本在View上):

    $.ajax({
        url: '@Url.Action("TestAction", "Home")', //note this line
        data: "Test data",
        type: 'POST',
        success: function (obj) {
            alert('Suceeded');
        }
    });
    

相关问题