ASP.NET Core Web应用程序 - 传递ID和模型以编辑操作

发布于 2025-02-02 16:19:55 字数 6310 浏览 4 评论 0原文

我是ASP.NET MVC的新手。我的项目是使用带有存储库和单位工程模式的干净体系结构(我知道这些天的存储库模式在很大程度上是有争议的,这对这个问题无关)。它具有ASP.NET核心Web API项目和一个单独的MVC核心项目。

在API中,我有一个UpdateModel操作,期望在URL中传递ID,并且模型在身体中传递:

        [HttpPut("update-book/{id}")]
        public IActionResult UpdateBook(int id, [FromBody] ComicBookViewModel book)
        {
            try
            {
                var b = _unitOfWork.ComicBooks.GetBookById(id);
                if (b != null)
                {
                    _unitOfWork.ComicBooks.UpdateBook(id, book);
                    return Accepted(book);
                }
                else
                {
                    return NotFound($"Book with id {id} not found");   
                }
            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, $"{ex.Message}");
            }
        }

在MVC应用中,我有一个页面,该页面调用API并显示来自数据库。每个实体都有一个编辑按钮。编辑按钮在控制器中调用此操作:

        [HttpGet]
        public async Task<IActionResult> EditComic(int id)
        {
            ComicBookWithAuthorsAndCharactersViewModel? model = null;
            string uri = $"https://localhost:5001/api/ComicBook/get-book-by-id/{id}";
            HttpClient client = _httpClientFactory.CreateClient(
                    name: "ComicbookInventory.Api");

            var request = new HttpRequestMessage(HttpMethod.Get, uri);
            var response = await client.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                model = await response.Content.ReadFromJsonAsync<ComicBookWithAuthorsAndCharactersViewModel>();
            }
            return View(model);
        }

然后显示一个简单的编辑页面:

@model ComicBookInventory.Shared.ComicBookWithAuthorsAndCharactersViewModel

@{
    ViewData["Title"] = "EditComic";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Edit @Model?.Title</h1>

<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="EditComic">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Id" class="control-label"></label>
                <input asp-for="Id" class="form-control" />
                <span asp-validation-for="Id" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Description" class="control-label"></label>
                <input asp-for="Description" class="form-control" />
                <span asp-validation-for="Description" class="text-danger"></span>
            </div>
            <div class="form-group form-check">
                <label class="form-check-label">
                    <input class="form-check-input" asp-for="IsRead" /> @Html.DisplayNameFor(model => model.IsRead)
                </label>
            </div>
            <div class="form-group">
                <label asp-for="DateRead" class="control-label"></label>
                <input asp-for="DateRead" class="form-control" />
                <span asp-validation-for="DateRead" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Rating" class="control-label"></label>
                <input asp-for="Rating" class="form-control" />
                <span asp-validation-for="Rating" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="CoverUrl" class="control-label"></label>
                <input asp-for="CoverUrl" class="form-control" />
                <span asp-validation-for="CoverUrl" class="text-danger"></span>
            </div>
            <div class="form-group">
                @*<input type="hidden" name="Id" value="@Model.Id" />*@
                <input type="submit" value="Save" class="btn btn-primary"/>
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="GetAllComics">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

编辑页面底部的提交按钮,然后在控制器中调用此操作:

        [HttpPost]
        public ActionResult EditComic(ComicBookWithAuthorsAndCharactersViewModel model)
        {
            var userId = Request.HttpContext.Request;
            string uri = $"https://localhost:5001/api/ComicBook/update-book/{id}";
            HttpClient client = _httpClientFactory.CreateClient(
                    name: "ComicbookInventory.Api");

            var put = client.PutAsJsonAsync<ComicBookWithAuthorsAndCharactersViewModel>(uri, model);
            put.Wait();
            var result = put.Result;
            if (result.IsSuccessStatusCode)
            {
                return RedirectToAction("GetAllComics");
            }
            return View(model);
        }

我的问题是,当执行最后一个操作时,我需要将ID和模型传递回API。我该怎么做?

我不一定要寻找答案,只是让某人指向正确的方向。正如我所说,我是ASP.NET Core MVC应用程序的新手。只需要一些方向。

我没有任何编译时错误,但是如果我在 下面的Editcomic(comicbookWithAuthorSandCharActerSviewModel模型)方法,结果设置为http 400:

var result = put.result设置为http 400。

我的代码在这里。 /comicbookInventoryApp“ rel =“ nofollow noreferrer”> https://github.com/rnemeth90/comicbookbookinventoryapp

我目前正在从事主要分支。

I am relatively new to asp.net mvc. My project is using clean architecture with repository and UnitOfWork patterns (I know repository pattern is largely debated these days, and that is no concern for this question). It has an asp.net core web api project and a separate MVC core project.

In the api, I have an updateModel action that expects an id to be passed in the URL, and the model to be passed in the body:

        [HttpPut("update-book/{id}")]
        public IActionResult UpdateBook(int id, [FromBody] ComicBookViewModel book)
        {
            try
            {
                var b = _unitOfWork.ComicBooks.GetBookById(id);
                if (b != null)
                {
                    _unitOfWork.ComicBooks.UpdateBook(id, book);
                    return Accepted(book);
                }
                else
                {
                    return NotFound(
quot;Book with id {id} not found");   
                }
            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, 
quot;{ex.Message}");
            }
        }

In the MVC app, I have a page that calls the API and displays a list of entities from the database. Each entity has an edit button. The edit button calls this action in the controller:

        [HttpGet]
        public async Task<IActionResult> EditComic(int id)
        {
            ComicBookWithAuthorsAndCharactersViewModel? model = null;
            string uri = 
quot;https://localhost:5001/api/ComicBook/get-book-by-id/{id}";
            HttpClient client = _httpClientFactory.CreateClient(
                    name: "ComicbookInventory.Api");

            var request = new HttpRequestMessage(HttpMethod.Get, uri);
            var response = await client.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                model = await response.Content.ReadFromJsonAsync<ComicBookWithAuthorsAndCharactersViewModel>();
            }
            return View(model);
        }

and then displays a simple edit page:

@model ComicBookInventory.Shared.ComicBookWithAuthorsAndCharactersViewModel

@{
    ViewData["Title"] = "EditComic";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Edit @Model?.Title</h1>

<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="EditComic">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Id" class="control-label"></label>
                <input asp-for="Id" class="form-control" />
                <span asp-validation-for="Id" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Description" class="control-label"></label>
                <input asp-for="Description" class="form-control" />
                <span asp-validation-for="Description" class="text-danger"></span>
            </div>
            <div class="form-group form-check">
                <label class="form-check-label">
                    <input class="form-check-input" asp-for="IsRead" /> @Html.DisplayNameFor(model => model.IsRead)
                </label>
            </div>
            <div class="form-group">
                <label asp-for="DateRead" class="control-label"></label>
                <input asp-for="DateRead" class="form-control" />
                <span asp-validation-for="DateRead" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Rating" class="control-label"></label>
                <input asp-for="Rating" class="form-control" />
                <span asp-validation-for="Rating" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Genre" class="control-label"></label>
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="CoverUrl" class="control-label"></label>
                <input asp-for="CoverUrl" class="form-control" />
                <span asp-validation-for="CoverUrl" class="text-danger"></span>
            </div>
            <div class="form-group">
                @*<input type="hidden" name="Id" value="@Model.Id" />*@
                <input type="submit" value="Save" class="btn btn-primary"/>
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="GetAllComics">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

The submit button at the bottom of the edit page then calls this action in the controller:

        [HttpPost]
        public ActionResult EditComic(ComicBookWithAuthorsAndCharactersViewModel model)
        {
            var userId = Request.HttpContext.Request;
            string uri = 
quot;https://localhost:5001/api/ComicBook/update-book/{id}";
            HttpClient client = _httpClientFactory.CreateClient(
                    name: "ComicbookInventory.Api");

            var put = client.PutAsJsonAsync<ComicBookWithAuthorsAndCharactersViewModel>(uri, model);
            put.Wait();
            var result = put.Result;
            if (result.IsSuccessStatusCode)
            {
                return RedirectToAction("GetAllComics");
            }
            return View(model);
        }

My question is, when this last action is executed, I need to pass the id and model back to the api. How can I accomplish this?

I'm not necessarily looking for answers, just for someone to point me in the right direction. As I said, I'm new to asp.net core MVC apps.. just need some direction.

I don't get any compile-time errors, but if I set a breakpoint in the
EditComic(ComicBookWithAuthorsAndCharactersViewModel model) method below, the result is set to http 400 on this line:

var result = put.Result is set to Http 400.

My code is here: https://github.com/rnemeth90/ComicBookInventoryApp

I'm working on the main branch currently.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

稳稳的幸福 2025-02-09 16:19:55

我刚才弄清楚了。我必须在视图模型中标记一些属性为无效,然后重新运行EF核心迁移以更新DB模式。在此视图中,我不会将这些值从应用程序中将其传递回API(因此不会将它们传递给EF Core)。因此,这就是为什么我得到400个。字符和权威现在可以在此类中无效。似乎有效。需要进一步测试。

I figured it out just now. I had to mark some properties as nullable in my view model and then re-run the EF core migration to update the db schema. I am not passing these values back to the api from the application in this view (and therefore not passing them to EF core). So that is why I was getting the 400. CharacterIds and AuthorIds are now nullable in this class. Seems to work. Need to test it some more.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文