首页 > 解决方案 > Microsoft.AspNet.OData:$filter 中的 URL 编码搜索值

问题描述

我们正在使用 Microsoft.AspNet.OData,我们的控制器如下所示:

namespace Backend.api.Process
{
    public class OdataProcessController: ODataController
    {
        private readonly IProcessService _service;

        public OdataProcessController(IProcessService service)
        {
            _service = service;
        }

        [EnableQuery]
        public IHttpActionResult Get()
        {
            return Ok(_service.GetAllProcesses());
        }
    }
}

但是,我们的某些进程的名称包含特殊字符(如“&”),在搜索时必须先对这些字符进行 URL 编码,然后再发送到后端。ASP.Net Odata 框架似乎不会自动处理这个问题。因此,我现在的任务是确保搜索字符串被后端解码。

我已经研究过扩展端点以接受 ODataQueryOptions(见下文),但我不知道如何更改过滤器字符串并将其重新包装回 ODataQueryOptions 对象:

    public IHttpActionResult Get(ODataQueryOptions<ProcessModel> queryOptions)
    {
        var allProcesses= _service.GetAllProcesses();
        queryOptions.ApplyTo(allProcesses);
        return Ok(allProcesses);
    }

我唯一的选择是重写我的服务功能以接受过滤器参数并自己实现过滤吗?

标签: c#asp.netodata

解决方案


Erdem 提供的链接给了我答案,那就是创建一个属性类来覆盖 OnActionExecuting 函数:

using Microsoft.AspNet.OData;
using System;
using System.Web;
using System.Web.Http.Controllers;

namespace Backend.api.Process
{
    public class DecodeFilter : EnableQueryAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var url = actionContext.Request.RequestUri.OriginalString;
            var newUrl = HttpUtility.UrlDecode(url);

            actionContext.Request.RequestUri = new Uri(newUrl);
            base.OnActionExecuting(actionContext);
        }
    }
}

然后按如下方式使用它:

    [EnableQuery]
    [DecodeFilter]
    public IHttpActionResult Get()
    {
        return Ok(_service.GetAllProcesses());
    }

推荐阅读