문제

이것은 TransferController 클래스의 스케치입니다.

이 모든 것은 웹 API 코드입니다.

public class TransferController : ApiController
{
  [HttpGet, ActionName("Queue")]
  public IEnumerable<object> GetQueue(Guid sessionId) {...}

  [HttpDelete, ActionName("Delete")]
  public void Delete(Guid sessionId, Guid fileId) {...}

  [HttpGet, ActionName("Cancel")]
  public bool Cancel(Guid sessionId, Guid fileId) {...}

  [HttpGet, ActionName("UploadedBytes")]
  public long GetUploadedByteCount(Guid sessionId, Guid fileId) {...}

  [HttpGet, ActionName("DownloadUrl")]
  public string GetDownloadUrl(string fileId) {...}

  [HttpPost, ActionName("FileChunk")] 
  public void PostFileChunk([FromUri]Guid sessionId, [FromUri]Guid fileId) {...}

  [HttpPost, ActionName("UploadDefinition")]
  public Guid PostUploadItem([FromBody]UploadDefinition uploadDef) {...}

}
.

이것은 라우팅입니다.

public static void Register(HttpConfiguration config)
{
  config.Routes.MapHttpRoute(
    name: "DefaultApi", 
    routeTemplate: "api/{controller}/{action}"
    );
  config.Routes.MapHttpRoute(
    name: "DefaultApiDefaultMethod", 
    routeTemplate: "api/{controller}"
    );
}
.

이것은 호출입니다.

$.ajax({
  url: "api/Transfer/Queue",
  data: { sessiondId: login.SessionId() }    
})
.done(function (result) {
  history.push(new UploadItem());
  for (var i = 0; i < result.length; i++) {
    var ui = new UploadItem(result[i]);
    history.push(ui);
  }
})
.fail(function (result) {
  app.showMessage(JSON.parse(result.responseText).Message);
});
.

과 이것이 결과입니다.

No HTTP resource was found that matches the request URI 'http://localhost:54770/api/Transfer/Queue?sessiondId=0e2c47b9-e674-446d-a06c-ce16932f9580'.

이것은 내 사용자 컨트롤러 클래스의 스케치입니다.

public class UserController : ApiController 

  [HttpGet, ActionName("Authenticate")]
  public object Authenticate(string email, string password) {...}

  [HttpPost]
  public void Register([FromBody]UserDefinition userDef) {...}

  [HttpGet, ActionName("Pulse")]
  public bool Pulse(Guid sessionId) {...}

}
.

나에게 전혀없는 이유로 userController에서 아무 것도 호출하는 데 어려움이 없습니다. 파라미터는 정확히 동일한 방식으로 마샬링되고 동일 경로가 사용 중입니다.


Darrel Miller는 단위 테스트를 사용하여 경로의 유효성을 검사합니다. 솔직히 나는 이것을 생각하지 않기 때문에 나 자신을 걷어 찼다. 그리고 지금 나는 똑같이했다.

그러나 그가 실제로 URL 파싱 만 테스트하는 것처럼 테스트합니다. 예를 들어,이 테스트는

을 통과합니다.
public void TestMvc4RouteWibble()
{
  var config = new HttpConfiguration();
  config.Routes.MapHttpRoute(
      name: "DefaultApi",
      routeTemplate: "api/{controller}/{action}/{id}",
      defaults: new { id = RouteParameter.Optional }
      );


  var route =
      config.Routes.GetRouteData(new HttpRequestMessage()
      {
        RequestUri = new Uri("http://localhost:54770/api/Transfer/Wibble?sessionId=0e2c47b9-e674-446d-a06c-ce16932f9580&fileId=0e2c47b9-e674-446d-a06c-ce16932f9581")  //?
      });

  Assert.IsNotNull(route);
  Assert.AreEqual("Transfer", route.Values["controller"]);
  Assert.AreEqual("Wibble", route.Values["action"]);

}
.

전송 컨트롤러에 균일 한 방법의 눈에 띄는 부재에도 불구하고

또한 경로 객체가 실제로 httproute 객체가 아니며 httproutedata 객체입니다. 그러나 그것은 사소히 교정됩니다. httproute 객체는 httproutedata 객체의 속성으로 사용할 수 있습니다.

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


  var routeData =
      config.Routes.GetRouteData(new HttpRequestMessage()
      {
        RequestUri = new Uri("http://localhost:54770/api/Transfer/Wibble?sessionId=0e2c47b9-e674-446d-a06c-ce16932f9580&fileId=0e2c47b9-e674-446d-a06c-ce16932f9581")  //?
      });

  Assert.IsNotNull(routeData);
  Assert.AreEqual("Transfer", routeData.Values["controller"]);
  Assert.AreEqual("Wibble", routeData.Values["action"]);

}
.

및 턴으로 핸들러 속성이 있습니다. 그러나 NULL 핸들러가 단순히 (MSDN)

을 의미하기 때문에 이것은 덜 유익한 것보다 덜 유익합니다.

null의 경우 기본 핸들러는 iHTTPController의 구현에 메시지를 전달합니다.

이제, 내 컨트롤러는 iHTTPController 인터페이스가 지정한 유일한 방법 인 ExecuteAsync 메서드를 확실히 구현하는 Apicontroller에서 파생됩니다. 내가 상상하는 것은 내가 그것에 대해 더 많이 알면 그 방법의 실행을 테스트 할 수 있음을 의미합니다.

도움이 되었습니까?

해결책 2

OK 그 다음 ... 내 머리에 장치 테스트 아이디어를 넣어 주셔서 감사합니다.

다음은 낮은 다운 :

다른 동사에 동일한 매개 변수 서명을 가질 수 있습니다 (POST PUT DELETE 가져 오기).

는 동일한 동사의 다른 동작 이름에 동일한 매개 변수 서명을 가지고 있습니다.

하나 매개 변수 이름 만 다르므로

그래서 이것은 모두 다른 동사에있는 것이므로

[HttpDelete, ActionName("Delete")]
public void Delete(Guid sessionId, Guid fileId) {...}

[HttpGet, ActionName("Cancel")]
public bool Cancel(Guid sessionId, Guid fileId) {...}

[HttpPost, ActionName("FileChunk")] 
public void PostFileChunk(Guid sessionId, Guid fileId) {...}
.

둘 다

를 가져 오기 때문에 이것은 멋지지 않습니다.
[HttpGet, ActionName("UploadedBytes")]
public long GetUploadedByteCount(Guid sessionId, Guid fileId) {...}

[HttpGet, ActionName("Cancel")]
public bool Cancel(Guid sessionId, Guid fileId) {...}
.

이 다음과 같이 수정할 수 있습니다

[HttpGet, ActionName("UploadedBytes")]
public long GetUploadedByteCount(Guid sessionId, Guid uploadBytesFileId) {...}

[HttpGet, ActionName("Cancel")]
public bool Cancel(Guid sessionId, Guid cancelFileId) {...}
.

일 어쩌면 나는 어려운 엉덩이 일 수도 있지만, 내가 걱정하는 한 그것이 메소드가 호출 될 때까지 라우팅이 아닙니다.

다른 팁

라우팅 작동을 보여주는 테스트가 있습니다.

[Fact]
public void TestRoute() 
{
    var config = new HttpConfiguration();
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{action}"
        );


    var route =
        config.Routes.GetRouteData(new HttpRequestMessage()
        {
            RequestUri = new Uri("http://localhost:54770/api/Transfer/Queue?sessionId=0e2c47b9-e674-446d-a06c-ce16932f9580")  //?
        });

    Assert.NotNull(route);
    Assert.Equal("Transfer",route.Values["controller"]);
    Assert.Equal("Queue",route.Values["action"]);

}
.

및 여기서 디스패치 / 액션 선택도 작동하는 테스트가 있습니다

[Fact]
public void TestDispatch()
{
    var config = new HttpConfiguration();
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{action}"
        );

    var server = new HttpServer(config);

    var client = new HttpClient(server);
    var response =
        client.GetAsync(new Uri("http://localhost:54770/api/Transfer/Queue?sessionId=0e2c47b9-e674-446d-a06c-ce16932f9580")) // 
            .Result;

    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}


public class TransferController : ApiController
{
   [HttpGet]
   [ActionName("Queue")]
   public IEnumerable<object> Queue(Guid sessionId) 
   {
       return null;
   }

}
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top