加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 路由参数,自定义模型绑定器还是动作过滤器?

发布时间:2020-12-16 03:20:46 所属栏目:asp.Net 来源:网络整理
导读:我们的ASP.NET MVC应用程序允许经过身份验证的用户管理链接到其帐户的一个或多个“站点”. 我们的网址是高度可猜测的,因为我们在网址中使用网站友好名称而不是Id,例如: /sites/mysite//sites/mysite/settings/sites/mysite/blog/posts/sites/mysite/pages/c
我们的ASP.NET MVC应用程序允许经过身份验证的用户管理链接到其帐户的一个或多个“站点”.

我们的网址是高度可猜测的,因为我们在网址中使用网站友好名称而不是Id,例如:

/sites/mysite/
/sites/mysite/settings

/sites/mysite/blog/posts
/sites/mysite/pages/create

如您所见,我们需要在多个路线中访问站点名称.

我们需要为所有这些操作执行相同的行为:

>在当前帐户中查找具有给定标识符的站点
>如果返回的站点为null,则返回404(或自定义视图)
>如果站点非空(有效),我们可以继续执行操作

我们始终可以通过ISiteContext对象使用当前帐户.以下是我如何使用普通路由参数实现上述所有操作并直接在我的操作中执行查询:

private readonly ISiteContext siteContext;
private readonly IRepository<Site> siteRepository;

public SitesController(ISiteContext siteContext,IRepository<Site> siteRepository)
{
    this.siteContext = siteContext;
    this.siteRepository = siteRepository;
}

[HttpGet]
public ActionResult Details(string id)
{
    var site =
        siteRepository.Get(
            s => s.Account == siteContext.Account && s.SystemName == id
        );

    if (site == null)
        return HttpNotFound();

    return Content("Viewing details for site " + site.Name);
}

这不是太糟糕,但我需要在20个左右的动作方法上做这个,所以想尽可能保持干燥.

我没有做过自定义模型粘合剂,所以我想知道这是否是一个更适合他们的工作.一个关键要求是我可以将我的依赖项注入模型绑定器(对于ISiteContext和IRepository – 如果需要,我可以回退到DependencyResolver).

非常感谢,

更新

下面是工作代码,使用自定义模型绑定器和操作筛选器.我仍然不确定我对此的感受是因为

>我应该从模型绑定器上击中我的数据库吗?
>我实际上可以从动作过滤器中检索对象和空验证.哪个更好?

型号粘合剂:

public object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext)
{
    if (!controllerContext.RouteData.Values.ContainsKey("siteid"))
        return null;

    var siteId = controllerContext.RouteData.GetRequiredString("siteid");

    var site =
        siteRepository.Get(
            s => s.Account == siteContext.Account && s.SystemName == siteId
        );

    return site;
}

动作过滤器:

public class ValidateSiteAttribute : ActionFilterAttribute
{       
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {           
        var site = filterContext.ActionParameters["site"];

        if (site == null || site.GetType() != typeof(Site))
            filterContext.Result = new HttpNotFoundResult();

        base.OnActionExecuting(filterContext);
    }
}

控制器动作:

[HttpGet]
[ValidateSite]
public ActionResult Settings(Site site)
{
    var blog = site.GetFeature<BlogFeature>();
    var settings = settingsProvider.GetSettings<BlogSettings>(blog.Id);

    return View(settings);
}

[HttpPost]
[ValidateSite]
[UnitOfWork]
public ActionResult Settings(Site site,BlogSettings settings)
{
    if (ModelState.IsValid)
    {
        var blog = site.GetFeature<BlogFeature>();
        settingsProvider.SaveSettings(settings,blog.Id);
        return RedirectToAction("Settings");
    }

    return View(settings);
}

解决方法

这听起来像是一个动作过滤器的工作.您可以使用动作过滤器进行DI而不是问题.

所以,是的,只需将现有功能转换为动作过滤器,然后将其应用于每个动作或控制器或您继承的基本控制器.

我不太清楚您的网站是如何工作的,但您可以使用全局操作过滤器来检查特定路由值的存在,例如“网站名称”.如果该路由值存在,则意味着您需要检查该站点是否存在…

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读