locked
How to get .net c# webAPI PUT and DELETE methods / verbs working RRS feed

  • Question

  • User-1740395346 posted

    I keep getting a 404 when i do a request via PUT or DELETE. This is driving me loco!

    My machince settings is windows 7, with iis 7.5.

    I have create the first webAPI project on my machine. With the code below I can change the type of verb to POST or GET and the request to the server and the response back to the client work perfectly.

    As the code is below I keep getting eaither a 405 error code or a 404 not found error code.

    My question is is their some type of setting that I need to add to the .config file or a setting that I need to make on the iis7.5 web server so I can get this working?

    In my JavaScript file on the client.

      $.ajax(
                         
    {
                             url
    : "/api/project",
                             type
    : "PUT",
                             contentType
    : "application/json",
                             data
    :'3',
                             success
    : function (result) {
                                alert
    (result);
                             
    }
                         
    });

    In the controller in c# class

       public void Put(int intt)
       
    {
           
    var obj = intt;
       
    }
    I've been tring to resolve this for over a day now and I really need to get this resolved! How or what do I need to do to be able to post to the server using PUT and DELETE?

    URGENT! 
    Friday, July 20, 2012 12:47 PM

Answers

  • User1779161005 posted

    I've run with IIS 7.5, so I think it's back to diagnosing that on your machine. I think you were using FREB earlier, so maybe use FREB and Fiddler on this sample project to get as much info as you can.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, July 21, 2012 5:06 PM

All replies

  • User1779161005 posted

    In IIS I had to:

    1) Uninstall WebDEV -- apparently you can't just disable it. You need to uninstall it from everything I read.

    2) Make sure to add the verbs PUT and DELETE to the Extensionless URL Http Handler.

    Friday, July 20, 2012 4:28 PM
  • User-1740395346 posted

    I have removed the wevDEV and added PUT,DELETE to all three Extensionless URL Http Handler.

    The only error iis7.5 now supplies is.

    What in the world am i missing?

    Help is greatly appricated! 

    ModuleName ManagedPipelineHandler
    Notification 128
    HttpStatus 400
    HttpReason Bad Request
    HttpSubStatus 0
    ErrorCode 0
    ConfigExceptionInfo
    Notification EXECUTE_REQUEST_HANDLER
    ErrorCode The operation completed successfully. (0x0)
    ManagedPipelineHandler
    Friday, July 20, 2012 6:03 PM
  • User1779161005 posted

    Progress! :)

    Hmm, as for this one... not sure. I mean... start putting break points in all your server code to see how far you get into the WebAPI code. Do you have any delegating handlers or anyting like that? If you can't narrow it down, maybe create a new controller with as little as possible (or a new project even) just to see if the IIS part is letting you in.

    Sorry I don't have anything better.

    Friday, July 20, 2012 6:10 PM
  • User-1740395346 posted

    Thank you for your help.

    I've created a new site and still this issue.

    This is so freaking aggervating.

    Friday, July 20, 2012 6:50 PM
  • User1779161005 posted

    Thank you for your help.

    I've created a new site and still this issue.

    This is so freaking aggervating.

    Hmm, so then maybe something baou the request is invalid in some way? What's the client code -- .NET or JavaScript?

    Friday, July 20, 2012 7:11 PM
  • User-1740395346 posted

    Here is the client code below, I am keeping it as simple as possiable right now just to make it work.

    If I change the PUT to POST then it works. I cannot even get it to break in debug mode, it's like it is not even makeing to the PUT method.

                        $.ajax(
                             {
                                 url: "/api/project",
                                 type: "PUT",
                                 contentType: "application/json",
                                 data: '7',
                                 success: function (result) {
                               
                                 }
                             });

    Server code

      public void Put(object obj)
            {
                var objx = obj;
            }

    Friday, July 20, 2012 7:24 PM
  • User1779161005 posted

    Ok, I'm guessing that you have the default route? What's happeing is this error is being produced (at least when I ran your same client code):

    "The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Net.Http.HttpResponseMessage Put(Int32, MovieReviewApp.Api.MovieDetails)' in 'MovieReviewApp.Api.MoviesController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."

    Run fiddler and you can see the error message in the body of the 400 response.

    So change the URL to contain and id.

    If that's not it, then I'm guessing the plumbing didn't like deserializing '7' into an object, but I didn't try to repo that.

    Friday, July 20, 2012 7:31 PM
  • User-1740395346 posted

    I have tried it /api/project/7 and the other way that I posted. I've also tried it with no parameter at all.

    Here is the return 404.. " THANK YOU FOR HELPING !"

    HTTP/1.1 404 Not Found
    Cache-Control: private
    Content-Type: text/html; charset=utf-8
    Server: Microsoft-IIS/7.5
    X-Powered-By: ASP.NET
    Date: Fri, 20 Jul 2012 23:33:43 GMT
    Content-Length: 5373

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>IIS 7.5 Detailed Error - 404.0 - Not Found</title>
    <style type="text/css">
    <!--
    body{margin:0;font-size:.7em;font-family:Verdana,Arial,Helvetica,sans-serif;background:#CBE1EF;}
    code{margin:0;color:#006600;font-size:1.1em;font-weight:bold;}
    .config_source code{font-size:.8em;color:#000000;}
    pre{margin:0;font-size:1.4em;word-wrap:break-word;}
    ul,ol{margin:10px 0 10px 40px;}
    ul.first,ol.first{margin-top:5px;}
    fieldset{padding:0 15px 10px 15px;}
    .summary-container fieldset{padding-bottom:5px;margin-top:4px;}
    legend.no-expand-all{padding:2px 15px 4px 10px;margin:0 0 0 -12px;}
    legend{color:#333333;padding:4px 15px 4px 10px;margin:4px 0 8px -12px;_margin-top:0px;
     border-top:1px solid #EDEDED;border-left:1px solid #EDEDED;border-right:1px solid #969696;
     border-bottom:1px solid #969696;background:#E7ECF0;font-weight:bold;font-size:1em;}
    a:link,a:visited{color:#007EFF;font-weight:bold;}
    a:hover{text-decoration:none;}
    h1{font-size:2.4em;margin:0;color:#FFF;}
    h2{font-size:1.7em;margin:0;color:#CC0000;}
    h3{font-size:1.4em;margin:10px 0 0 0;color:#CC0000;}
    h4{font-size:1.2em;margin:10px 0 5px 0;
    }#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS",Verdana,sans-serif;
     color:#FFF;background-color:#5C87B2;
    }#content{margin:0 0 0 2%;;}
    .summary-container,.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;;}
    .config_source{background:#fff5c4;}
    .content-container p{margin:0 0 10px 0;
    }#details-left{width:35%;float:left;margin-right:2%;
    }#details-right{width:63%;float:left;overflow:hidden;
    }#server_version{width:96%;_height:1px;min-height:1px;margin:0 0 5px 0;padding:11px 2% 8px 2%;color:#FFFFFF;
     background-color:#5A7FA5;border-bottom:1px solid #C1CFDD;border-top:1px solid #4A6C8E;font-weight:normal;
     font-size:1em;color:#FFF;text-align:right;
    }#server_version p{margin:5px 0;}
    table{margin:4px 0 4px 0;width:100%;border:none;}
    td,th{vertical-align:top;padding:3px 0;text-align:left;font-weight:bold;border:none;}
    th{width:30%;text-align:right;padding-right:2%;font-weight:normal;}
    thead th{background-color:#ebebeb;width:25%;
    }#details-right th{width:20%;}
    table tr.alt td,table tr.alt th{background-color:#ebebeb;}
    .highlight-code{color:#CC0000;font-weight:bold;font-style:italic;}
    .clear{clear:both;}
    .preferred{padding:0 5px 2px 5px;font-weight:normal;background:#006633;color:#FFF;font-size:.8em;}
    -->
    </style>
     
    </head>
    <body>
    <div id="header"><h1>Server Error in Application "STOREFRONTSYSTEMM.NET"</h1></div>
    <div id="server_version"><p>Internet Information Services 7.5</p></div>
    <div id="content">
    <div class="content-container">
     <fieldset><legend>Error Summary</legend>
      <h2>HTTP Error 404.0 - Not Found</h2>
      <h3>The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.</h3>
     </fieldset>
    </div>
    <div class="content-container">
     <fieldset><legend>Detailed Error Information</legend>
      <div id="details-left">
       <table border="0" cellpadding="0" cellspacing="0">
        <tr class="alt"><th>Module</th><td>IIS Web Core</td></tr>
        <tr><th>Notification</th><td>MapRequestHandler</td></tr>
        <tr class="alt"><th>Handler</th><td>StaticFile</td></tr>
        <tr><th>Error Code</th><td>0x80070002</td></tr>
         
       </table>
      </div>
      <div id="details-right">
       <table border="0" cellpadding="0" cellspacing="0">
        <tr class="alt"><th>Requested URL</th><td>http://storefrontsystemm.net:80/api/project</td></tr>
        <tr><th>Physical Path</th><td>C:\inetpub\wwwroot\StorefrontSystem\api\project</td></tr>
        <tr class="alt"><th>Logon Method</th><td>Anonymous</td></tr>
        <tr><th>Logon User</th><td>Anonymous</td></tr>
        <tr class="alt"><th>Failed Request Tracing Log Directory</th><td><a href="file://C:\inetpub\logs\FailedReqLogFiles">C:\inetpub\logs\FailedReqLogFiles</a></td></tr>
       </table>
       <div class="clear"></div>
      </div>
     </fieldset>
    </div>
    <div class="content-container">
     <fieldset><legend>Most likely causes:</legend>
      <ul>     <li>The directory or file specified does not exist on the Web server.</li>     <li>The URL contains a typographical error.</li>     <li>A custom filter or module, such as URLScan, restricts access to the file.</li> </ul>
     </fieldset>
    </div>
    <div class="content-container">
     <fieldset><legend>Things you can try:</legend>
      <ul>     <li>Create the content on the Web server.</li>     <li>Review the browser URL.</li>     <li>Create a tracing rule to track failed requests for this HTTP status code and see which module is calling SetStatus. For more information about creating a tracing rule for failed requests, click <a href="http://go.microsoft.com/fwlink/?LinkID=66439">here</a>. </li> </ul>
     </fieldset>
    </div>
     
     
    <div class="content-container">
     <fieldset><legend>Links and More Information</legend>
      This error means that the file or directory does not exist on the server. Create the file or directory and try the request again.
      <p><a href="http://go.microsoft.com/fwlink/?LinkID=62293&amp;IIS70Error=404,0,0x80070002,7601">View more information &raquo;</a></p>
       
     </fieldset>
    </div>
    </div>
    </body>

    Friday, July 20, 2012 7:37 PM
  • User-1740395346 posted

    Here is my RouteConfig.

        public class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

                routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}/{id}",
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );
            }
        }

    Friday, July 20, 2012 8:02 PM
  • User1779161005 posted

    Right, so did you try it with an updated URL? According to your route and your Put on the controller, the PUT needs /api/{controller}/{id} for the URL. Also, the param to the Put needs to be called id, so Put(int id), not "intt".

    Was this working with Cassini or IIS Express?

    Friday, July 20, 2012 8:41 PM
  • User-1740395346 posted

    My development enviroment is windows7 and iis7.5, with visual studio 2012RC

       CLIENT:

    $.ajax(
                             {
                                 url: "/api/project",
                                 type: "PUT",
                                 data: JSON.stringify({ id: 3, value: 'str' }),
                                 contentType: "application/json",
                                 success: function (result) {

                                 }
                             });
                    }

    SERVER:

            public void Put(int id,string value)
            {
                var objx = value;
            }

    This may be something to do with visual studio 2012RC. I've updated everything possiable. I've been developing for 8 years now, so I'm versed; however, this has got me totally stumped....

    Friday, July 20, 2012 9:00 PM
  • User1779161005 posted

    Change the URL to "/api/project/1" -- you're missing the {id} param in the URL. And now since you're passing a JSON object as the data, the 2nd param to your server method should be an object param (which can be strongly type, but object works): Put(int id, object data).

    Here's one I just created:

    C#:

    // PUT api/values/5
            public void Put(int id, object value)
            {
    
            }



    JS:

    <script>
        $(function () {
            $.ajax({
                url: "/api/values/1",
                contentType: "application/json",
                type: "PUT",
                data: JSON.stringify({foo:"hello"}),
                success: function (result) {
                    console.log(result);
                }
            });
        });
    
    </script>



    Friday, July 20, 2012 9:11 PM
  • User-1740395346 posted
    1. I think .net hates me...
    2.       $.ajax(
                               {
                                   url: "/api/project/1",
                                   type: "PUT",
                                   data: JSON.stringify({value: 'str' }),
                                   contentType: "application/json",
                                   success: function (result) {

                                   }
                               });
                      }

    1.    public void Put(int id,object value)
              {
                  var objx = value;
              }

    Request URL:http://storefrontsystemm.net/api/project/1
    Request Method:PUT
    Status Code:404 Not Found
    Request Headersview source
    Accept:*/*
    Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
    Accept-Encoding:gzip,deflate,sdch
    Accept-Language:en-US,en;q=0.8
    Content-Length:15
    Content-Type:application/json
    Host:storefrontsystemm.net
    Origin:http://storefrontsystemm.net
    Proxy-Connection:keep-alive
    Referer:http://storefrontsystemm.net/
    User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11
    X-Requested-With:XMLHttpRequest
    Request Payload
    {"value":"str"}
    Response Headersview source
    Cache-Control:private
    Content-Length:5377
    Content-Type:text/html; charset=utf-8
    Date:Sat, 21 Jul 2012 01:14:40 GMT
    Server:Microsoft-IIS/7.5
    X-Powered-By:ASP.NET

    Friday, July 20, 2012 9:17 PM
  • User1779161005 posted

    The only other thing I can think of is that it looks like you're deplyed to IIS, so if there's an application then that also needs to be in the URL. For example, if the app is deployed to ":http://storefrontsystemm.net/yourappname" then the ajax URL will have to include that name, so:

    $.ajax({
        url : "/yourappname/api/project/1"
        ....

    Saturday, July 21, 2012 11:57 AM
  • User-1740395346 posted

    Do you have a link to a site that has a downloadable working example of the PUT,DELETE method? This way I can take a known working example and work outward. I am almost positive this has something to do with iis7.5 on my local machine but I do not know what it can be.

    I am also placeing a breakpoint on my put method that I cannot reach for the bad request, my question is , is there another place I can begin debugging and work my way to the PUT method to see where it breaks before it gets to the put method?

    I've got the new visual studio 2012 as my developement enviroment and this may have something to do with it, but there is so little info on the net to help me with this type of error.

    Saturday, July 21, 2012 2:05 PM
  • User1779161005 posted

    Yep, here's a sample: http://sdrv.ms/NElIDd

    Saturday, July 21, 2012 3:19 PM
  • User-1740395346 posted

    It worked wit this example.

    Opened Fiddler and did a PUT to the app using the signature below so I did not have to pass the movie xml paramater and it returned just fine.

      public HttpResponseMessage Put(int id)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest, "You're Putting!");

    The example is using iis express 8 and I am using iis7.5 on windows7. This is a setting somewhere in iis7.5 that is causing my issue.

    What should I do? Develop with the iis8 Express or find a way to get iis7.5 to work?

    Surely this is something to do with my iis7.5 settings and not iis7.5 in general. Becuase my server is running server2008 with iis7.5. Do I need to upgrage everthing to make the webapi work?

    Saturday, July 21, 2012 5:01 PM
  • User1779161005 posted

    I've run with IIS 7.5, so I think it's back to diagnosing that on your machine. I think you were using FREB earlier, so maybe use FREB and Fiddler on this sample project to get as much info as you can.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, July 21, 2012 5:06 PM
  • User-1740395346 posted

    Ok, here is the deal.

    I've repeated this process about 5 times.

    Start VS2012, Create a new MVC4 project, Choose WebAPI as the type.

    The projects get set under the Default Web Site of iis7.5

    I do a get, everything works as expected. I do a PUT everything works as expected.

    Ok,

    --------------------------------------SCRATCH THIS-------------------------------------------------------------

    I right click ->copy the mvcproject, paste the entire project  into a website outside the Default Web Site so that the project can simulate having it's own domain name, "Just like in production". I do a get from fiddler, everything works perfect, I do a PUT and I get that dam 404 Not Found, over and over again.

    -----------------------------------------------------------------------------------------------------------------------

    I right click and copy the project from the projects folder inside my documents and then paste the project into iis7.5

    I can just develope with the working senerio; however, what happens when I move over to the production server? So, I've got to find a fix before then.

    I've been on this one project for almost a year, and I sure do not need to headach of finding a fix at launch time. ;)

    Just to let you know I've tried altering the ExtensionlessUrlHandler-ISAPI-4.0_64bit and adding PUT,DELETE to the accept verbs and this does not solve the issue.

    Worse comes to worse I;ve done this process over and over so much to where I could capture the screen as a video and post what I am talking about.

    Saturday, July 21, 2012 8:32 PM
  • User-1891547698 posted

    Hi, You could use the ff. attributes for specific methods in you service.

    [WebGet(UriTemplate = "{key}")]

    public Get ...  

    [WebInvoke(Method = "PUT", UriTemplate = "{key}")]      

    public Update...

     [WebInvoke(Method = "POST")]      

    public Add...  

    [WebInvoke(Method = "DELETE", UriTemplate = "{key}")] 

    public remove...

     

    Please mark this if it helps..

    Monday, July 23, 2012 5:26 AM
  • User-1740395346 posted

    If you will please write the entire signature out. You're assuming that I know something that you're not showing.

    How does UriTemplate play into this? Do I need to set any other settings in the filter section?

    Thank you.

    Monday, July 23, 2012 11:02 AM
  • User276734987 posted

    I had this issue before as well.

    The only thing that I found that fixed it was to add the PUT and DELETE verbs to the ExtensionlessUrlHandler as per:

    http://geekswithblogs.net/michelotti/archive/2011/05/28/resolve-404-in-iis-express-for-put-and-delete-verbs.aspx

    Hope that helps

    Monday, July 23, 2012 10:39 PM
  • User-230568899 posted

    I have the exact same issue and getting 404 not found error. My sandbox server works fine by adding the IIS Role Service HttpRedirection and remove WebDAV. Unfortunately, I can't get it to work on the production server and it's behaving the sameway as the OP.

    Monday, October 22, 2012 11:16 AM