Asp.net-Web-Api
在 LINQPad 中使用 WebAPI?
當我嘗試在 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'
預設情況下,Web API 會忽略不公開的控制器,並且 LinqPad 類是嵌套的 public,我們在scriptcs中遇到了類似的問題
您必須添加一個自定義控制器解析器,它將繞過該限制,並允許您手動從正在執行的程序集中發現控制器類型。
這實際上已經修復(現在 Web API 控制器只需要可見而不是公開),但這發生在 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(); }; }