Я изучаю web.api из asp.net. Проблема в том, что мой метод удаления и размещения сейчас не работает. Я думаю, что с моим кодом что-то не так: *
Вот мой контроллер для удаления:
[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;
}
}
Может здесь кто-нибудь мне поможет :) заранее спасибо
это сработало для вас ??





Можете ли вы добавить [HttpDelete] в свой метод удаления, чтобы он идентифицировался как глагол действия удаления
[HttpDelete]
[ResponseType(typeof(Location))]
public IHttpActionResult DeleteLocation(Guid id)
{
Это верно, но .NET также идентифицирует команду HTTP из имени действия, в этом случае DeleteLocation следует идентифицировать как допустимую конечную точку, принимающую команду DELETE.
На основе MSDN:
Web API also selects actions based on the HTTP method of the request (GET, POST, etc). By default, Web API looks for a case-insensitive match with the start of the controller method name. For example, a controller method named PutCustomers matches an HTTP PUT request.
You can override this convention by decorating the method with any the following attributes:
- [HttpDelete]
- [HttpGet]
- [HttpHead]
- [HttpOptions]
- [HttpPatch]
- [HttpPost]
- [HttpPut]
Итак, для вашего метода Delete:
[HttpDelete]
[Route("{id}")]
[ResponseType(typeof(Location))]
public IHttpActionResult DeleteLocation(Guid id)
{
}
И из метода почтальона установите 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)
{
}
И из метода почтальона установите Put и URL-адрес http://localhost:xxxx/api/Locations/xxxx-xxxx-xxxx-xxxx
Все еще не работает .. shopdiary.funcraftstudio.com/api/Locations/… все еще метод 405 не разрешен
По-прежнему не работает .. shopdiary.funcraftstudio.com/api/Locations/… по-прежнему метод 405 не разрешен общедоступная асинхронная задача <IHttpActionResult> DeleteLocation (Guid id) << вызывает ли это проблема? И я использую этот маршрут для поста: локальный: 8080 / api / Locations / PostLocation
Возможно, вам потребуется убедиться, что ваш IIS настроен на прием метода DELETE - stackoverflow.com/questions/9854602/…
Причина в том, что Удалить в Ставить глаголы не разрешены 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>
Надеюсь, что это работает.
Я удалил webdavModule в web.config. И это работает!
<system.webServer>
<modules>
<remove name = "WebDAVModule" />
</modules>
<handlers>
<remove name = "WebDAV" />
</handlers>
</system.webServer>
Возможно, вам нужно включить его через web.config или через owin, чтобы разрешить указанные методы, которые вы планируете использовать. Также
POST != PUT