asp.net - 如何使用 ASP.Net/MVC 5/EF 编写拍卖网站代码

标签 asp.net asp.net-mvc html entity-framework razor

我对 ASP.NET 还比较陌生,所以请耐心等待。

我正在尝试使用 MVC 5 和具有 Code-First 的 Entity Framework 为慈善机构编写一个简单的拍卖网站。

我已经创建了一个项目模型和 Controller 。 Item 模型包含标题、描述、起始出价、当前出价、出价数量、最高出价者等字段。

public class Item
{
    public int ID { get; set; }
    public string Code { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    [DisplayName("Starting Bid")] public int StartingBid { get; set; }
    public int Increment {get; set;}
    public int Bids { get; set; }
    [DisplayName("Current Bid")] public int CurrentBid { get; set; }
    public string HighBidder { get; set; }

    public int CurrentOrStartingBid
    { // The price that is displayed next to an item
        get
        {
            return Bids > 0 ? CurrentBid : StartingBid;
        }
    }
    public int NextBid
    { // The minimum amount that is valid for a new bid
        get
        {
            return Bids > 0 ? CurrentBid + Increment : StartingBid;
        }
    }
}

(我在上面的代码中尝试做的是添加这些属性 CurrentOrStartingBid 和 NextBid,它们不打算成为数据库记录的一部分,它们只是衍生属性而不是数据库中的列。所以希望拥有这些因为只读属性会这样做...)

我现在正在查看该项目的详细信息。这显示了商品描述,并且还具有用于出价的表单控件,类似于您在 eBay 上看到的内容。我的问题是如何正确连接出价按钮的逻辑。

我认为在 View 中我应该使用带有提交按钮的 HTML 表单来进行投标。当按下按钮时,这会执行一个 HTTP post,并允许我在 Item Controller 中编写一个当时被调用的方法。

所以我在 View 中的 Razor 代码当前如下所示:

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <div class="form-group">
        <div class="input-group">
            <span class="input-group-addon">£</span>
            <input type="number" class="form-control" value="@Model.NextBid" id="CurrentBid" name="CurrentBid"/>
        </div>
        <br />
        <button type="submit" class="btn btn-primary btn-lg">Place bid</button>
    </div>
}

使用此代码允许我编写具有此签名的 Controller 方法:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Bid([Bind(Include = "ID,CurrentBid")] Item item)

到目前为止这种方法有效。但请注意,在服务器端验证之前,我必须传递项目的 CurrentBid 字段中已出价的金额。这对我来说感觉不太对劲。有没有一种方法可以编写该方法,使其只需要这样的签名?

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Bid(int itemID, int bidAmount)

也许有办法用查询字符串或其他东西来做到这一点?

无论如何,一旦进入该方法,事情又显得有点奇怪了。为了防止过度发布,item 变量中唯一有效的字段是 IDCurrentBid。因此,我然后在 DbContext 中进行查找,找到与该 ID 对应的实际项目并更新它:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Bid([Bind(Include = "ID,CurrentBid")] Item item)
    {
        if (ModelState.IsValid)
        {
            Item i2 = db.Items.Find(item.ID);
            if (item.CurrentBid >= i2.NextBid)
            {
                i2.Bids++;
                i2.CurrentBid = item.CurrentBid;
                i2.HighBidder = HttpContext.User.Identity.Name;
                db.Entry(i2).State = EntityState.Modified;
                db.SaveChanges();
            }
            return View(i2);
        }
        return RedirectToAction("Auction");
    }

这似乎有效。但感觉不对。我认为我在这里遗漏了一些重要的概念/模式。如果任何有经验的 MVC 人员能够勾勒出如何为这个简单的按钮连接客户端/服务器逻辑,那就太好了。 (您也将帮助一项公益事业!)

最佳答案

Is there a way of writing the method so it just takes a signature like this?

[HttpPost] [ValidateAntiForgeryToken] 
public ActionResult Bid(int itemID, int bidAmount)

当然有办法,假设你有一个像这样的简单模型 -

public class Item
{
    public int ID { get; set; }
    public int NextBib { get; set; }
    public int CurrentBid { get; set; }
    public string Description { get; set; }
}

然后您的操作将创建一个项目并发送到 View ,如下所示 -

    public ActionResult BidForm()
    {
        Item i = new Item();
        i.ID = 100;
        i.CurrentBid = 10;
        return View(i);
    }

您的观点如下 -

@model MVC.Controllers.Item

@{
    ViewBag.Title = "BidForm";
}

<h2>BidForm</h2>

@using (Html.BeginForm("Bid", "sample", FormMethod.Post))
{
    @Html.AntiForgeryToken()

    <input type="hidden" name="itemId" value="@Model.ID" />
    <input type="number" class="form-control" value="@Model.NextBib" id="CurrentBid" name="bidAmount" />
    <input type="submit" value="Create" />
}

您的 NextBid 操作将是 -

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Bid(int itemID, int bidAmount)
    {
        return View();
    }

如您所见,我们有一个名称= itemID 的隐藏字段和一个名称= `bidAmount 的输入类型=数字字段。这些被映射到操作的参数,如下所示 -

enter image description here

您可以考虑的一些建议 -

  • 您可以使用 Ajax.BeginForm() 来代替常规的 HTml.BeginForm(),以提供更直观的用户体验。或者,您也可以使用 JQuery POST 操作。
  • 为了防止过度发布,您需要为特定事件(例如提高出价、展示产品等)创建特定的 ViewModel。并且您只为所需事件发布所需的 viewModel,这样就可以防止表单过度发布。

关于asp.net - 如何使用 ASP.Net/MVC 5/EF 编写拍卖网站代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21904200/

相关文章:

asp.net - 如何使所有用户都具有角色(Microsoft ASP.NET Identity EntityFramework 2.0.0-beta1)?

asp.net - 由于启动用户实例进程失败,因此无法生成SQL Server用户实例。连接将关闭

c# - 更新实体时序列不包含元素

c# - Asp.Net MVC 数据注释。如何在 2 个属性相等时获得客户端验证

javascript - Bootstrap :Grid not working in mobile view

javascript - 使用 jQuery 根据 URL 将父菜单项和子子菜单项设置为事件状态

asp.net - 在 asp.net 核心 Web 应用程序 + Angular 项目中更新 Bootstrap

asp.net-mvc - 使用 ASP.NET MVC 将多个 View 返回到一个 ActionResult

html - 如何修复 HTML 表格中的第一列以允许水平滚动?

html - html 中的白色不透明框和调整标题(photoshopped)图片