2014-09-14 9 views
11

Ich arbeite an einem ASP.NET WebAPI-Projekt mit grundlegenden CRUD-Operationen. Das Projekt wird lokal ausgeführt und enthält eine Beispieldatenbank in Windows Azure.PUT und Löschen funktioniert nicht mit ASP.NET WebAPI und Datenbank unter Windows Azure

Bis jetzt funktioniert das Http GET und POST, gibt mir eine 200 und 201. Aber ich kämpfe mit DELETE und POST. Ich änderte die Handler in der Web.config, entfernte WebDav, aber nichts davon funktionierte. Auch die Aktivierung von CORS und aller Arten von Attributen wie [AcceptVerbs] funktionierte nicht.

Irgendeine Idee, was ich falsch mache?

Fiddler Raw Ausgabe:

HTTP/1.1 405 Method Not Allowed 
Cache-Control: no-cache 
Pragma: no-cache 
Allow: GET 
Content-Type: application/json; charset=utf-8 
Expires: -1 
Server: Microsoft-IIS/8.0 
X-AspNet-Version: 4.0.30319 
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcTWFyY1xPbmVEcml2ZVxEb2t1bWVudGVcRmlcVnNQcm9qZWt0ZVxONTIwMTQwODI1XE41XE41XGFwaVxwcm9kdWN0XDEwODM=?= 
X-Powered-By: ASP.NET 
Date: Sun, 14 Sep 2014 15:00:43 GMT 
Content-Length: 75 

{"Message":"The requested resource does not support http method 'DELETE'."} 

Web.config:

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

Controller:

public class ProductController : BaseApiController 
    { 
     public ProductController(IRepository<Product> repo) 
      : base(repo) 
     { 

     } 

     [HttpGet] 
     public IEnumerable<Product> Get() 
     { 
      //... 
     } 

     [HttpGet] 
     public Product Get(int id) 
     { 
      //... 
     } 

     [HttpPost] 
     public HttpResponseMessage Post([FromBody] Product product) 
     { 
      //... 
     } 

     [HttpPut] 
     public HttpResponseMessage Put(int productId, [FromBody] Product product) 
     { 
      //.. 
     } 

     [HttpDelete] 
     public HttpResponseMessage Delete(int productId) 
     { 
      //.. 
     } 

    } 

Routing & Formatter:

public static void Register(HttpConfiguration config) 
    { 
     // Web API configuration and services 
     // Configure Web API to use only bearer token authentication. 
     config.SuppressDefaultHostAuthentication(); 
     config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); 


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

     // Custom Formatters: 
     config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(
      config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml")); 

     var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First(); 
     jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 
    } 
} 
+0

Warum rufen Sie das Attribut-Routing auf, aber Sie konfigurieren die Produktroute mithilfe der WebApi2-Vorbereitungsmethode für eine Route? –

+0

Es ist ein Überbleibsel und sollte nicht da sein. Ich aktualisiere es. thx – oldsport

Antwort

25

Endlich fand ich, was ich vermasselt habe. Die Benennung der Id (productId) in beiden Controller-Methoden (Post und Put) muss identisch sein wie im Customized Routing (id). Als ich es von productId zu id änderte, arbeiteten sowohl POST als auch PUT in fiddler. Danach habe ich meine Web.config-Einstellungen auf die Standardeinstellungen zurückgesetzt. Dies ist, was ich geändert:

Controller:

[HttpPut] 
    public HttpResponseMessage Put(int id, [FromBody] Product product) 
    { 
     //.. 
    } 

    [HttpDelete] 
    public HttpResponseMessage Delete(int id) 
    { 
     //.. 
    } 

Web.config:

<system.webServer> 
<modules> 
    <remove name="FormsAuthentication" /> 
</modules> 
<handlers> 
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
    <remove name="OPTIONSVerbHandler" /> 
    <remove name="TRACEVerbHandler" /> 
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
</handlers> 

+0

Wenn Sie das integrierte Standardrouting verwenden, muss der Parametername auch "id" lauten. – RMorrisey

7

Die "Attribut Routing in ASP.NET Web API 2" (20-Jan -2014) Artikel sagt uns folgendes;

Routing ist, wie Web-API einen URI mit einer Aktion übereinstimmt. Web API 2 unterstützt eine neue Art von Routing, Attribut-Routing genannt.

(Siehe: "Attribute Routing in ASP.NET Web API 2")

So, wie der Web-API-2, können Sie auch das Problem beheben, indem Sie die Route Attribut Hinzufügen von [dem Verfahren in Frage] mit dem Platzhalter genannt, wie Sie möchten.

Getestet dies in meinem eigenen Code, weil ich mit dem gleichen Problem getroffen wurde, und es funktionierte wie ein Charme!

+0

In dem obigen Code, warum konnte productId nicht mehr als Werte sein. Zählen und noch gültig sein. Soweit ich sehen kann, würde die Verwendung dieser if-Anweisung letztendlich fehlschlagen. –

+0

@KeenanStewart Der Code ist nur ein schnelles und schmutziges Beispiel. Hier geht es um das Attribut Routing. –

Verwandte Themen