0

朋友們,我正在使用VS2013,並在我的應用程序中存在路由問題。我創建了一個非常簡單的Web應用程序來說明我的問題,並張貼到GitHub上的位置:Fluent-Nhibernate + Web Api v2 + Unity

https://github.com/ewhitmore/RoutingIssues/

目前,我有一個控制器,GET,PUT,POST和DELETE動詞,但是當我嘗試使用它,GET和POST工作,但DELETE和PUT不工作。

我收到以下錯誤:「405方法不允許」和「消息」:「請求的資源不支持http方法'PUT'。」

我已經在控制器上放置了斷點,並且PUT/DELETE操作甚至沒有將它放到控制器上。

我已經使用AngularJS ng-resources,Postman和REST Console獲得了相同的結果。

我已經從我的電腦卸載了webdev,嘗試了一堆不同的路由技術,但都沒有成功。據我所知,這都是本地的,所以不是跨站點/服務器/域(CORS)問題。在這一點上,我已經在這個問題上工作了20多個小時,我即將放棄。任何幫助將不勝感激。

代碼如下亮點:

UserProfileContoller:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Web; 
using System.Web.Http; 
using System.Web.Http.Description; 
using Microsoft.Practices.Unity; 
using TrackInstant.Models.Entities; 
using TrackInstant.Services; 

namespace TrackInstant.Controllers 
{ 
    [AllowAnonymous] 
    [RoutePrefix("api/userprofile")] 
    public class UserProfileController : ApiController 
    { 
     [Dependency] 
     public UserProfileService UserProfileService { private get; set; } 

     [HttpGet] 
     public IEnumerable<UserProfile> GetAllUsers() 
     { 
      return UserProfileService.GetAllUserProfiles(); 
     } 

     [HttpGet] 
     [ResponseType(typeof(UserProfile))] 
     public UserProfile GetUserById(int id) 
     { 
      UserProfile userProfile = UserProfileService.GetUser(id); 
      if (userProfile == null) 
      { 
       throw new HttpResponseException(HttpStatusCode.NotFound); 
      } 
      return userProfile; 
     } 



     [HttpPost] 
     [ResponseType(typeof(UserProfile))] 
     public IHttpActionResult PostUser(UserProfile userProfile) 
     { 

      if (userProfile == null) 
      { 
       return BadRequest(); 
      } 

      UserProfileService.Save(userProfile); 

      return CreatedAtRoute("DefaultApi", new { id = userProfile.UserId }, userProfile); 
     } 

     [HttpPut] 
     public IHttpActionResult PutUser(int id, UserProfile userProfile) 
     { 
      UserProfile persistentUser = UserProfileService.GetUser(id); 
      if (persistentUser == null) 
      { 
       throw new HttpResponseException(HttpStatusCode.NotFound); 
      } 
      persistentUser.Email = userProfile.Email; 
      UserProfileService.UpdateUser(persistentUser); 

      return StatusCode(HttpStatusCode.NoContent); 
     } 

     [HttpDelete] 
     [ResponseType(typeof(UserProfile))] 
     public IHttpActionResult DeleteUser(int id) 
     { 
      UserProfile userProfile = UserProfileService.GetUser(id); 
      if (userProfile == null) 
      { 
       throw new HttpResponseException(HttpStatusCode.NotFound); 
      } 
      UserProfileService.DeleteUser(userProfile); 

      return Ok(userProfile); 
     } 
    } 
} 

Web.config文件亮點:

<system.webServer> 
    <validation validateIntegratedModeConfiguration="false" /> 
    <modules> 
     <remove name="FormsAuthenticationModule" /> 
     <remove name="WebDAVModule" /> 
    </modules> 
    <handlers> 
     <remove name="WebDAV" /> 
     <remove name="OPTIONSVerbHandler" /> 
     <remove name="TRACEVerbHandler" /> 
     <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
     <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" /> 
</handlers> 
</system.webServer> 

的Global.asax

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Optimization; 
using System.Web.Routing; 
using System.Web.Security; 
using System.Web.SessionState; 
using System.Web.Http; 
using TrackInstant.App_Start; 

namespace TrackInstant 
{ 
    public class Global : HttpApplication 
    { 
     void Application_Start(object sender, EventArgs e) 
     { 
      // Code that runs on application startup 

      GlobalConfiguration.Configure(WebApiConfig.Register); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
      BundleConfig.RegisterBundles(BundleTable.Bundles); 

      WebApiFilterConfig.RegisterGlobalFilters(GlobalConfiguration.Configuration.Filters); 


      HibernateConfig.InitHibernate(); 
      UnityBootstrapper.Initialise(); 





     } 

     public override void Dispose() 
     { 
      HibernateConfig.SessionFactory.Dispose(); 
      base.Dispose(); 
     } 
    } 
} 

RouteConfig

using System; 
using System.Collections.Generic; 
using System.Web; 
using System.Web.Http; 
using System.Web.Routing; 
using Microsoft.AspNet.FriendlyUrls; 


namespace TrackInstant 
{ 
    public static class RouteConfig 
    { 
     public static void RegisterRoutes(RouteCollection routes) 
     { 

      var settings = new FriendlyUrlSettings {AutoRedirectMode = RedirectMode.Permanent}; 
      routes.EnableFriendlyUrls(settings); 
     } 
    } 
} 

WebApiConfig

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.Http; 
using Newtonsoft.Json; 
using Newtonsoft.Json.Serialization; 

namespace TrackInstant 
{ 
    public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 
      // Web API configuration and services 

      // Web API routes 
      config.MapHttpAttributeRoutes(); 


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



      GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); 
      var formatters = GlobalConfiguration.Configuration.Formatters; 

      var jsonFormatter = formatters.JsonFormatter; 
      jsonFormatter.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()); 

      var settings = jsonFormatter.SerializerSettings; 
      settings.Formatting = Formatting.Indented; 
      settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

      config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; 
     } 
    } 
} 

WebApiFilterConfig

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Http.Filters; 

namespace TrackInstant.App_Start 
{ 
    public class WebApiFilterConfig 
    { 
     public static void RegisterGlobalFilters(HttpFilterCollection filters) 
     { 
      filters.Add(new HibernateSessionFilter()); 
     } 
    } 
} 
+0

這是一個看跌的郵遞員輸出。注意「Allow」:'Allow→GET,POST Cache-Control→no-cache Content-Length→79 Content-Type→application/json;字符集= UTF-8 日期→星期二,2013年12月17日16時09分28秒GMT 過期→-1 附註→無緩存 服務器→微軟IIS/8.0 X-ASPNET-版→4.0.30319 X -Powered-通過→ASP.NET X-SourceFiles→=?UTF-8?B'QzpcVXNlcnNcd2hpdG0xZWtcRG9jdW1lbnRzXFZpc3VhbCBTdHVkaW8gMjAxM1xQcm9qZWN0c1xSb3V0aW5nXFJvdXRpbmdJc3N1ZXNcVHJhY2tJbnN0YW50XGFwaVx1c2VycHJvZmlsZQ ==?=' – Eric

+0

我想,如果安裝的WebDAV它可能會導致這個問題。 – Andy

+0

在發佈之前,我完全從我的電腦中刪除了WebDAV。仍然沒有運氣。 – Eric

回答

0

我能弄明白!有兩個問題。

  1. 我的控制器中的PUT動詞在聲明中包含「int id」。這會混淆默認路由,因爲在發佈期間url沒有包含標識。更改PUT聲明下面的固定問題:

    公共IHttpActionResult PutUser(用戶配置USERPROFILE)

  2. 在我的控制器的DELETE動詞沒有得到從郵遞員或angularjs正確的輸入,由於一個錯字。

給自己的注意事項:多睡覺,看這些URL。

這是我工作的控制器的外觀:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Web; 
using System.Web.Http; 
using System.Web.Http.Description; 
using Microsoft.Ajax.Utilities; 
using Microsoft.Practices.Unity; 
using TrackInstant.Models.Entities; 
using TrackInstant.Services; 

namespace TrackInstant.Controllers 
{ 

    public class UserProfileController : ApiController 
    { 
     [Dependency] 
     public UserProfileService UserProfileService { private get; set; } 


     public IEnumerable<UserProfile> GetAllUsers() 
     { 
      return UserProfileService.GetAllUserProfiles(); 
     } 

     public UserProfile GetUserById(int id) 
     { 
      UserProfile userProfile = UserProfileService.GetUser(id); 
      if (userProfile == null) 
      { 
       throw new HttpResponseException(HttpStatusCode.NotFound); 
      } 
      return userProfile; 
     } 

     public IHttpActionResult PostUser(UserProfile userProfile) 
     { 

      if (userProfile == null) 
      { 
       return BadRequest(); 
      } 

      UserProfileService.Save(userProfile); 

      return CreatedAtRoute("DefaultApi", new { id = userProfile.UserId }, userProfile); 
     } 


     public IHttpActionResult PutUser(UserProfile userProfile) 
     { 
      UserProfile persistentUser = UserProfileService.GetUser(userProfile.UserId); 
      if (persistentUser == null) 
      { 
       throw new HttpResponseException(HttpStatusCode.NotFound); 
      } 
      persistentUser.Email = userProfile.Email; 
      UserProfileService.UpdateUser(persistentUser); 

      return StatusCode(HttpStatusCode.NoContent); 
     } 


     public IHttpActionResult DeleteUser(int id) 
     { 
      UserProfile persistentUser = UserProfileService.GetUser(id); 
      if (persistentUser == null) 
      { 
       throw new HttpResponseException(HttpStatusCode.NotFound); 
      } 
      UserProfileService.DeleteUser(persistentUser); 

      return Ok(persistentUser); 
     } 
    } 
}