【问题标题】:How to make simple calculations using model items and an input from a form in ASP.net MVC 3?如何使用模型项和 ASP.net MVC 3 中的表单输入进行简单计算?
【发布时间】:2012-01-19 08:58:28
【问题描述】:

我是编程和 ASP.net MVC 3 的新手,所以不要对我缺乏这方面的知识感到惊讶。好吧,我想乘以两位小数,一位来自用户填写的表格,另一位来自用户填写的表格decimal 来自 Model 类(从数据库中获取)。

我有两个名为 RATE 和 PROJECTMATERIAL 的模型类。 RATE 类有一个名为 Amount 的项目,它表示 Rate 的数量,而 PROJECTMATERIAL 类有一个名为 quantity 的项目。这些类是相关的,我希望能够说 variable1 = quantity*Rates.amount 并将 variable1 返回到我的索引、删除、详细信息视图。我不想将变量 1 存储到我的数据库中,但我只想在我的视图中显示.....但我不知道如何以及在哪里进行操作

项目材料类的代码..

public class ProjectMaterial
{
    public int ProjectMaterialID { get; set; }

    [Required]
    [Display(Name = "Scope Name")]
    public int? ScopeID { get; set; }

    [Required]
    [Display(Name = "Rate Code")]
    public int? RateID { get; set; }

    [Required]
    [Display(Name = "Quantity")]
    public decimal Quantity { get; set; }


    public virtual Scope Scopes { get; set; }
    public virtual Rate Rates { get; set; }

}

范围类的代码..

public class Rate
{
    public int RateID { get; set; }


    [Required]
    [Display(Name = "Rate Code")]
    public int RateCode { get; set; }

    [Required]
    [Display(Name = "Unit")]
    public string Unit { get; set; }

    [Required]
    [Display(Name = "Description")]
    public string Description { get; set; }

    [Required]
    [Display(Name = "Amount")]
    public decimal Amount { get; set; }

    public virtual ICollection<ProjectMaterial> ProjectMaterials { get; set; }
}

项目控制器类的代码...

public class ProjectMaterialController : Controller
{
    private ContructorContext db = new ContructorContext();

    //
    // GET: /ProjectMaterial/

    public ViewResult Index()
    {
        var projectmaterials = db.ProjectMaterials.Include(p => p.Scopes).Include(p => p.Rates);

        return View(projectmaterials.ToList());
    }



    //
    // GET: /ProjectMaterial/Details/5

    public ViewResult Details(int id)
    {
        ProjectMaterial projectmaterial = db.ProjectMaterials.Find(id);
        return View(projectmaterial);
    }

    //
    // GET: /ProjectMaterial/Create

    public ActionResult Create()
    {
        ViewBag.ScopeID = new SelectList(db.Scopes, "ScopeID", "ScopeName");
        ViewBag.RateID = new SelectList(db.Rates, "RateID", "Unit");
        return View();
    } 

    //
    // POST: /ProjectMaterial/Create

    [HttpPost]
    public ActionResult Create(ProjectMaterial projectmaterial)
    {
        if (ModelState.IsValid)
        {
            db.ProjectMaterials.Add(projectmaterial);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }

        ViewBag.ScopeID = new SelectList(db.Scopes, "ScopeID", "ScopeName", projectmaterial.ScopeID);
        ViewBag.RateID = new SelectList(db.Rates, "RateID", "Unit", projectmaterial.RateID);
        return View(projectmaterial);
    }

    //
    // GET: /ProjectMaterial/Edit/5

    public ActionResult Edit(int id)
    {
        ProjectMaterial projectmaterial = db.ProjectMaterials.Find(id);
        ViewBag.ScopeID = new SelectList(db.Scopes, "ScopeID", "ScopeName", projectmaterial.ScopeID);
        ViewBag.RateID = new SelectList(db.Rates, "RateID", "Unit", projectmaterial.RateID);
        return View(projectmaterial);
    }

    //
    // POST: /ProjectMaterial/Edit/5

    [HttpPost]
    public ActionResult Edit(ProjectMaterial projectmaterial)
    {
        if (ModelState.IsValid)
        {
            db.Entry(projectmaterial).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        ViewBag.ScopeID = new SelectList(db.Scopes, "ScopeID", "ScopeName", projectmaterial.ScopeID);
        ViewBag.RateID = new SelectList(db.Rates, "RateID", "Unit", projectmaterial.RateID);
        return View(projectmaterial);
    }

    //
    // GET: /ProjectMaterial/Delete/5

    public ActionResult Delete(int id)
    {
        ProjectMaterial projectmaterial = db.ProjectMaterials.Find(id);
        return View(projectmaterial);
    }

    //
    // POST: /ProjectMaterial/Delete/5

    [HttpPost, ActionName("Delete")]
    public ActionResult DeleteConfirmed(int id)
    {            
        ProjectMaterial projectmaterial = db.ProjectMaterials.Find(id);
        db.ProjectMaterials.Remove(projectmaterial);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

提前谢谢各位!!真的需要你的帮助。

【问题讨论】:

  • 不清楚您要做什么。您是在尝试计算控制器中的总计并将其传递回视图,还是尝试在控制器中计算总计并将其提供给所有其他视图?
  • 谢谢,我想计算并将结果传递给除编辑视图之外的所有其他视图(索引、详细信息和删除),因为总计将是一个计算值..

标签: asp.net asp.net-mvc-3


【解决方案1】:

看到你说你是 MVC 的新手,我给了你几个选项,并解释了哪个是最好的以及为什么,因为现在最好理解,这样你就不会养成坏习惯,特别是如果你开始构建更大的项目。

您不一定需要创建变量,因为您可以在视图中进行计算。因为您将域模型直接传递给您可以执行的视图(在剃刀中):

@(Model.Quantity * Model.Rates.Amount)

虽然这是最简单的选择,但我不一定会推荐它,因为视图应该是愚蠢的 - 请参阅 ASP.NET MVC: How dumb should my view be?

另一种选择是在控制器中进行计算并在 ViewBag 中传递值,例如:

public ViewResult Details(int id)
{
    ProjectMaterial projectmaterial = db.ProjectMaterials.Find(id);
    ViewBag.Price = projectmaterial.Quantity * projectmaterial.Rates.Amountl
    return View(projectmaterial);
}

然后你可以在你的视图中使用它:

@ViewBag.Price

同样,这很简单,但我不建议这样做,因为 ViewBag 不是强类型 - 请参阅 Is using ViewBag in MVC bad?

您可以在 ProjectMaterial 类上放置一个属性,这是一个很好的解决方案。

public decimal Price
{
    get
    {
        return Quantity * Rates.Amount;
    }
}

但是,如果 Price 是一个仅在您的视图中使用的属性(即您只是显示它),那么它可能不应该在您的域模型中,因为您的域模型就是这样 - 存储和访问原始数据。

也许最好的方法是使用 Price 属性创建特定于您的视图的视图模型(请参阅http://stephenwalther.com/blog/archive/2009/04/13/asp.net-mvc-tip-50-ndash-create-view-models.aspx)。这意味着该属性仅在需要的地方使用,域模型保持不变,您的视图保持不变并且您的域模型不会暴露给您的视图。请参阅Why Two Classes, View Model and Domain Model? 以获得对视图模型的良好解释

【讨论】:

  • 非常感谢!!!我想要最好的方法,现在正在阅读您的链接,我尝试了我之前(昨天)在 ProjectMaterial 类中放置一个属性的方法,但它对我来说效果不佳,每次我创建一个新项目时材料我会得到一个空引用异常,因为 Rates.Amount 是 NULL 我意识到这是一个逻辑错误,因为我知道这是不正确的,因为填充了费率表。再次感谢很多!
【解决方案2】:

您可以将属性添加到您的 ProjectMaterial 模型:

public decimal Price
{
    get
    {
        return Quantity * Rates.Amount;
    }
}

【讨论】:

  • 我之前尝试过,它看起来可以工作,因为所有项目材质视图似乎都很好但每次我创建一个 新的 ProjectMaterial 我收到空引用异常错误。它抱怨 Rates.Amount 为空,这是不正确的,因为我填充了费率表
【解决方案3】:

您可能希望有一个模型函数,其中包含您的 self.rate 实例,以及从您的视图传递的 self.material 项目。或者,您可以单独计算每个视图中的乘法值。

无论哪种方式,您都应该能够将乘法值 (variable1) 的副本存储在视图的包中,并将其传递给每个视图,而无需将其保存在数据库中。

ViewBag.variable1 = rate*material
return View()

【讨论】:

    【解决方案4】:
    @(int.Parse(variable) * your value) 
    

    【讨论】:

    • 当我们需要在 razor 视图中将字符串值相乘时,我们可以这样使用。
    【解决方案5】:

    除了所有答案之外,您还可以在 model class 中使用 Data Format String,在 View 中使用 Html Helper 来维护数字类型显示结果中的格式,方法是修改Controller 中的返回属性。

    在模型类中应用格式,在控制器中进行值转换并保持视图标准,目的是实现关注点分离(SoC),以便于维护和控制代码。

    考虑这个例子:

    产品类属性

    [Display(Name = "Max Disc %")]
    [DisplayFormat(DataFormatString = "{0:P1}", ApplyFormatInEditMode = true)]
    public decimal MaxDiscountRate { get; set; }
    

    产品控制器

            [HttpGet]
            public ActionResult Details(int id)
            {
                if (id == 0)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Products products = _uow.Products.GetById(id);
                if (products == null)
                {
                    return HttpNotFound();
                }
                else
                {
                    products.MaxDiscountRate /= 100;
                }
    
                return View(products);
            }
    

    产品详情查看

    <div class="detail">
       <h5 class="text-teal">@Html.DisplayNameFor(model => model.MaxDiscountRate)</h5>
       <span class="text-peru">@Html.DisplayFor(model => model.MaxDiscountRate)</span>
    </div>
    

    【讨论】:

      猜你喜欢
      • 2019-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多