【问题标题】:Improve nameof() in C#改进 C# 中的 nameof()
【发布时间】:2022-07-08 19:39:07
【问题描述】:

我正在使用带有 C# 的 ASP.NET Core MVC。

我这样定义我的模型:

public class Student
{
      public class FirstName {get;set;}
      public int? PriorityId { get; set; }
}

public class Priority
{
    [Key]
    public int PriorityId { get; set; }
    [Required]
    [Display(Name = "Priority Name")]
    public string Name { get; set; }        
}

所以它会像这样为优先级下拉列表呈现 HTML。

<div class="col-sm-4">
     <div class="form-group">
         <label for="Student_PriorityId">Priority<span style="color:red"> *</span></label>
         <select class="form-control valid" id="Student_PriorityId" name="Student.PriorityId" aria-invalid="false">
              <option selected="selected" value="0">Select</option>
              <option value="3">High</option>
              <option value="1">Low</option>
              <option value="2">Medium</option>
         </select>
         <span class="text-danger field-validation-error" data-valmsg-for="Student.PriorityId" data-valmsg-replace="true">Priority is required.</span>
     </div>
</div>

问题

当我要检查自定义验证时,消息不会显示在下拉列表下方。

if (obj.Student.PriorityId <= 0)
{
    ModelState.AddModelError(nameof(obj.Student.PriorityId), "Priority is required.");
}

当我尝试使用nameof() 时,上面的代码不起作用。

但是当我删除nameof() 并写下如下字符串时。它在下拉菜单下方显示错误消息。

if (obj.Student.PriorityId <= 0)
{
    ModelState.AddModelError("Student.PriorityId", "Priority is required.");
}

有什么方法可以改进C#的nameof()函数?

【问题讨论】:

  • 不行,你不能改进nameof()函数。
  • nameof() 将返回您输入的变量的名称,该名称为"PriorityId"nameof() 在这里提供什么好处?如果您已经知道必须将什么变量作为参数放入,那么您也知道结果...
  • 您能否详细说明您的“无效”是什么意思?您是否收到任何编译或运行时错误?或者观察到的行为不像预期的那样?哪个是预期的?
  • 如果要使用nameof( )实现"Student.PriorityId",可以将第一个AddModelError( )输入值扩展为:$"{nameof(obj.Student)}.{nameof(obj.Student.PriorityId)}"
  • @derpirscher nameof() 没有被使用,因为人们不知道结果(它总是一个常数),但因为它确保在重构​​的情况下值保持正确。

标签: c# validation asp.net-core-mvc


【解决方案1】:

我不确定这是一种改进,但您可以编写如下方法:

public static string NameOf<T>(Expression<Func<T>> func)
{
    return string.Join(".", func.ToString().Split('.').Reverse().Take(3).Reverse().ToArray());
}

那么你的代码就是

if (obj.Student.PriorityId <= 0)
{
    ModelState.AddModelError(NameOf( () => obj.Student.PriorityId ), "Priority is required.");
}

在这种情况下,NameOf 将返回“obj.Student.PriorityId”。

【讨论】:

    【解决方案2】:

    以下是如何使用CallerArgumentExpressionAttribute 替代nameof 的示例。

    using Microsoft.AspNetCore.Mvc.ModelBinding;
    using System.Runtime.CompilerServices;
    public static class ModelStateExtensions
    {
        public static void AddModelErrorEx(
            this ModelStateDictionary modelStateDictionary,
            object _,
            string errorMessage,
            [CallerArgumentExpression("_")] string expr = "")
            => modelStateDictionary.AddModelError(expr, errorMessage);
    }
    

    用法:

    ModelState.AddModelErrorEx(Student.PriorityId, "Priority is required.")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 2017-11-24
      • 2016-12-25
      • 2017-10-06
      • 2018-11-01
      相关资源
      最近更新 更多