Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何实现在不同控制器中调用另一个操作的控制器操作?_C#_Asp.net Web Api_Asp.net Core_Repository Pattern - Fatal编程技术网

C# 如何实现在不同控制器中调用另一个操作的控制器操作?

C# 如何实现在不同控制器中调用另一个操作的控制器操作?,c#,asp.net-web-api,asp.net-core,repository-pattern,C#,Asp.net Web Api,Asp.net Core,Repository Pattern,我正在使用ASP.NET core创建一个Web API,对于如何发布到审核/日志表感到困惑 有两个表,一个事件表和一个事件日志表。如果用户创建了一个新事件,那么它将向事件和事件日志表中添加一个条目。如果用户编辑事件的名称/描述,还将在事件日志表中创建一个新条目。请注意,事件日志表在结构上与事件表基本相同 事件表 +------------------+ | Event Table | +------------------+ | Id | | EventN

我正在使用ASP.NET core创建一个Web API,对于如何发布到审核/日志表感到困惑

有两个表,一个事件表和一个事件日志表。如果用户创建了一个新事件,那么它将向事件和事件日志表中添加一个条目。如果用户编辑事件的名称/描述,还将在事件日志表中创建一个新条目。请注意,事件日志表在结构上与事件表基本相同

事件表

+------------------+
|   Event Table    |
+------------------+
| Id               |
| EventName        |
| EventDescription |
| CreatorId        |
+------------------+
+------------------+
| Event Log Table  |
+------------------+
| Id               |
| EventId          |
| EventName        |
| EventDescription |
| EditorId         |
| TimeEdited       |
+------------------+
事件日志表

+------------------+
|   Event Table    |
+------------------+
| Id               |
| EventName        |
| EventDescription |
| CreatorId        |
+------------------+
+------------------+
| Event Log Table  |
+------------------+
| Id               |
| EventId          |
| EventName        |
| EventDescription |
| EditorId         |
| TimeEdited       |
+------------------+
目前,我的Web API中有两个单独的控制器,分别用于两个表,即事件控制器和事件日志控制器

当前发生的情况:当有事件的post/put时,它将创建事件日志控制器的实例,并调用post方法来创建事件日志,传递新创建/更新的事件日志对象

这里有一些简化的代码

在EventController.cs中..

public IActionResult PostEvent([FromBody] Event event)
{
    _context.Event.Add(event);
    _context.Event.SaveChanges();

    EventLogController logController = new EventLogController(context);
    logController.PostEventLog(event);

    return Ok();
}
public IActionResult PostEventLog([FromBody] Event event)
{
    var eventLog = _mapper.Map<EventLog>(event);
    eventLog.TimeEdited = DateTime.Now;

    _context.EventLog.Add(eventLog);
    _context.EventLog.SaveChanges();

    return Ok();
}
在EventLogController.cs中…

public IActionResult PostEvent([FromBody] Event event)
{
    _context.Event.Add(event);
    _context.Event.SaveChanges();

    EventLogController logController = new EventLogController(context);
    logController.PostEventLog(event);

    return Ok();
}
public IActionResult PostEventLog([FromBody] Event event)
{
    var eventLog = _mapper.Map<EventLog>(event);
    eventLog.TimeEdited = DateTime.Now;

    _context.EventLog.Add(eventLog);
    _context.EventLog.SaveChanges();

    return Ok();
}
public IActionResult PostEventLog([FromBody]事件)
{
var eventLog=_mapper.Map(事件);
eventLog.TimeEdited=DateTime.Now;
_context.EventLog.Add(EventLog);
_context.EventLog.SaveChanges();
返回Ok();
}
虽然这很好,但就目前而言,我很担心这是否是最佳实践(仅仅为了调用一种方法而创建一个新的控制器似乎不好)。请注意,我不想向每个控制器发送两个单独的API调用,这可能很有用。我希望在添加/更新条目后创建事件日志

在我看来,我可以采取其他方法……

public IActionResult PostEvent([FromBody] Event event)
{
    _context.Event.Add(event);
    _context.Event.SaveChanges();

    EventLogController logController = new EventLogController(context);
    logController.PostEventLog(event);

    return Ok();
}
public IActionResult PostEventLog([FromBody] Event event)
{
    var eventLog = _mapper.Map<EventLog>(event);
    eventLog.TimeEdited = DateTime.Now;

    _context.EventLog.Add(eventLog);
    _context.EventLog.SaveChanges();

    return Ok();
}
  • 创建存储库/服务?用于将事件日志添加到数据库并将其注入EventController。虽然这确实允许我避免创建控制器,但我听说在asp.net核心中创建存储库是不必要的抽象

  • 在EventController中的PostEvent操作中添加事件日志条目,而不创建控制器或存储库/服务。但是,这意味着操作方法正在处理两个请求

  • 继续使用当前方法,但只注入EventLog控制器,而不是创建新实例

  • 至于我认为我做不到的事情…

    public IActionResult PostEvent([FromBody] Event event)
    {
        _context.Event.Add(event);
        _context.Event.SaveChanges();
    
        EventLogController logController = new EventLogController(context);
        logController.PostEventLog(event);
    
        return Ok();
    }
    
    public IActionResult PostEventLog([FromBody] Event event)
    {
        var eventLog = _mapper.Map<EventLog>(event);
        eventLog.TimeEdited = DateTime.Now;
    
        _context.EventLog.Add(eventLog);
        _context.EventLog.SaveChanges();
    
        return Ok();
    }
    
    我认为我不能在数据库本身中创建触发器,因为创建事件条目没有包含足够的信息来创建事件日志(因为数据库不知道编辑器)

    我也不认为我可以使用RedirectToAction,因为它是一个post请求,需要在体内发送一些东西


    所以我的问题是:在每次创建/更新相关实体时,创建日志/审核条目的正确方法是什么?

    我更喜欢创建一个单独的类,就像您在“其他方法1”中提到的那样。你可以从多个地方打电话


    一般来说,如你所知,许多方法都是可能的。经验法则应该始终是:“控制器应该只控制,它不应该自己做工作。”这意味着控制器应该只知道调用什么来做工作。如果遵循这一原则,您可以将实际代码放在一个单独的类中,然后根据需要从一个或多个控制器的多个位置调用它。

    一个单独的类将是您的朋友。当然,如果实现非常简单,并且应用程序不是很大,那么创建最简单的解决方案没有什么错。无论如何,调用另一个控制器将耦合您的代码

    我举了一个简单的例子,我通常喜欢类似的例子

    EventService.cs
    公共类事件服务
    {
    私人IEventLogger记录器;
    公共事件服务(IEventLogger记录器)
    {
    this.logger=记录器;
    }
    内部作废新增(事件@事件)
    {
    //这是用于持久化事件的代码。
    //例如,context.SaveChanges(@event)
    //或者任何你想要的。
    //当事件被保存时,我调用了
    //实现IEventLogger接口。它只是一个简单的
    //接口来引入日志(Event@Event)-方法。
    // 
    //创建此服务时,您可以传递日志
    //实现。您也可以使用不同的方式进行传递
    //如果构造器不适合您,请使用正确的实现。
    如果(记录器!=null){
    this.logger.Log(@event);
    }
    }
    }
    
    事件控制器
    #在控制器中,您可以使用这样的服务。
    #当然,不需要在操作内部创建服务
    #但我只想举个简单的例子。
    公共IActionResult PostEvent([FromBody]Event@Event)
    {
    IEventLogger logger=新事件记录器();
    EventService EventService=新的EventService(记录器);
    eventService.AddNew(@event);
    返回Ok();
    } 
    
    为什么要使用服务? 它不应该是一个了解实现细节的控制器。如前所述,控制器只是控制

    这里,我介绍了一个负责处理持久化事件的服务。您可以使用
    上下文
    初始化服务。我保持示例的简单性,不引入任何抽象概念,但您可能已经明白了

    当调用AddNew(event)方法时,服务将了解您的业务规则。在您的案例中,我认为“日志记录”是您需要的规则之一。您希望保留更改日志,以便使用该服务时,始终可以使用日志记录器

    ieventloger
    是一个简单的界面。当您实现它时,您可以在其中使用相同的上下文,然后处理日志记录