1

I was trying to call the Put method through Postman and always getting error:
"405 Method Not Allow" and "Message": "The requested resource does not support http method 'PUT'."

I'm using DocumentDB and C#. Here is my code:

[Route("multilanguage/Resources/{id}/{Language}")]
[HttpPut]
public async Task<IHttpActionResult> UpdateResource(string Id, string Language, string text)
{
    client = new DocumentClient(new Uri(EndPoint), AuthKey);
    var collectionLink = UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId);

    var query = new SqlQuerySpec("SELECT * FROM MultiLanguage as m where m.id = @pmId", 
    new SqlParameterCollection(new SqlParameter[] { new SqlParameter { Name = "@pmId", Value = Id } }));

    Document doc = client.CreateDocumentQuery<Document>(
            collectionLink, query).AsEnumerable().FirstOrDefault();

    List<Models.Translations> d = doc.GetPropertyValue<List<Models.Translations>>("Translations");
    Models.Translations temp = d.Find(p => p.Language == Language);

    temp.Content = text;
    temp.LastModified = DateTimeOffset.Now;
    temp.ModifiedBy = "admin";
    doc.SetPropertyValue("Translations", d);

    Document updated = await client.ReplaceDocumentAsync(doc);

    return Ok();
}

When I call the Put method throught Postman, I call "http://localhost:XXXX/multilanguage/resources/2/En". "2" and "En" are the first two parameters in my code. And I also specify the "text" parameter value in the Postman request Body with x-www-form-urlencoded type: key = text, value = Test! This put method suppose to update the temp.Content value to "Test!". However, it always failed with the error I mentioned above.

Did I miss anything here?

Julie C.
  • 629
  • 2
  • 11
  • 20

2 Answers2

2

The 405 error when performing a PUT request to web api is a well known topic. You can find many solutions in this or this SO question.

And for the design of you controller:

PUT are designed to have a body, just like POST and in your case you should send all parameters in the body instead.

You should create a class which contains the objects you want to send to the server:

public class resourceClass
{
    public string Id { get; set; }
    public string Language { get; set; }
    public string text { get; set; }
}

Then specify the route without the attribute routing and get the object from the request body

[Route("multilanguage/Resources/PutResource")]
[HttpPut]
public async Task<IHttpActionResult> UpdateResource([FromBody] resourceClass obj)
{
    client = new DocumentClient(new Uri(EndPoint), AuthKey);
    var collectionLink = UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId);

    var query = new SqlQuerySpec("SELECT * FROM MultiLanguage as m where m.id = @pmId", 
    new SqlParameterCollection(new SqlParameter[] { new SqlParameter { Name = "@pmId", Value = Id } }));

    Document doc = client.CreateDocumentQuery<Document>(
            collectionLink, query).AsEnumerable().FirstOrDefault();

    List<Models.Translations> d = doc.GetPropertyValue<List<Models.Translations>>("Translations");
    Models.Translations temp = d.Find(p => p.Language == Language);

    temp.Content = text;
    temp.LastModified = DateTimeOffset.Now;
    temp.ModifiedBy = "admin";
    doc.SetPropertyValue("Translations", d);

    Document updated = await client.ReplaceDocumentAsync(doc);

    return Ok();
}

From the client you could add an object to the PUT request of Content-Type application/json like this

var data = {
    Id: clientId,
    Language: clientLanguage,
    text: clientText
};

Don't forget to stringify the json when adding it to the http request

data: JSON.stringify(data),

The PUT controller will then be reached at "http://localhost:XXXX/multilanguage/resources/putresource".

Community
  • 1
  • 1
Marcus Höglund
  • 16,172
  • 11
  • 47
  • 69
0

Check the URL for which you are posting the data, in my case the URL was incorrect because of which I got these errors, also verify that in Body you should select raw and change the Text to JSON if you are passing a JSON as a data.