当我尝试在LINQPad中使用Selfhosted WebAPI时,我只是得到了相同的错误,该类的控制器不存在。
我是否必须为WebAPI(控制器/类)创建单独的程序集,然后在我的查询中引用它们?
这是我正在使用的代码
#region namespaces
using AttributeRouting;
using AttributeRouting.Web.Http;
using AttributeRouting.Web.Http.SelfHost;
using System.Web.Http.SelfHost;
using System.Web.Http.Routing;
using System.Web.Http;
#endregion
public void Main()
{
var config = new HttpSelfHostConfiguration("http://192.168.0.196:8181/");
config.Routes.MapHttpAttributeRoutes(cfg =>
{
cfg.AddRoutesFromAssembly(Assembly.GetExecutingAssembly());
});
config.Routes.Cast<HttpRoute>().Dump();
AllObjects.Add(new UserQuery.PlayerObject { Type = 1, BaseAddress = "Hej" });
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
using(HttpSelfHostServer server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Server open, press enter to quit");
Console.ReadLine();
server.CloseAsync();
}
}
public static List<PlayerObject> AllObjects = new List<PlayerObject>();
public class PlayerObject
{
public uint Type { get; set; }
public string BaseAddress { get; set; }
}
[RoutePrefix("players")]
public class PlayerObjectController : System.Web.Http.ApiController
{
[GET("allPlayers")]
public IEnumerable<PlayerObject> GetAllPlayerObjects()
{
var players = (from p in AllObjects
where p.Type == 1
select p);
return players.ToList();
}
}
此代码在VS2012中的单独控制台项目中正常工作。
当我没有让“正常”的WebAPI路由工作时,我开始通过NuGET使用AttributeRouting。
我在浏览器中遇到的错误是:No HTTP resource was found that matches the request URI 'http://192.168.0.196:8181/players/allPlayers'.
其他错误:No type was found that matches the controller named 'PlayerObject'
答案 0 :(得分:16)
Web API默认会忽略非公开的控制器,而LinqPad类是嵌套公共,我们在scriptcs
中遇到了类似的问题您必须添加一个自定义控制器解析程序,它将绕过该限制,并允许您手动从执行程序集中发现控制器类型。
这实际上已经修复了(现在Web API控制器只需要 Visible 不公开),但是那次发生在9月份,最新稳定版本的自我主机是从8月开始。
所以,加上这个:
public class ControllerResolver: DefaultHttpControllerTypeResolver {
public override ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver) {
var types = Assembly.GetExecutingAssembly().GetExportedTypes();
return types.Where(x => typeof(System.Web.Http.Controllers.IHttpController).IsAssignableFrom(x)).ToList();
}
}
然后注册您的配置,您就完成了:
var conf = new HttpSelfHostConfiguration(new Uri(address));
conf.Services.Replace(typeof(IHttpControllerTypeResolver), new ControllerResolver());
这是一个完整的工作示例,我刚刚对LinqPad进行了测试。请注意,您必须以管理员身份运行LinqPad,否则您将无法在端口上进行侦听。
public class TestController: System.Web.Http.ApiController {
public string Get() {
return "Hello world!";
}
}
public class ControllerResolver: DefaultHttpControllerTypeResolver {
public override ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver) {
var types = Assembly.GetExecutingAssembly().GetExportedTypes();
return types.Where(x => typeof(System.Web.Http.Controllers.IHttpController).IsAssignableFrom(x)).ToList();
}
}
async Task Main() {
var address = "http://localhost:8080";
var conf = new HttpSelfHostConfiguration(new Uri(address));
conf.Services.Replace(typeof(IHttpControllerTypeResolver), new ControllerResolver());
conf.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var server = new HttpSelfHostServer(conf);
await server.OpenAsync();
// keep the query in the 'Running' state
Util.KeepRunning();
Util.Cleanup += async delegate {
// shut down the server when the query's execution is canceled
// (for example, the Cancel button is clicked)
await server.CloseAsync();
};
}