Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.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# 在运行时为Web Api控制器创建资源_C#_Asp.net_Asp.net Web Api2 - Fatal编程技术网

C# 在运行时为Web Api控制器创建资源

C# 在运行时为Web Api控制器创建资源,c#,asp.net,asp.net-web-api2,C#,Asp.net,Asp.net Web Api2,我的应用程序现在是多租户的,我有一个类,可以根据登录的租户查找要使用的设置。所以我在每个控制器中都有一些代码,基本上看起来像这样 [RoutePrefix("api/client/{id})] public class ReportsController : ApiController { ILogHandler _logHandler = new LogHandler(); private processor _processor = null; public Rep

我的应用程序现在是多租户的,我有一个类,可以根据登录的租户查找要使用的设置。所以我在每个控制器中都有一些代码,基本上看起来像这样

[RoutePrefix("api/client/{id})]
public class ReportsController : ApiController
{
    ILogHandler _logHandler = new LogHandler();
    private processor _processor = null;

    public ReportsController(IProcessor Processor)
    {
        _processor = Processor;
    }

    [Route("")]
    [HttpGet]
    [EnableQuery]
    public IHttpActionResult Get(Guid id)
    {
            //Some pseudo code here to get some settings for a client
            var settings = clientSettings(id);

            //investigate the settings
            if(settings.CanDoSomething())
                var qi = _processor.process();
            return Ok(qi);
    }
}
我查阅了一些设置并决定做一些事情。我的问题是每个控制器都必须执行查找过程,但我想做的是让对象已经存在,并将其范围限定到正确的客户端

我尝试使用Owin中间件并将对象放在Owin环境中,但我想这是在管道的早期,我不知道中间件中Id的值是多少


我也有autofac,我也研究过使用它,但它似乎更适合于解决每个租户的特定依赖关系,或者让租户访问某些控制器。我想要的是,每个租户在每个请求中都会得到一个这样的对象,但它只需要不同的设置

看起来您已经尝试使用Owin中间件实现了这一点。我认为它会起作用,但也许您正在寻找一种获取id字段的简单方法,这是不可能的。Owin中间件的问题是它的工作级别非常低:您只会得到一个IDictionary,其中包含您在案例中执行操作所需的所有信息,从查询字符串中获取id;在WebAPI的例子中,得到一大堆东西。在此基础上的一个次要抽象是OwinMiddleware类;它在IOwinContext类型的对象中显示来自web请求的信息。使用Autofac,您可以向它注册中间件,以便它可以向其中注入依赖项。根据这些信息,我们可以创建一个owin中间件,该中间件从查询字符串中获取id,并在注入的ClientSettings实例上进行设置:

public class IDParserMiddleware : OwinMiddleware
{
    private ClientSettings Settings;

    public IDParserMiddleware(OwinMiddleware next, ClientSettings settings)
        : base(next)
    {
        Settings = settings;
    }

    public override Task Invoke(IOwinContext context)
    {
        string[] query = context.Request.QueryString.Value.Split('&');
        string id = null;
        foreach (string keyvalue in query)
        {
            if (keyvalue.StartsWith("id=", StringComparison.InvariantCultureIgnoreCase))
            {
                id = keyvalue.Substring(3); // right after "id="
                break;
            }
        }

        Settings.ID = Guid.Parse(id);

        return this.Next.Invoke(context);
    }
}
然后,您可以向Owin注册,如下所示:

IAppBuilder app; // you get this from Owin code like WebApp.Start()
var builder = new ContainerBuilder();
builder.RegisterType<IDParserMiddleware>();
//...
var container = builder.Build();

// This will add the Autofac middleware as well as the middleware
// registered in the container, like IDParserMiddleware
app.UseAutofacMiddleware(container);
// Finally, register Web Api. We do this last so that our middleware
// can run before it and set the ID property.
app.UseAutofacWebApi(config);
app.UseWebApi(config);

值得注意的是,我还没有尝试过这一点,但从我所读到的来看,这应该是可行的。祝你好运

身份证是从哪里来的?url/查询字符串?还是发布数据?或者它是否会根据它调用的控制器方法来执行?现在我已经设置了所有路由,将其作为url的一部分发送。因此,我所有的控制器都遵循/api/client/{clientid}/{resource}的模式。我一直在努力避免使用一个粗糙的正则表达式解决方案。我知道有像getRoueData这样的功能可用。它们似乎总是在我需要使用它们的地方不可用,比如MiddleWare我刚刚意识到代码正在查看查询字符串,而对您来说,它不是查询字符串的一部分;它只是主url。所以,您只需要修改解析代码,从context.Request.Path或context.Request.Uri中找到它。这不是一个很好的解决方案,我只是希望我不必使用正则表达式。似乎我希望控制器提供一些东西,比如GetRoutedState问题是所有这些都是在Web Api有机会查看它之前发生的。上一次我研究如何连接到WebAPI本身,以便使用更简单的类和方法时,如果不在控制器级别进行,我无法找到解决方案。因此,除非有人或您在WebAPI中找到了这样做的方法,否则您将无法像上面那样解析URL。说实话,我希望有人能想出更好的解决办法。这真的很难看,级别太低,无法使用,我也希望使用更简单的WebAPI类。但就目前而言,这似乎是唯一合理的解决方案。
public ReportsController(IProcessor Processor, ClientSettings settings)
{
    _processor = Processor;
    _settings = settings;
}