WebApi HttpDelete的困境

时间:2014-10-23 09:25:27

标签: jquery asp.net-web-api asp.net-routing

我有一个像这样的控制器(我将发布所有代码,以便你可以看到它是如何工作的。)

/// <summary>
/// Handles all of the Upload functions, including GetAll, Get and Create.
/// </summary>
[RoutePrefix("Api/Uploads")]
public class UploadsController : BaseController
{
    private readonly UploadService service;

    /// <summary>
    /// Parameterless constructor in which the upload service is instantiated.
    /// </summary>
    public UploadsController()
    {
        this.service = new UploadService(UnitOfWork);
    }

    // GET api/uploads
    /// <summary>
    /// Gets a list of all the Uploads.
    /// </summary>
    /// <returns>A list of uploads.</returns>
    [HttpGet]
    [Route("")]
    [ResponseType(typeof(IList<UploadViewModel>))]
    public async Task<IHttpActionResult> Get()
    {
        try
        {
            var uploads = await this.service.GetAllAsync();
            var models = uploads.Select(model => new UploadViewModel(model)).ToList();

            return Ok(models);
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }
    }

    // GET api/uploads
    /// <summary>
    /// Gets an upload by the required parameter; id.
    /// </summary>
    /// <param name="id">The required id paramter of the upload.</param>
    /// <returns>An upload view model.</returns>
    [HttpGet]
    [Route("{id:int}")]
    [ResponseType(typeof(UploadViewModel))]
    public async Task<IHttpActionResult> Get(int id)
    {
        try
        {
            var model = new UploadViewModel(await this.service.GetAsync(id));

            return Ok(model);
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }
    }

    // POST api/uploads
    /// <summary>
    /// Creates an Upload.
    /// </summary>
    /// <param name="model">The model representing the upload.</param>
    /// <returns>Nothing.</returns>
    [HttpPost]
    [Route("")]
    [Authorize]
    public async Task<IHttpActionResult> Post(UploadBindingViewModel model)
    {
        if (!ModelState.IsValid)
            return BadRequest(ModelState);

        var upload = new Upload
        {
            Id = model.Id,
            Name = model.Name,
            Url = model.Url
        };

        try
        {
            this.service.Create(upload);

            await this.UnitOfWork.SaveChangesAsync();
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }

        return Ok(upload.Id);
    }

    // DELETE api/uploads
    /// <summary>
    /// Deletes an upload.
    /// </summary>
    /// <param name="id">The id of the upload.</param>
    /// <returns></returns>
    [HttpDelete]
    [Route("{id:int}")]
    [Authorize]
    public async Task<IHttpActionResult> Delete(int id)
    {
        try
        {
            await this.service.RemoveAsync(id);

            await this.UnitOfWork.SaveChangesAsync();
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }

        return Ok();
    }
}

在控制器的底部,我有删除功能,目前看起来像这样:

// DELETE api/uploads
/// <summary>
/// Deletes an upload.
/// </summary>
/// <param name="id">The id of the upload.</param>
/// <returns></returns>
[HttpDelete]
[Route("{id:int}")]
[Authorize]
public async Task<IHttpActionResult> Delete(int id)
{
    try
    {
        await this.service.RemoveAsync(id);

        await this.UnitOfWork.SaveChangesAsync();
    }
    catch (Exception ex)
    {
        return InternalServerError(ex);
    }

    return Ok();
}

现在,如果我这样从jQuery调用它:

$.ajax({
    type: "DELETE",
    url: uploadUrl + "?id=" + self.id()
}).fail(function () {
    toastr.error("Failed to remove the upload from our system.");
});

或者像这样:

$.ajax({
    type: "DELETE",
    url: uploadUrl,
    data: { id: self.id() }
}).fail(function () {
    toastr.error("Failed to remove the upload from our system.");
});

我收到此错误:

  
    

{“消息”:“请求的资源不支持http方法'DELETE'。”}

  

但是,如果我将控制器方法更改为:

// DELETE api/uploads
/// <summary>
/// Deletes an upload.
/// </summary>
/// <param name="id">The id of the upload.</param>
/// <returns></returns>
[HttpDelete]
[Route("")]
[Authorize]
public async Task<IHttpActionResult> Delete(int id)
{
    try
    {
        await this.service.RemoveAsync(id);

        await this.UnitOfWork.SaveChangesAsync();
    }
    catch (Exception ex)
    {
        return InternalServerError(ex);
    }

    return Ok();
}

然后像这样消费它:

$.ajax({
    type: "DELETE",
    url: uploadUrl + "?id=" + self.id()
}).fail(function () {
    toastr.error("Failed to remove the upload from our system.");
});

它有效,但如果我改为:

$.ajax({
    type: "DELETE",
    url: uploadUrl,
    data: { id: self.id() }
}).fail(function () {
    toastr.error("Failed to remove the upload from our system.");
});

我收到与以前相同的错误消息。

我想使用后一种语句调用web api并在我的控制器中保留 {id:int} 声明。有人能告诉我我做错了吗?

1 个答案:

答案 0 :(得分:1)

我现在可以回答这个问题。 DELETE HttpMethod不接受正文数据,它只接受查询字符串参数,这就是附加的URL方法有效的原因。

此外,Web API方法的默认参数已经是 int ,因此路径应指定为 [Route(“”)] 。这意味着使用 DELETE HttpMethod,呼叫的实际路径应为 / Api / Uploads

我希望这能为其他有同样问题的人解决这个问题。