【问题标题】:ASP.Net Controller method not allowed不允许使用 ASP.Net 控制器方法
【发布时间】:2018-03-14 05:57:17
【问题描述】:

我正在从 asp.net 学习 web.api。问题是,我的删除和放置方法现在不起作用。我认为我的代码有问题:*

这是我的删除控制器:

    [ResponseType(typeof(Location))]
    public IHttpActionResult DeleteLocation(Guid id)
    {
        Location location = _locationRepository.GetSingle(e => e.Id == id);
        if (location == null)
        {
            return NotFound();
        }

        _locationRepository.Delete(location);


        return Ok(location);
    }

这些是我的观点:

    [HttpPost]
    [ResponseType(typeof(LocationViewModel))]
    public async Task<IHttpActionResult> PutLocation(Guid id, LocationViewModel location)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != location.Id)
        {
            return BadRequest();
        }

        location.Id = id;

        try
        {
            await _locationRepository.EditAsync(location.ToModel());
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!LocationExist(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return StatusCode(HttpStatusCode.NoContent);
    }

这让我很困惑.. 我的获取和发布的东西完美无缺。 我正在使用邮递员来测试该方法,它说:

405 方法不允许.. 我不知道。这些是我的通用存储库。也许这也有问题..

public abstract class GenericRepository<C, T> :IGenericRepository<T> where T : class,ISoftDelete where C : DbContext, new()
//public abstract class GenericRepository<T> : IGenericRepository<T> where T : class, ISoftDelete
{
    //protected readonly ShopDiaryProject.EF.ShopDiaryDbContext _entities;

    private C _entities = new C();
    public C Context
    {

        get { return _entities; }
        set { _entities = value; }
    }


    public virtual IQueryable<T> GetAll()
    {
        IQueryable<T> query = _entities.Set<T>().Where(i => i.IsDeleted == false);

        return query;
    }

    public virtual IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
    {

        IQueryable<T> query = _entities.Set<T>().Where(i => i.IsDeleted == false).Where(predicate);
        return query;
    }

    public virtual T GetSingle(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
    {
        T data = _entities.Set<T>().Where(i => i.IsDeleted == false).FirstOrDefault(predicate);
        return data;
    }

    public virtual bool Add(T entity)
    {
        try
        {
            _entities.Set<T>().Add(entity);
            this.Save();
            return true;
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {

                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                }
            }
            return false;
        }
    }

    public virtual bool AddRange(IEnumerable<T> entity)
    {
        try
        {
            _entities.Set<T>().AddRange(entity);
            this.Save();
            return true;
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {

                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                }
            }
            return false;
        }
    }

    public virtual bool Delete(T entity)
    {
        try
        {
            entity.IsDeleted = true;
            entity.DeletedDate = DateTime.Now;
            Edit(entity);
            this.Save();
            return true;
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {

                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                }
            }
            return false;
        }
    }

    public virtual bool Edit(T entity)
    {
        try
        {
            entity.ModifiedDate = DateTime.Now;
            _entities.Entry(entity).State = EntityState.Modified;
            this.Save();
            return true;
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {

                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                }
            }
            return false;
        }
    }

    public virtual bool Save()
    {
        try
        {
            _entities.SaveChanges();
            return true;
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {

                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                }
            }
            return false;
        }
    }
    private bool _disposed = false;
    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _entities.Dispose();
            }
        }
        _disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public int Count(Expression<Func<T, bool>> match)
    {
        return _entities.Set<T>().Count(match);
    }

    public async virtual Task<bool> AddAsync(T entity)
    {
        try
        {
            _entities.Set<T>().Add(entity);
            await this.SaveAsync();
            return true;
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {

                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                }
            }
            return false;
        }
    }

    public async virtual Task<bool> AddRangeAsync(IEnumerable<T> entity)
    {
        try
        {
            _entities.Set<T>().AddRange(entity);
            await this.SaveAsync();
            return true;
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {

                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                }
            }
            return false;
        }
    }

    public async virtual Task<bool> DeleteAsync(T entity)
    {
        try
        {
            entity.IsDeleted = true;
            entity.DeletedDate = DateTime.Now;
            Edit(entity);
            await this.SaveAsync();
            return true;
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {

                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                }
            }
            return false;
        }
    }

    public async virtual Task<bool> EditAsync(T entity)
    {
        try
        {
            entity.ModifiedDate = DateTime.Now;
            _entities.Entry(entity).State = EntityState.Modified;
            await this.SaveAsync();
            return true;
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {

                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                }
            }
            return false;
        }
        //catch (Exception e)
        //{
        //    return false;
        //}
    }

    public async virtual Task<bool> SaveAsync()
    {
        try
        {
            await _entities.SaveChangesAsync();
            return true;
        }
        catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {

                    string message = string.Format("{0}:{1}",
                        validationErrors.Entry.Entity.ToString(),
                        validationError.ErrorMessage);
                }
            }
            return false;
        }
    }

也许这里有人可以帮助我:) 在此先感谢

【问题讨论】:

  • 可能您必须通过 web.config 或通过 owin 启用它,以允许您计划使用上述方法。还有POST != PUT
  • 这对你有用吗??

标签: c# asp.net asp.net-mvc asp.net-web-api controller


【解决方案1】:

基于MSDN:

Web API 还根据请求的 HTTP 方法(GET、POST 等)选择操作。默认情况下,Web API 会查找与控制器方法名称开头的不区分大小写的匹配项。例如,名为 PutCustomers 的控制器方法匹配 HTTP PUT 请求。

您可以通过使用以下任何属性装饰方法来覆盖此约定:

  • [HttpDelete]
  • [HttpGet]
  • [HttpHead]
  • [HttpOptions]
  • [HttpPatch]
  • [HttpPost]
  • [HttpPut]

所以对于你的Delete 方法:

[HttpDelete]
[Route("{id}")]
[ResponseType(typeof(Location))]
public IHttpActionResult DeleteLocation(Guid id)
{
}

从 Postman 设置方法到 Delete 和 url 到 http://localhost:xxxx/api/Locations/xxxx-xxxx-xxxx-xxxx

对于您的Put 方法:

[HttpPut]
[Route("{id}")]
[ResponseType(typeof(LocationViewModel))]
public async Task<IHttpActionResult> PutLocation(Guid id, LocationViewModel location)
{
}

从 Postman 设置方法到 Put 和 url 到 http://localhost:xxxx/api/Locations/xxxx-xxxx-xxxx-xxxx

【讨论】:

【解决方案2】:

你能在你的删除方法上添加[HttpDelete],所以它被识别为删除动作动词

[HttpDelete]
[ResponseType(typeof(Location))]
public IHttpActionResult DeleteLocation(Guid id)
{

【讨论】:

  • 没错,但.NET也从Action的名称中识别HTTP动词,在这种情况下,DeleteLocation应该被识别为一个接受DELETE动词的有效端点。
【解决方案3】:

原因是 DeletePut 动词默认情况下 IIS 或 IIS Express 是不允许的。因此,您应该将标签内容替换为 web.config 文件中的以下内容。

<validation validateIntegratedModeConfiguration="false" />
<handlers>
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />

//This will enable all Web API verbose
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

希望它有效。

【讨论】:

    【解决方案4】:

    我在 web.config 中删除了 webdavModule。它有效!

    <system.webServer>
      <modules>
        <remove name="WebDAVModule" />
      </modules>
      <handlers>
        <remove name="WebDAV" />
      </handlers>
    </system.webServer>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-13
      • 2020-04-24
      • 1970-01-01
      • 2016-05-06
      • 2018-04-08
      • 2020-09-25
      • 2017-07-31
      相关资源
      最近更新 更多