문제

Using the WebAPI.

One of our tests that had been created was to ensure that for a specific controller, only GET verbs where permitted.

A test had been written that used the MVC HelpPages

HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(baseAddress);
config.Routes.MapHttpRoute(
    "SearchAPI", 
    "api/{controller}/{id}");

HttpSelfHostServer server = new HttpSelfHostServer(config);
server.OpenAsync().Wait();
IApiExplorer apiExplorer = config.Services.GetApiExplorer();
var apiDescriptions = apiExplorer.ApiDescriptions;
var data = from description in apiDescriptions
           where description.ActionDescriptor.ControllerDescriptor.ControllerType.FullName.StartsWith("MySite.Presentation.Pages.SearchAPI")
           orderby description.RelativePath
           select description
           ;
foreach (var apiDescription in data)
{
    Assert.That(apiDescription.HttpMethod, Is.EqualTo(HttpMethod.Get), string.Format("Method not Allowed: {0} {1}", apiDescription.RelativePath, apiDescription.HttpMethod));
}

Now this test while it may not have been the best way of ensuring that for our controller, only GET HTTP VERB methods where applicable, it worked.

We have now upgraded to MVC5, and this test now fails. As HttpSelfHostServer is no longer available

Looking at Microsoft's msdn library, you are not recommended to use HttpSelfHostServer, but instead are encouraged to use Owin.

I have started off with a new Owin class

public class OwinStartUp
{
    public void Configuration(IAppBuilder appBuilder)
    {
        var config = new HttpConfiguration();
        config.Routes.MapHttpRoute(
            name: "SearchAPI",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        AreaRegistration.RegisterAllAreas();
        appBuilder.UseWebApi(config); 
    }
}

But when it comes to the test, this is as far as I have been able to get

        string baseAddress = "http://localhost/bar";
        using (var server = WebApp.Start<OwinStartUp>(url: baseAddress))
        {


        }

I dont know how to access Services from the configuration, to then be able to call the GetApiExplorer method as there are no public methods on the server variable being suggested by Intellisense..

I have been looking at some sites that show how to use Owin, but they have not helped me solve this issue: http://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api

There is also this existing questions Can't get ASP.NET Web API 2 Help pages working when using Owin But that has not helped me solve the problem.

What do I need to do, to be able to write a unit test to ensure that only specific HTTP VERBS are permitted for a controller/method, or how to configure Owin to use the API HelpPages

도움이 되었습니까?

해결책

For you scenario, you do not need to spin up the server, for example, you could just do the following to get the api descriptions. Note that for getting api descriptions, api explorer doesn't need to execute an actual request to get the apidescription.

var config = new HttpConfiguration();

config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

IApiExplorer explorer = config.Services.GetApiExplorer();

var apiDescs = explorer.ApiDescriptions;

다른 팁

I have a .NET Core 3.1 test project using XUnit that tests an ASP.NET MVC project. The following test ensures all controllers have an HTTP verb associated with them (e.g. someone didn't forget to add one or more). This question helped me get there, so I'm posting my test here:

[Fact]
public void Controllers_All_Have_Http_Verbs()
{
  var methodsMissingHttpVerbs = Assembly
    .GetAssembly(typeof(HomeController)).GetTypes()
    .Where(type => typeof(Controller).IsAssignableFrom(type))
    .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
    .Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), true).Any())
    .Count(c => c.GetCustomAttribute<HttpGetAttribute>() == null &&
                c.GetCustomAttribute<HttpPostAttribute>() == null &&
                c.GetCustomAttribute<HttpDeleteAttribute>() == null);

  Assert.Equal(0, methodsMissingHttpVerbs);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top