首页 > 解决方案 > 如何从控制器向数据库添加两个特定值?

问题描述

在下面的代码中,我试图获取当前登录用户的用户名和他们订购到数据库的项目的详细信息,但它不起作用,因为我根本不知道将用户名和选择的项目添加到数据库。

[HttpPost]
        public async Task<IActionResult> AddOrder([Bind("Id,Name,Location,Price,Description")] Order order)
        { 
            var user = _userManager.GetUserName(User);

            if (ModelState.IsValid)
            {
                _context.Add(order + user);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(order);
        } 

任何有关如何实现此功能的帮助将不胜感激。(以下是我项目中的更多代码)

我的整个 PackagesController

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using JTMajorProject.DataAccess.Models;
using JTMajorProject.Models;
using JTMajorProject.DataAccess;
using Microsoft.AspNetCore.Identity;

namespace JTMajorProject.Controllers
{
    //[Route("/packages")]
    public class PackagesController : Controller
    {
        private readonly JTMajorProjectContext _context;
        private readonly UserManager<IdentityUser> _userManager;

        public PackagesController(JTMajorProjectContext context, UserManager<IdentityUser> userManager)
        {
            _context = context;
            _userManager = userManager;
        }


        // GET: Packages
        public async Task<IActionResult> Index(string searchString, string searchLocation)
        {

            var packages = from p in _context.Package
                         select p;

            if (!String.IsNullOrEmpty(searchString))
            {
                packages = packages.Where(s => s.Name.Contains(searchString));
            }

            if (!String.IsNullOrEmpty(searchLocation))
            {
                packages = packages.Where(s => s.Location.Contains(searchLocation));
            } 

            return View(await packages.ToListAsync());
        }

        // GET: Packages/Details/5
        public async Task<IActionResult> Details(int? id)
        {
            if (id == null)
            {   
                return NotFound(); 
            } 

            var package = await _context.Package
                .FirstOrDefaultAsync(m => m.Id == id);
            if (package == null)
            {
                return NotFound();
            }

            return View(package);
        }

        public async Task<IActionResult> Order(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var package = await _context.Package
                .FirstOrDefaultAsync(m => m.Id == id);
            if (package == null)
            {
                return NotFound();
            }

            return View(package);
        }

        // GET: Packages/Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: Packages/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("Id,Name,Location,Price,Description")] Package package)
        {
            if (ModelState.IsValid)
            {
                _context.Add(package);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(package);
        }

        [HttpPost]
        public async Task<IActionResult> AddOrder([Bind("Id,Name,Location,Price,Description")] Order order)
        { 
            var user = _userManager.GetUserName(User);

            if (ModelState.IsValid)
            {
                _context.Add(order + user);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(order);
        }

        // GET: Packages/Edit/5
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var package = await _context.Package.FindAsync(id);
            if (package == null)
            {
                return NotFound();
            }
            return View(package);
        }

        // POST: Packages/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int id, [Bind("Id,Name,Location,Price,Description")] Package package)
        {
            if (id != package.Id)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(package);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!PackageExists(package.Id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(package);
        }

        // GET: Packages/Delete/5
        public async Task<IActionResult> Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var package = await _context.Package
                .FirstOrDefaultAsync(m => m.Id == id);
            if (package == null)
            {
                return NotFound();
            }

            return View(package);
        }

        // POST: Packages/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            var package = await _context.Package.FindAsync(id);
            _context.Package.Remove(package);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }

        private bool PackageExists(int id)
        {
            return _context.Package.Any(e => e.Id == id);
        }
    }
}

订购流程的 Razor 页面,其中包含将数据发送到控制器的表单

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
@using System.Security.Claims

@model JTMajorProject.DataAccess.Models.Package

@{
    ViewData["Title"] = "Order";
}

<div>
    <section style="background-color: black; height: 150px; width: 1520px"></section>
</div>
<div class="row">
    <div class="col-md-4">
        <form asp-action="AddOrder"> 
            <input type="hidden" asp-for="Id" />
            <h1 style="margin-top:50px">Your Order: </h1>

            <div style="margin: 20px;">
                <h4>
                    Account - @if (SignInManager.IsSignedIn(User))
                    {
                        <a id="manage" class="text-black" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage" style="color: black">
                            @UserManager.GetUserName(User)
                        </a>
                    }
                    else
                    {
                        <a style="margin:20px">Currently not signed in.</a>
                    }
                </h4>
            </div>


            <div style="margin: 30px">
                <h4 style="margin-top: 50px;">Package</h4>
                <hr />
                <dl class="row">
                    <dt class="col-sm-2">
                        @Html.DisplayNameFor(model => model.Name)
                    </dt>
                    <dd class="col-sm-10">
                        @Html.DisplayFor(model => model.Name)
                    </dd>
                    <dt class="col-sm-2">
                        @Html.DisplayNameFor(model => model.Location)
                    </dt>
                    <dd class="col-sm-10">
                        @Html.DisplayFor(model => model.Location)
                    </dd>
                    <dt class="col-sm-2">
                        @Html.DisplayNameFor(model => model.Price)
                    </dt>
                    <dd class="col-sm-10">
                        @Html.DisplayFor(model => model.Price)
                    </dd>
                    <dt class="col-sm-2">
                        @Html.DisplayNameFor(model => model.Description)
                    </dt>
                    <dd class="col-sm-10">
                        @Html.DisplayFor(model => model.Description)
                    </dd>
                </dl>
            </div>
            @if (SignInManager.IsSignedIn(User))
            {
                <div style="margin: 30px">
                    <button type="submit">Confirm Order</button>
                </div>
            }
            else
            {
                <a style="margin:30px; font-weight:bold; font-size: 25px;">Please sign in to purchase this order.</a>
            }

    </form>
        </div>
    </div>
            <div style="margin: 30px">
                <a asp-action="Index">Back to Package List</a>
            </div>



标签: c#databaseasp.net-core-mvc

解决方案


似乎您正试图在您的IdentityUser表格和Order表格之间建立一对多的关系。为此,您需要在定义Order模型时添加外键。

public class Order
{
    [Key]
    public string Id { get; set; }
    public string Name { get; set; }
    public string Location { get; set; }
    public double Price { get; set; }
    public string Description { get; set; }

    //This sets the relation
    public string IdentityUserId {get; set; }
    [ForeignKey("IdentityUserId ")]
    public IdentityUser IdentityUser { get; set; }
}

有关 ASP 中关系的更多信息:https ://docs.microsoft.com/en-us/ef/core/modeling/relationships

建立关系后,您应该能够使用将订单链接到下订单的用户的 FK 将订单添加到表中。您的控制器应如下所示:

[HttpPost]
public async Task<IActionResult> AddOrder([Bind("Id,Name,Location,Price,Description")] Order order)
{ 
    //Gets the ID of the currently logged user
    string userId = _userManager.GetUserId(HttpContext.User);

    if (ModelState.IsValid)
    {
        var newOrder = New Order
        {
            Id = order.Id,
            Name = order.Name,
            Location = order.Location,
            Price = order.Price,
            Description = order.Description,

            //Here you make the relation between the order and the user that made it
            IdentityUserId = userId
        }

        _context.Add(newOrder);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(order);
}

推荐阅读