【问题标题】:How do I properly format a readonly @TextBoxFor Value as currency?如何正确地将只读的 @TextBoxFor 值格式化为货币?
【发布时间】:2015-12-31 18:32:02
【问题描述】:

我有一个维修订单域模型。这里只是它的三个属性:

    [DataType(DataType.Currency)]
    [DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true)]
    [DisplayName("Labor Total")]
    [ScaffoldColumn(true)]
    [ReadOnly(true)]
    public virtual decimal LaborTotal => Labor.Sum(p => p.LineTotal);

    [DataType(DataType.Currency)]
    [DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true)]
    [DisplayName("Parts Total")]
    [ScaffoldColumn(true)]
    [ReadOnly(true)]
    public virtual decimal PartsTotal => RepairOrderParts.Sum(p => p.LineTotal);

    [DataType(DataType.Currency)]
    [DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true)]
    [DisplayName("Order Total")]
    [ScaffoldColumn(true)]
    [ReadOnly(true)]
    public virtual decimal OrderTotal => LaborTotal + PartsTotal;

在搭建控制器和视图后,我修改了 Edit.cshtml,使其包含我的三个货币属性:

    <div class="form-group">
        @Html.LabelFor(model => model.LaborTotal, htmlAttributes: new {@class = "control-label col-md-2"})
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.LaborTotal, new {@class = "form-control", @readonly = "readonly", Value = string.Format("{0:C}", Model.LaborTotal) })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.PartsTotal, htmlAttributes: new {@class = "control-label col-md-2"})
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.PartsTotal, new {@class = "form-control", @readonly = "readonly", Value = string.Format("{0:C}", Model.PartsTotal) } )
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.OrderTotal, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.OrderTotal, new { @class = "form-control", @readonly = "readonly", Value = string.Format("{0:C}", Model.OrderTotal) } )
        </div>
    </div>

如果我删除该行的 Value = string.Format… 部分。所有 vales 显示正常,我可以进行更改并保存记录。留下Value = string.Format…,我的值格式正确,但我无法保存任何更改。它抱怨所有三行都不是数字(没有逗号或美元符号)。我取出了 Validate 行,但这并没有帮助,也没有将其切换到 @EditorFor

提前致谢,

编辑:

工作但未格式化货币:

    <div class="form-group">
        <label class="control-label col-md-2" for="LaborTotal">Labor Total</label>
        <div class="col-md-10">
            <input class="form-control" data-val="true" data-val-number="The field Labor Total must be a number." data-val-required="The Labor Total field is required." id="LaborTotal" name="LaborTotal" readonly="readonly" type="text" value="75.00" />
        </div>
    </div>

    <div class="form-group">
        <label class="control-label col-md-2" for="PartsTotal">Parts Total</label>
        <div class="col-md-10">
            <input class="form-control" data-val="true" data-val-number="The field Parts Total must be a number." data-val-required="The Parts Total field is required." id="PartsTotal" name="PartsTotal" readonly="readonly" type="text" value="0" />
        </div>
    </div>

    <div class="form-group">
        <label class="control-label col-md-2" for="OrderTotal">Order Total</label>
        <div class="col-md-10">
            <input class="form-control" data-val="true" data-val-number="The field Order Total must be a number." data-val-required="The Order Total field is required." id="OrderTotal" name="OrderTotal" readonly="readonly" type="text" value="75.00" />
        </div>
    </div>

尝试格式化货币:

    <div class="form-group">
        <label class="control-label col-md-2" for="LaborTotal">Labor Total</label>
        <div class="col-md-10">
            <input Value="$75.00" class="form-control" data-val="true" data-val-number="The field Labor Total must be a number." data-val-required="The Labor Total field is required." id="LaborTotal" name="LaborTotal" readonly="readonly" type="text" value="75.00" />
        </div>
    </div>

    <div class="form-group">
        <label class="control-label col-md-2" for="PartsTotal">Parts Total</label>
        <div class="col-md-10">
            <input Value="$0.00" class="form-control" data-val="true" data-val-number="The field Parts Total must be a number." data-val-required="The Parts Total field is required." id="PartsTotal" name="PartsTotal" readonly="readonly" type="text" value="0" />
        </div>
    </div>

    <div class="form-group">
        <label class="control-label col-md-2" for="OrderTotal">Order Total</label>
        <div class="col-md-10">
            <input Value="$75.00" class="form-control" data-val="true" data-val-number="The field Order Total must be a number." data-val-required="The Order Total field is required." id="OrderTotal" name="OrderTotal" readonly="readonly" type="text" value="75.00" />
        </div>
    </div>

【问题讨论】:

  • 你能分享渲染的html吗?即你从这把剃须刀得到的 html
  • 够了吗,@lazy?我被指责在我的问题中投入过多。
  • 感谢您发布 HTML。看起来如果我们使用 Editor For 它应该将 html 输入设置为十进制,然后使用日期格式字符串将正确格式化该值。此外,对于格式化,您可以使用此 stackoverflow 示例中给出的 CSS - stackoverflow.com/questions/5080451/…

标签: c# razor format


【解决方案1】:

当您在 htmlAttributes 中执行 Value = string.Format("{0:C}", Model.LaborTotal) 时,razor 将执行 C# 代码并返回值 "$86.34",(假设您的 LaborTotal 属性的值是 86.34345M ) 这是一个字符串。所以你的视图生成的标记将是

<input value="$86.34"  id="LaborTotal" name="LaborTotal" readonly="readonly" type="text">

省略了其他一些 html 属性

因此,当您将其发回时,该字符串无法分配给小数属性。您可以做的是从输入字段中删除货币符号并将其显示在标签中。

<label>$</label>
@Html.TextBoxFor(model => model.LaborTotal, 
       new {@class = "form-control", @readonly = "readonly", 
       Value = string.Format("{0:0.00}", Model.LaborTotal)})

如果您仍然希望 dot net 为您提供货币符号而不是硬编码,您可以创建一个新的视图模型,它具有您的十进制属性的字符串版本并使用它,当它被回发时,您可以转换它使用Parse 方法重载之一转换为十进制。

此外,您似乎仅将此字段用于显示目的(用户未编辑此值,在这种情况下,我建议读取现有实体并仅更新您要更新的字段(在这种情况下,您不想更新 LaborTotal)。

要做到这一点,并避免过度发布,最好的解决方案是为您的视图创建一个视图模型

public class LabelTotalSummaryVm
{
  public int Id {set;get;}
  public decimal LaborTotal {set;get;}      
  public string SomeEditableProperty { set;get;}
}

在你的 GET 操作中

public ActionResult View(int id)
{
  var vm = new LabelTotalSummaryVm { Id=id };
  var e = yourDbContext.RepairOrders.FirstOrDefault(s=>s==Id);
  if(e!=null) 
  {
     vm.LaborTotal =e.LaborTotal ;
     vm.SomeEditableProperty =e.SomeEditableProperty ;
  }
  return View(vm);
}

在你看来,

@model LabelTotalSummaryVm
@using(Html.BeginForm())
{
  @Html.TextBoxFor(s=>s.SomeEditableProperty);
  <label>$ @Model.LaborTotal</label>
  @Html.HiddenFor(s=>s.Id)
  <input type="submit" />
}

在您的帖子中,您将只更新您希望更新的属性

[HttpPost]
public ActionResult View(LabelTotalSummaryVm model)
{
      var e = yourDbContext.RepairOrders.FirstOrDefault(s=>s==Id);
      if(e!=null) 
      {       
         vm.SomeEditableProperty =model.SomeEditableProperty ;
         yourDbContext.Entry(e).State=EntityState.Modified;
         yourDbContext.SaveChanges();
         return RedirectToAction("SomeSuccess");
      }
      return View(vm);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    • 2011-06-29
    • 2020-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多