You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# MVC5控制器含return的重复代码复用问题(DRY原则)

解决带return语句的重复Controller代码优化问题

这问题我之前做ASP.NET MVC项目时也碰到过!带return的重复代码确实没法直接抽成普通方法(因为return会直接终止原方法),不过有几种实用的办法能搞定,既符合DRY原则又不破坏原有逻辑:

方法一:封装成返回ActionResult的私有方法

把重复的逻辑和return分支封装成一个私有方法,让它返回ActionResult或者null——授权通过时返回null,需要终止原方法时返回对应的结果(比如跳转、视图等)。原方法调用这个私有方法后,判断结果是否为null,非null就直接return,否则继续执行自己的逻辑。

示例代码:

public class ExampleController : Controller {
    private Authorizer _authorizer = new Authorizer();

    // 抽取的重复授权检查逻辑
    private ActionResult CheckEditAuthorization(int id) {
        var result = _authorizer.EditThing(id);
        if (!result.CanEditPartA) {
            // 记录非法访问日志
            // 其他重复操作
            return RedirectToAction("AccessDenied", "Home"); // 替换成你原来的return内容
        }
        return null; // 授权通过,返回null让原方法继续执行
    }

    public ActionResult Edit(int id) {
        var authResponse = CheckEditAuthorization(id);
        if (authResponse != null) {
            return authResponse;
        }

        // 原方法的核心逻辑,不用再写重复代码了
        var model = FetchThingById(id);
        return View(model);
    }

    // 另一个需要相同检查的Action
    public ActionResult Delete(int id) {
        var authResponse = CheckEditAuthorization(id);
        if (authResponse != null) {
            return authResponse;
        }

        // Delete的核心逻辑
        RemoveThingById(id);
        return RedirectToAction("Index");
    }
}

方法二:使用ActionFilterAttribute(更优雅的复用方式)

如果多个Action都需要这套重复的前置检查,用ASP.NET MVC的过滤器会更合适。把重复逻辑放到自定义的ActionFilter里,然后在需要的Action上标记属性即可,完全解耦授权逻辑和业务逻辑。

示例代码:

// 自定义授权过滤器
public class EditAuthorizationFilter : ActionFilterAttribute {
    private Authorizer _authorizer = new Authorizer();

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        // 从Action参数中获取id
        if (filterContext.ActionParameters.TryGetValue("id", out var idObj) && idObj is int id) {
            var result = _authorizer.EditThing(id);
            if (!result.CanEditPartA) {
                // 记录非法访问日志
                // 其他重复操作
                // 设置返回结果,终止原Action执行
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary {
                    { "controller", "Home" },
                    { "action", "AccessDenied" }
                });
            }
        }
        base.OnActionExecuting(filterContext);
    }
}

// 在Controller中使用过滤器
public class ExampleController : Controller {
    [EditAuthorizationFilter]
    public ActionResult Edit(int id) {
        // 原方法核心逻辑
        var model = FetchThingById(id);
        return View(model);
    }

    [EditAuthorizationFilter]
    public ActionResult Delete(int id) {
        // Delete核心逻辑
        RemoveThingById(id);
        return RedirectToAction("Index");
    }
}

选择建议

  • 如果只是2-3个Action有重复逻辑,方法一简单直接,不用额外定义过滤器;
  • 如果有大量Action需要相同的前置检查,方法二更优雅,扩展性更强,后续修改授权逻辑只需要改过滤器就行。

内容的提问来源于stack exchange,提问作者Luke Hammer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:58:51