1

我是 Web Api 的新手。我正在使用自定义命名操作创建一个 Web Api 控制器。我使用 HttpClient 从 WPF 客户端调用它。但是我得到一个错误 响应状态码不表示成功 404 (Not Found)

这是我的 Web Api 控制器:

public class ActivationController : ApiController
{
    private readonly IActivationUnit _activationUnit;

    public ActivationController()
    {
        _activationUnit = new ActivationUnit();
    }

    //  api/activation/GetAllActivisionInformations
    public HttpResponseMessage GetAllActivationInformations(string username)
    {
        return Request.CreateResponse(HttpStatusCode.OK, _activationUnit.ActivationRepository.GetActivationInformations(username));
    }

    // api/activation/NewLicense
    [HttpPost]
    public HttpResponseMessage PostNewLicense(LicenseMetadata licenseMetadata)
    {
        bool isSuccess = _activationUnit.ActivationRepository.NewLicense(licenseMetadata.Username, licenseMetadata.ActivisionInformation);
        if (isSuccess)
        {
            try
            {
                _activationUnit.Save();
            }
            catch (Exception)
            {
                isSuccess = false;
            }
        }
        return Request.CreateResponse(isSuccess ? HttpStatusCode.OK : HttpStatusCode.BadRequest, isSuccess);
    }
}

我的路由是:

 //   Route for POST method
 config.Routes.MapHttpRoute(
 name: "DefaultApi2",
 routeTemplate: "api/{controller}/{action}/{id}",
 defaults: new { id = RouteParameter.Optional }
 );

 //   Route  GET method

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

我的客户代码是:

 HttpClient client = new HttpClient();
 client.BaseAddress = new Uri("http://localhost:42471");
 client.DefaultRequestHeaders.Accept.Add(
       new MediaTypeWithQualityHeaderValue("application/json"));

 var licenseMetadata = new LicenseMetadata
      {
         ActivisionInformation = new ActivisionInformation(),
         Username = "UserName"
       };

 var response = await client.PostAsJsonAsync("api/activation/NewLicense", licenseMetadata);
 try
   {
      response.EnsureSuccessStatusCode();
      MessageBox.Show("Success");

    }
    catch (Exception ex)
    {
       MessageBox.Show(ex.Message);
    }

当我使用 HttpClient 向服务器发送请求时,我得到响应状态代码不指示成功 404(未找到)

我试图将 url "api/activation/newlicense" 更改为 "api/activation/PostNewLicense" 但在这种情况下我得到

响应状态码不表示成功 500 (Internal Server Error) form HttpClient

我在哪里做错了。我已经花了两天时间。

我正在使用:Visual Studio 2012、.NET 4、MVC 4、Windows 8、IIS 8

4

3 回答 3

6

如果您不想在操作名称中使用 Get/Post 的默认实现,而是想调用方法,请按照您的方式调整您的路线(只是第一个,没有第二个用于 get ),并停止使用GetandPost前缀。

路线配置:

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

在您的控制器中:

public class ActivationController : ApiController
{
    // .. other code ..

    // api/Activation/NewLicense
    [HttpPost]
    public HttpResponseMessage NewLicense(LicenseMetadata licenseMetadata)
    {
        // .. rest of your code ..
    }
}

我个人不喜欢默认实现,除非您尝试创建 REST API。它的工作方式是你可以拥有GetFooBarand PostBarBaz,不管你在Getand之后拥有什么Post。出于我的目的,我总是像上面那样覆盖路线。

于 2013-08-27T06:15:15.543 回答
1

这实际上是一个很好的问题。还没有人回答。这是答案。您必须像这样使用预期的 Route 来装饰 Post 方法。

这是我终于开始工作的一个例子。我的发帖方式:

    [HttpPost]
    [Route("api/excel/createauditfile")]
    public IHttpActionResult CreateAuditFile(Request<AuditFile> request)
    {
        Response<FileInfo> response = new Response<FileInfo>();

        try
        {
            response.Result = _repository.CreateAuditFile(request.Parameter);
            response.IsSuccessStatusCode = true;
        }
        catch (Exception ex)
        {
            response.IsSuccessStatusCode = false;
            response.exception = ex;
        }
        return Ok<Response<FileInfo>>(response);
    }

我的服务调用方法:

    public FileInfo CreateAuditFile(AuditFile auditFile)
    {
        Request<AuditFile> request = new Request<AuditFile>();
        request.Parameter = auditFile;

        response = Client.PostAsJsonAsync("api/excel/createauditfile", request).Result;

        if (response.IsSuccessStatusCode)
        {
            var data = response.Content.ReadAsStringAsync().Result;
            var responseData = JsonConvert.DeserializeObject<Response<FileInfo>>(data);

            if (!responseData.IsSuccessStatusCode)
            {
                Exception ex = responseData.exception;
                throw ex;
            }

            return responseData.Result;
        }
        else
        {
            throw new Exception("An unexpected Service Exception has Happened.  Please contact your administrator.");
        }
    }
于 2016-08-03T19:47:18.010 回答
0

默认路由应该适用于您的操作方法。Web API 将根据 http 动词选择正确的操作方法。

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

控制器代表一个资源,您可以通过发送 get 请求获取并通过向其发出 post 请求来创建它。

发帖时应使用 URL:

var response = await client.PostAsJsonAsync("api/activation", licenseMetadata);

500 响应通常意味着您的 api 方法被调用并引发了异常。我会在我的 web api 方法的第一行设置一个断点来检查这个。我还建议让 fiddler 更好地查看请求和响应。

于 2013-08-27T05:14:02.580 回答