API控制器和底层服务 - 参数验证的责任

时间:2016-12-15 18:22:30

标签: c# web-services rest design-patterns asp.net-web-api

也许这是微不足道的情况,但这对我来说很困惑,我需要澄清如何以正确的方式处理它。

为了简单起见,模型就像休闲一样:

User * - * Project

(用户被分配到许多项目,项目分配了许多用户)。

我创建了rest控制器,用于分配和解雇特定项目的用户:

…\Api\v1\Projects\{projectId}\users\{userId}

允许两个http动作:

  • 将现有用户分配给项目和
  • 的POST操作
  • DELETE以从项目中解除用户。 (不确定它是否是正确的解决方案,但它适用于我)。

API Controller使用服务层来执行这些操作。服务接口是休闲的:

void projectService.assignUser(int projectId, int userId)
void projectService.dismissUser(int projectId, int userId)

服务使用dbContext来执行这些操作。

问题1:哪个元素应该负责检查projectId和userId是否正确? 恕我直言,最好把这个逻辑放在服务层,因为它可以重用。

问题2:如果projectId和userid不正确,这些方法应该返回什么(例如:项目/用户不存在或不允许分配)?

我的第一个想法是返回null值,但我认为它不是很有意义。主要是因为如果enitiyId不正确,服务中的类似方法返回null。例如: projectService.getProject(projectId) - 如果项目不存在则返回null

第二个是回归布尔。假是至少有一个参数不正确

第三个想法是抛出带有消息的ArgumentException。它似乎很好但它使api控制器能够捕获异常。

2 个答案:

答案 0 :(得分:1)

Q1)我认为将它们放在服务层是一个有效的想法,我可以想到许多场景,你可能想要重用这些方法。

Q2)这个有点棘手,受制于意见,但这实际上取决于你想要如何与业务逻辑层(这些方法可能存在的地方)进行通信。我最近使用的一种方法是创建一个特殊的服务消息类,以便在服务层和业务层之间进行通信(我认为你可以使用它在表示层和服务层之间进行通信,以及一些变化)。课程可能如下所示:

public class BusinessLogicMessage<T> where T : new()
    {
        public BusinessLogicMessage(T result)
        {
            Result = result;
            Status = BusinessLogicStatus.Success;
            Message = string.Empty;
        }

        public BusinessLogicMessage(T result, BusinessLogicStatus status, string message)
        {
            Result = result;
            Status = status;
            Message = message;
        }

        public BusinessLogicStatus Status { get; set; }
        public string Message { get; set; }
        public T Result { get; set; }
    }

    public class BusinessLogicMessage
    {
        public BusinessLogicMessage()
        {
            Status = BusinessLogicStatus.Success;
            Message = string.Empty;
        }

        public BusinessLogicMessage(BusinessLogicStatus status, string message)
        {
            Status = status;
            Message = message;
        }

        public BusinessLogicStatus Status { get; set; }
        public string Message { get; set; }
    }

    public enum BusinessLogicStatus
    {
        Success,
        Failure,
        Warning
    }

因此,如果您的方法成功,您只需返回类的默认构造函数,其状态为Success。如果发生故障或其他情况,您可以添加详细信如果您需要为该方法返回特殊结果对象,可以将其附加到结果

我的两分钱。

更新以获得更好的答案。

答案 1 :(得分:0)

答案1:您应该继续将projectId / userId验证到服务层以供重用,并在需要的地方调用这些函数。

答案2: 根据有效/无效的projectId / userId创建一个json。它可能包含与用户或项目相关的详细信息,以防两者都有效并返回错误消息和错误ID(对于无效项目,例如1,对于无效用户,则为2)。

a)JsonObject projectService.assignUser(int projectId,int userId)

例如:
有效的ID(两者):

  

{&#34; stat&#34;:&#34; ok&#34;,&#34; userId&#34;:&#34; userId Here&#34;,&#34; projectId&#34;: &#34; projectId在这里&#34;}

无效的项目ID:

  

{&#34; errorMsg&#34;:&#34;无效的项目ID&#34;,&#34; stat&#34;:&#34;失败&#34;,&#34;错误&#34; :1}

b)JsonObject projectService.dismissUser(int projectId,int userId)

有效的ID(两者):

  

{&#34; stat&#34;:&#34; ok&#34;}

无效的用户ID:

  

{&#34; errorMsg&#34;:&#34;无效的用户ID&#34;,&#34; stat&#34;:&#34;失败&#34;,&#34;错误&#34; :2}