代码之家  ›  专栏  ›  技术社区  ›  Martin Hansen Lennox

如何在控制器操作上使用可选的通用参数?

  •  0
  • Martin Hansen Lennox  · 技术社区  · 7 年前

    我正在使用一个用于各种实体的BaseController。他们可能有 int string 主键,由表示 <TPk> .

    例如。:

    [HttpGet]
    public ActionResult Create(TPk id)
    {
        return View();
    }
    

    在我尝试使用之前一切都很好 TPk 作为 可选择的 参数。

    [HttpGet]
    public ActionResult Create(TPk id = default(TPk))
    {
        return View();
    }
    

    “可选”部分似乎不起作用。

    所以 /controller/create/2 很好,但是 /controller/create 给出以下错误:

    “参数字典包含一个不可为空类型”System.Int32“的参数”ID“的空条目,用于方法”System.Web.MVC.ActionResult Create(Int32)“”

    该选项与 利息 一串 我可以打电话给 /控制器/创建/2 /控制器/创建 .

    但使用泛型类型参数 TPK公司 ,无参数路由不再工作。


    我试过的

    我试过把 TPK公司 参数可以为空,但不会编译:

    类型“tpk”必须是不可为空的值类型,才能用作泛型类型或方法“nullable”中的参数“t”。


    我尝试更改参数名 id altId 根据 this question -没有欢乐


    我尝试以完全相同的方式调用相同的方法,但使用了非泛型参数。例如。:

    public virtual async Task<ActionResult> Create(int id = default(int))
    

    这很管用。


    我尝试创建一个简单的新项目来隔离此代码。(如下所示)。这仍然会给无参数版本带来问题。


    简单代码测试

    控制器

    public abstract class BaseController<TPk> : Controller
    {
        public ActionResult Create(TPk id = default(TPk))
        {
            return View();
        }
    }
    
    
    public class NewsController : BaseController<int>
    {
    
    }
    

    实体类

    public class BaseDataModel<TPk>
    {
        public TPk Id { get; set; }
        public string Title { get; set; }
    }
    
    public class PageDataModel : BaseDataModel<string>
    {
        public string Content { get; set; }
    }
    
    public class NewsDataModel : BaseDataModel<int>
    {
        public DateTime Date { get; set; }
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Christian Gollhardt    7 年前

    也许可以通过深入研究路由(方法选择)和ModelBinder源代码来解决这个问题…

    DuplicateRecord

    // duplicates existing record if id is passed in, otherwise from scratch
    


    • 如果您需要加入,会发生什么?
    • 你如何处理错误?
    • 层叠删除/限制删除?

    public async Task<IActionResult> CreateProduct(CancellationToken ct, ProductCreateModel model)
    {
        var result = await _productService.CreateAsync(model, ct);    
        //create response with some helpers... probably some ActionFilters
    }