ASP MVC: HTTP Error 405.0 - Method Not Allowed - visual-studio

I have ASP MVC 4 Visual Studio 2017 project running in my Windows 10 machine. When my page loads, it makes jquery ajax post call to load contents of the page. Now when i run the project, it is giving me HTTP Error 405.0 - Method Not Allowed error page.
Error Screenshot
Here is what i did so far:
Checked WebDAV and make sure it is not running.
Made sure all the handlers has appropriate verbs. Actually i added 'GET,HEAD,POST,DEBUG,PUT,DELETE' in all handlers tag in %windir%\system32\inetsrv\config\applicationhost.config file just to make sure i don't miss anyone.
Note: This site was working previously when i ran through my Visual Studio 2017. I configure project to use SSL and that is when i started running into this 405 error. I changed the project not to use SSL but still i am running into this 405 error.
Can you guys suggest how i can fix this issue?
Thanks
Razor Code:
<ul class="partialContents" data-url="#Url.Action("LoadUser", "BaseWeb")"></ul>
Jquery:
$(".partialContents").each(function (index, item){
var url = $(item).data("url");
if (url && url.length > 0) {
$(item).load(url);
}
});
Controller:
public async Task<ActionResult> LoadUser()
{
var httpClient = await GetHttpClient(); <--returns WebAPI running locally
UserModel requestModel = new UserModel();
requestModel.Email = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Name).Value;
var response = await httpClient.PostAsJsonAsync("api/user/", requestModel);
var result = await response.Content.ReadAsStringAsync();
var userModel = JsonConvert.DeserializeObject<List<UserModel>>(result);
return PartialView("_LoadUser", userModel);
}

Related

PostAsync hanging in Xamarin Forms works on emulator but hangs on actual Mobile phone

I have Xamarin Forms project where I'm trying to POST and GET data to/from a Web API but when I'm making an async/await call, it works on the emulator (not without its original problems!) but when I try it on my actual phone mobile (Samsung S8+), it just hangs indefinitely.
Note that I'm only concentrating on the Android part right now, not iOS, not that the problem should make any difference in either.
This is the code I'm using:
IDataService.cs
Task<TResponse> PostDataAsync<TRequest, TResponse>(string uri, TRequest data)
where TRequest : class
where TResponse : class;
DataService.cs:
public async Task<TResponse> PostDataAsync<TRequest, TResponse>(string
additionalUri, TRequest data)
where TRequest : class
where TResponse : class
{
return await WebClient
.PostData<TRequest, TResponse>
(string.Concat(this.Uri, additionalUri), data);
}
WebClient.cs
using (var client = new HttpClient())
{
var jsonData = JsonConvert.SerializeObject(data);
using (var response = await client.PostAsync(
uri,
new StringContent(jsonData,
Encoding.UTF8,
"application/json" )))
{
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<TResponse>(content);
}
}
}
Method 1:
LoginPageViewModel.cs
public DelegateCommand SignInCommand => _signInCommand ??
(this._signInCommand = new DelegateCommand(SignInCommandAction));
private async void SignInCommandAction()
{
try
{
....
var user = await this._dataService
.PostDataAsync<LoginRequestDto,
LoginResponseDto>(#"Accounts/Login", loginRequestDto);
....
}
...
}
Method2:
LoginPageViewModel.cs
public DelegateCommand SignInCommand => _signInCommand ??
(this._signInCommand =
new DelegateCommand(async () => await SignInCommandAction()));
private async Task SignInCommandAction()
{
try
{
....
var user = await this._dataService
.PostDataAsync<LoginRequestDto,
LoginResponseDto>(#"Accounts/Login", loginRequestDto);
....
}
...
}
The PostDataAsync works with both methods when I call my local web API i.e. http://10.0.2.2/MyApp/api/ but both methods still hangs when calling external my web service from web provider i.e. http://myapp-123-site.atempurl.com/api/ which is a temp url for testing purpose.
The same apply to my GetDataAsync which is not demonstrated in question but I just thought I'd mention it.
Based on the above, you would think that my async/await code is correct since it works when calling the local web api but then what's causing it to hang when calling the remote web api.
As mentioned, I did enable my INTERNET permission in the manifest.
Any suggestions welcomed?
Thanks.
UPDATE-1:
Note that I've just tried to call a GET opertation within the same function and this is working in the emulator but hanging with the actual mobile.
using (var client = new HttpClient())
{
using (var response = await client.GetAsync(uri))
{
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
return Newtonsoft.Json.JsonConvert
.DeserializeObject<TResponse>(content);
}
}
}
UPDATE-2:
This is somehow working and I have no idea why! The only thing that comes to mind is that I upgraded my libraries. This included PRISM which may have been at the source of the problem but I have no idea.
Sorry I can't provide more details. I could role back my code and try to see if it's hanging again but I just don't have the time to go and experiment some more considering the amount of time I've already spent on this. Sorry.
The requested url is an IP or a domain name.
If it is ip, only the IP of the public network can be accessed by devices on multiple network segments.
If it is a domain name, it needs to support the domain name resolution service.
If you do not have these environments for a while, you need the IP of the device and the IP of the server on the same network segment.
The PostDataAsync works with both methods when I call my local web API i.e. http://10.0.2.2/MyApp/api/ but both methods still hangs when calling external my web service from web provider i.e. http://myapp-123-site.atempurl.com/api/ which is a temp url for testing purpose.
From this phenomenon , the reason should be the temp url. From this domain name (myapp-123-site.atempurl.com) can not find the right local IP (10.0.2.2).And when you test in local network , I guess this will work.However the network of actual mobile can be not the same with local network , such as using 3G/4G network , then this will not working.

Connecting to localhost with Restsharp on Android

I created a Web API and would like to access it in my Android XAMARIN App. It's a XAMARIN Forms App, which references a .NET Standard 2.0 library with the newest RestSharp nuget package installed.
Unfortunately I get the error:
Error: ConnectFailure (No route to host)
whenever I do the following:
public async Task<List<ETFPortfolio>> GetPortfolios()
{
var client = new RestClient("http://10.0.2.2:51262/api/");
var request = new RestRequest("portfolio", Method.GET);
request.AddHeader("Accept", "application/json");
var response = client.Execute(request); // Result with the error stated above
throw new Exception();
}
My WebAPI controller is set up like this:
[Route("api/[controller]")]
public class PortfolioController : Controller
{
// GET api/portfolio
[HttpGet]
public async Task<IActionResult> Get()
{
try
{
var handler = new MyHandler();
var portfolioList = await handler.Handle();
return Ok(portfolioList);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
I found a similar question, unfortunately there were no answers yet.
Error: ConnectFailure (No route to host)
Is there anything I'm missing here or could check out to make this work?
Since you are using a real device, your API url should not be a localhost but an IP address of the computer on which you have the API running.
localhost will work only on the emulator running on the same machine with your API.
P.S.: I wrote a blogpost on this topic, you might be interested in checking it as well.

I don't get the $.connection.[hubName]

I try to add web socket functionality using signalR, based on :
the chat example.
I have 2 different project -
1: is pure server, includes web api:
I have a web method to get the request and call to hub:
[HttpGet]
[Route("api/GetData")]
public IHttpActionResult GetCorpDataApi()
{
return Ok(getResponse());
**startWebSocket();**
}
the start web socket method calls to:
private void startWebSocket()
{
MonitorHub hub = new MonitorHub();
Timer myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler(hub.DisplayTimeEvent);
myTimer.Interval = 3000;
myTimer.Start();
}
that calls to a method in my hub:
public class MonitorHub : Hub
{
public void DisplayTimeEvent(object source, ElapsedEventArgs e)
{
var response = MonitorUtils.GetCorpData();
Clients.All.broadcastMessage(response);
}
}
(All is in the same project, compiled with no errs).
My client code is located in the client angular project (also under VS),
I added the required functionality within the controller:
function initWebSocket() {
self.chatHub = null; // holds the reference to hub
self.chatHub = $.connection.MonitorHub; // **I dont have MonitorHub**
$.connection.hub.start();
self.chatHub.client.broadcastMessage = function (response) {
//bla bla
};
}
I want to mention that I included in the index.html the files:
<script src="scripts/Vendor/jquery/jquery-2.2.1.js"></script>
<script src="scripts/Vendor/jquery/jquery.signalR-2.2.1.js"></script>
<script src="scripts/signalr/hubs"></script>
<script src="assets/global/plugins/angularjs/angular.min.js" type="text/javascript"></script>
$.connection.MonitorHub gets nothing - undefined.
I really believe that it has something to do with the fact that the server side
is in a different project than the client side. When I run a simple example like the chat example, it works - all in the same project.
I get in the console this error:
Error: SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. .
Any idea?
I am not 100% sure but it might be a case of JQuery version mismatch. Try using a lower jquery version e.g. jquery-1.6.4.js
You did not seem to have added SignalR server to your project. You seem to be starting a WebSocket and create an instance of a hub and throwing some Web API. This is not how SignalR works. You need to install SignalR server packages to your server and then SignalR will take care of handling your calls, instantiating your hubs etc. Just follow the tutorial you posted a link to (Setting up the project section) or this one.

Calling an ASP.Net RESTful POST controller API method with HTTPClient.PostAsync

A colleague has written an Azure Mobile Service API which includes the following controller method:
public class SegmentationController : ApiController
{
// [...]
// POST api/<controller>/id
public async Task<string> Post(string id)
{
// [...]
I am trying to call that from a Windows Universal app. The calls to GET methods work without issue but I am failing to call that POST method. Here is what I've tried:
response = await client.PostAsync("api/segmentation/", new StringContent(item.Id));
// 405 Method Not Allowed
response = await client.PostAsync("api/segmentation/" + item.Id, new StringContent(""));
// 500 Internal Server Error
response = await client.PostAsync("api/segmentation/", new StringContent("id=" + item.Id));
// 405 Method Not Allowed
response = await client.PostAsync("api/segmentation/", new StringContent("{\"id\":" + item.Id + "}"));
// 405 Method Not Allowed
(N.B. System.Collections.Specialized.NameValueCollection used in Marc's answer is not available on WinRT / Windows Universal.)
It is possible that my second call is correct and that the error is in the server side code; we are exploring that possibility.
What is the correct way to make a POST call to an ASP.Net RESTful API method which expects a parameter called "id" of type string?
Your parameter is the problem. You have two options:
Use a query parameter instead of body. e.g. api/segmentation?id=abc
Add [FromBody] Attribute to your parameter. e.g. public async Task<string> Post([FromBody]string id)
Now your parameter is read from body. by default only complex types are read from body.
For more details see Parameter Binding in ASP.NET Web API
It was a server error. Once we had added error reporting code we could see that the problem was the server failing to load a C++ DLL it relied on due to an x64 /x86 mismatch on Azure. The call style that now works is the second one I list in the question:
response = await client.PostAsync("api/segmentation/" + item.Id, new StringContent(""));

WebApi Odata Windows Store App EndSaveChanges exception

I am trying to create a Windows Store App using a WebApi Odata controller. After some effort I have all the Get requests working, I am now moving onto the CRUD methods, and am getting the following Exception on the EndSaveChanges of the Data Service Context.
<?xml version="1.0" encoding="utf-8"?>
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<m:code />
<m:message xml:lang="en-US">No HTTP resource was found that matches the request URI 'http://localhost:56317/odata/ESFClients(guid'f04ad636-f896-4de4-816c-388106cd39ce')'.</m:message>
<m:innererror>
<m:message>No routing convention was found to select an action for the OData path with template '~/entityset/key'.</m:message>
<m:type></m:type>
<m:stacktrace></m:stacktrace>
</m:innererror>
</m:error>
Now I think this is a bug in WebApi from this http://aspnetwebstack.codeplex.com/workitem/822 and its hiding the actual error. To make sure it wasn't my Odata Endpoint I created a quick console app to get an entry, update it and Patch it back, which worked all ok. My WebApi Odata Controller derives from ODataController with
public HttpResponseMessage Patch([FromODataUri] Guid key, Delta<ESFClient> patch)
As the method.
In my windows application I have a extension method on the DataServiceContext for the Save Changes.
public static async Task<DataServiceResponse> SaveChangesAsync(this DataServiceContext context, SaveChangesOptions options)
{
var queryTask = Task.Factory.FromAsync<DataServiceResponse>(context.BeginSaveChanges(options, null, null),
queryAsyncResult =>
{
var results = context.EndSaveChanges(queryAsyncResult);
return results;
});
return await queryTask;
}
And calling the update like so from a blank Windows Store XAML page.
public async Task UpdateWeekNo()
{
var container = new ESFOdataService.Container(new Uri("http://localhost:56317/odata/"));
var clients = (DataServiceQuery<ESFClient>)from p in container.ESFClients where p.UserID == new Guid("f04ad636-f896-4de4-816c-388106cd39ce") select p;
var result = await clients.ExecuteAsync();
var updatedClient = result.Single();
if (updatedClient != null)
{
updatedClient.WeekNo = 19;
container.UpdateObject(updatedClient);
await container.SaveChangesAsync(SaveChangesOptions.PatchOnUpdate); // Use PATCH not MERGE.
}
}
So does anyone come across the same issue, or know how I can find out the actual error. One interesting point is that if I debug the controller while running the Windows App, the patch method does not get called.
Ok, so I have finally solved this. Just a recap for those who could experience the same issue. I have an Odata WebApi controller, Windows 8 Store Application using WCF Client Library, with the reference created from Add Service Reference. When trying to update (patch) a record an exception was being thrown at the EndSaveChanges. This is because for some reason Post Tunneling is enabled by default on my context. Setting this to false allowed everything to work.
Context.UsePostTunneling = false;
Context.IgnoreResourceNotFoundException = true;

Resources