PhoneGap (Build) & SignalR, works everywhere except when actually installed on device with vague error - asp.net

I have created a SignalR server, a web client, and a mobile application built with PhoneGap Build. When I launch the PhoneGap application with lite-server, PhoneGap CLI, or the PhoneGap Desktop Application the SignalR works flawlessly between the web client and the PhoneGap application. This includes using the PhoneGap mobile application to connect to the PhoneGap Desktop application. The only time it fails is when I build it with PhoneGap Build and install the APK on the device. I have no explanation for this error.
I have handled CORS through the WEB.CONFIG of the server. It is a plain ASP.NET application that just has an OWIN startup file to configure SignalR and a Hub class.
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE, TOKEN" />
<add name="Access-Control-Allow-Credentials" value="false"/>
</customHeaders>
</httpProtocol>
</system.webServer>
The frustrating part is that the error that is produced when $.connection.hub.start fails is just "Error: Error during negotiation request"
When 'deviceready' event triggers I call initiateSignalR()
var appConfig = {
'serverUrl': "http://wolf-signalrserver.azurewebsites.net"
}
var initiateSignalR = function(){
if ($.signalR) {
}
var username = prompt("username");
var success = `
<div class ="serverMessage">
<span>--- WELCOME, ${username} ---</span>
</div>
`
$('#chatbox').append(success)
$.connection.hub.logging = true
$.connection.hub.qs = { 'username': username }
$.connection.hub.url = appConfig.serverUrl + "/signalr";
var chatHub = $.connection.chatHub
chatHub.client.broadcastMessage = function (name, message) {
console.log("Data Incoming ---- Name: " + name + " Message: " + message);
var message = `
<div class="row">
<span class="col-sm-2">${name}:</span>
<span class="col-sm-9"> ${message}</span>
</div>
`
$('#chatbox').append(message)
}
$('#messageButton').on('click', function () {
chatHub.server.send(username, $('#messageBox').val())
})
$('#messageForm').on('submit', function (e) {
e.preventDefault();
chatHub.server.send(username, $('#messageBox').val())
})
$.connection.hub.start({ withCredentials: false, jsonp: true })
.done(function () {
console.log("Connected successfully to SignalR");
var success = `
<div class ="serverMessage">
<span>--- Successfully connected to the server ---</span>
</div>
`
$('#chatbox').append(success)
})
.fail(function (err) {
console.log("Unable to connect to SignalR")
alert(err);
})
}
I have a git repo of this here: https://github.com/PhilWolf91/SignalR
I realize there are tons of questions here with this, but none of them have a detailed answer to how they fixed it.
Ex: SignalR .Net Client fails with 500 server error on device, on simulator works fine

OK. I'm a giant idiot. When I was cleaning up the Config.Xml I removed the network permission AND the default White List plugin.
<feature name="http://api.phonegap.com/1.0/network" />
<gap:plugin name="cordova-plugin-whitelist" source="npm" />
Full functional config for this project
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.wolf.signalrphonegap" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
<name>SignalRPhoneGap</name>
<description>
Hello World sample application that responds to the deviceready event.
</description>
<author email="phillip.wolf91#gmail.com" href="http://phillipwolf91.wordpress.com">
Wolf Software
</author>
<feature name="http://api.phonegap.com/1.0/network" />
<gap:plugin name="cordova-plugin-whitelist" source="npm" />
<content src="index.html" />
<preference name="DisallowOverscroll" value="true" />
<preference name="android-minSdkVersion" value="14" />
<platform name="android">
</platform>
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
</widget>
I now have SignalR working between the Server, Web Client, and PhoneGap app installed on the device

Related

Navigate to another Page Ionic on IOS

I have a Ionic Button, which register the User via Google Authentication and Firebase.
<ion-buttons end>
<a href="#" (click)="GoogleAuth()" target="_blank">
<img src="../../assets/signInButton.png">
</a>
</ion-buttons>
The Function is this:
async GoogleAuth() {
try {
const provider = new GoogleAuthProvider();
await this.afAuth.signInWithRedirect(provider);
} catch (error) {
console.log(error);
}
On Web everything works fine.
When I build the App for IOS it canĀ“t be open.
Therefore I installed the Package '<universal-links>'. When installed it the Error Message was at first :
<universal-links> tag is not set in the config.xml. Universal Links plugin is not going to work.
So I edited my config File in my xcode Project:
<widget id="de.markb.drinktogether" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>DrinkTogether</name>
<description>An awesome Ionic/Cordova app.</description>
<author email="hi#ionicframework.com" href="http://ionicframework.com/">Ionic Framework Team</author>
<content src="index.html" />
<universal-links>
<host name="https://drink-together-3d735.firebaseapp.com">
<path url="/__/auth/handler/*" />
</host>
</universal-links>
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<preference name="ScrollEnabled" value="false" />
<preference name="BackupWebStorage" value="none" />
<preference name="SplashMaintainAspectRatio" value="true" />
After editing it and buidling the App again I get this Error:
IOS project Code Sign Entitlements now set to: DrinkTogether/Resources/DrinkTogether.entitlements
Entitlements file is not in references section, adding it
Error: ENOENT: no such file or directory, open '/Users/markbaumann/Desktop/drink-together/ul_web_hooks/ios/https:/drink-together-3d735.firebaseapp.com#apple-app-site-association'
at Object.openSync (node:fs:600:3)
at Object.writeFileSync (node:fs:2221:35)
at saveContentToFile (/Users/markbaumann/Desktop/drink-together/plugins/cordova-universal-links-plugin/hooks/lib/ios/appleAppSiteAssociationFile.js:118:8)
at /Users/markbaumann/Desktop/drink-together/plugins/cordova-universal-links-plugin/hooks/lib/ios/appleAppSiteAssociationFile.js:72:5
at Array.forEach (<anonymous>)
at createNewAssociationFiles (/Users/markbaumann/Desktop/drink-together/plugins/cordova-universal-links-plugin/hooks/lib/ios/appleAppSiteAssociationFile.js:70:27)
at Object.generate (/Users/markbaumann/Desktop/drink-together/plugins/cordova-universal-links-plugin/hooks/lib/ios/appleAppSiteAssociationFile.js:45:3)
at activateUniversalLinksInIos (/Users/markbaumann/Desktop/drink-together/plugins/cordova-universal-links-plugin/hooks/afterPrepareHook.js:85:29)
at /Users/markbaumann/Desktop/drink-together/plugins/cordova-universal-links-plugin/hooks/afterPrepareHook.js:50:11
at Array.forEach (<anonymous>) {
errno: -2,
syscall: 'open',
code: 'ENOENT',
path: '/Users/markbaumann/Desktop/drink-together/ul_web_hooks/ios/https:/drink-together-3d735.firebaseapp.com#apple-app-site-association'
}
How can I open a external Link in IOS, that my users can register in my App via Google?
I expected it would open the default browser

Configuring Graylog on Web.Config class

I want to configure Graylog in web.Config file but for some reason, logs are not being sent. (configuring on JSON is not an option):
<add key="serilog:using:Graylog" value="Serilog.Sinks.Graylog" />
<add key="serilog:write-to:Graylog.hostnameOrAdress" value="URL" />
<add key="serilog:write-to:Graylog.port" value="12201" />
<add key="serilog:write-to:Graylog.transportType" value="Http" />
But I checked and I am able to send logs to Graylog if i configure it in my Serilog Init class
var logger = new LoggerConfiguration()
.ReadFrom.AppSettings().WriteTo.Graylog(new GraylogSinkOptions
{
HostnameOrAddress = "URL",
Port = 12201,
TransportType = TransportType.Http
})
.CreateLogger();
What could be the problem?
Just found out my mistake. Made a typo: instead of address I wrote adress :)
wrong:
<add key="serilog:write-to:Graylog.hostnameOrAdress" value="URL" />
should be:
<add key="serilog:write-to:Graylog.hostnameOrAddress" value="URL" />

How to keep Azure AD sign-on parameters with ASP.NET subdomains

I'm implementing, to an existing ASP.NET web application, the authentication via Azure AD and OpenIdConnect. All the packages version are listed at the end of the question
The application correctly contacts the Microsoft login service and the id_token is returned in the HTTP response, but when I try to access it inside the code with the Request structure, it appears to be Nothing.
(In the image below, Request.Url is the action url used within the Microsoft service returned form)
Going by exclusion in all the steps that the application performs, I think that the problem could be found in the URL structure generated by ASP.NET, in my case is http://localhost:50725/CONNECTION_ID/HomePage.aspx, where the CONNECTION_ID field is dynamic and reassigned for each connection.
Analyzing the HTTP packets, in fact, I find as a response to the sending of the token by Microsoft a "redirect" to the address linked to the user's connection, which, when loaded, loses the data related to authentication
<html>
<head>
<title>Object moved</title>
</head>
<body>
<h2>Object moved to here.</h2>
</body>
</html>
Based on other guides/answers and the Azure Application Registration form, I could not use any wildcards to define the return url for the authentication process.
How can I keep track of the authentication parameters to fully authenticate the user in my application?
EDIT
Debugging even more the code-flow I've found another issue, basically the Azure login procedure response triggers the Session_start event inside the Global.asax, therefore is creates a new Session.
The situation that I'm observing is the following:
The user opens the web application and tries the "Microsoft Login" option
The request is made to the login service
The id_token is passed via HTTP POST request back to the application, this triggers the Application_BeginRequest event inside the Global.asax
The request then triggers the Session_start event also from the Global.asax creating a new session and a new "base Url" for the current connection, therefore loosing track of the original session who called the authentication method and the id_token previously received
So, the real problem seems to be to keep the current session active and reload it with the authentication parameter provided by Microsoft
PACKAGES VERSION
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.Cors" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Cors" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.IdentityModel.Logging" version="5.3.0" targetFramework="net45" />
<package id="Microsoft.IdentityModel.Protocols" version="5.3.0" targetFramework="net45" />
<package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.3.0" targetFramework="net45" />
<package id="Microsoft.IdentityModel.Tokens" version="5.3.0" targetFramework="net45" />
<package id="Microsoft.Owin" version="4.2.0" targetFramework="net45" />
<package id="Microsoft.Owin.Cors" version="4.2.0" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="4.2.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="4.2.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security.Cookies" version="4.2.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security.OpenIdConnect" version="4.2.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="System.IdentityModel.Tokens.Jwt" version="5.3.0" targetFramework="net45" />
</packages>
We have tried the same in our environment and it works fine.
To Authenticate Azure AD(Microsoft Identity) in asp.net application we need to provide app registration details in our appsettings.json in below format.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "microsoft.onmicrosoft.com",
"TenantId": "xxxxxxxxxxxxxxxxxxb47",
"ClientId": "xxxxxxxxxxxxxxxxxx02",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath": "/signout-callback-oidc"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
You need to add following Required packages , In my case .csproj as below:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>aspnet-WebApplication11-xxxx027-0xx2-xxA-xxD-D39xxx</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.1" NoWarn="NU1605" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.1" NoWarn="NU1605" />
<PackageReference Include="Microsoft.Identity.Web" Version="1.16.0" />
<PackageReference Include="Microsoft.Identity.Web.UI" Version="1.16.0" />
</ItemGroup>
</Project>
Here is my program.cs file
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
builder.Services.AddRazorPages()
.AddMicrosoftIdentityUI();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
app.MapControllers();
app.Run();
Add AUTHORIZE attribute in homecontroller.cs as below:
SAMPLE OUTPUT FOR REFERNCE:-
signin:
Successfully signout:
For more information please refer this MICROSOFT DOCUMENTATION: Add sign-in to Microsoft to an ASP.NET web app

Internal endpoint for WCF service dont work on Azure Web role

I have two web roles and one of them runs the service layer consisting of 3 WCF services connected with net.tcp, each deployed as a website on port 808, 810, and 811.
Now I want the service layer to only be open to my other web role.
So I tried to make one of the services endpoint internal and to give access for my front web role.
Like this:
<ServiceDefinition name="MagnusAzureCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
<WebRole name="Core.Services" vmsize="Small">
<Runtime executionContext="elevated" />
<Startup>
<Task commandLine="Startup/startup.cmd" executionContext="elevated" taskType="background" />
</Startup>
<Sites>
<Site name="Core" physicalDirectory="C:\CoreServices">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
</Bindings>
</Site>
<Site name="Store" physicalDirectory="C:\StoreServices">
<Bindings>
<Binding name="Endpoint3" endpointName="Endpoint3" />
</Bindings>
</Site>
<Site name="Users" physicalDirectory="C:\UserServices">
<Bindings>
<Binding name="Endpoint4" endpointName="Endpoint4" />
</Bindings>
</Site>
</Sites>
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
</ConfigurationSettings>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="8282" />
<InputEndpoint name="Endpoint3" protocol="http" port="81" />
<InputEndpoint name="Endpoint4" protocol="http" port="8181" />
<InputEndpoint name="Endpoint2" protocol="tcp" port="808" localPort="808" />
<InputEndpoint name="Endpoint5" protocol="tcp" port="810" localPort="810" />
<InternalEndpoint name="Endpoint6" protocol="tcp" port="811" />
</Endpoints>
<Certificates>
</Certificates>
<Imports>
<Import moduleName="RemoteAccess" />
<Import moduleName="RemoteForwarder" />
</Imports>
</WebRole>
<WebRole name="UIWeb" vmsize="Small">
<Runtime executionContext="elevated" />
<Startup>
<Task commandLine="Startup/startup.cmd" executionContext="elevated" taskType="background" />
</Startup>
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
</Bindings>
</Site>
</Sites>
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
</ConfigurationSettings>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
</Endpoints>
<Imports>
<Import moduleName="RemoteAccess" />
</Imports>
</WebRole>
<NetworkTrafficRules>
<OnlyAllowTrafficTo>
<Destinations>
<RoleEndpoint endpointName="Endpoint6" roleName="Core.Services" />
</Destinations>
<WhenSource matches="AnyRule">
<FromRole roleName="UIWeb"/>
</WhenSource>
</OnlyAllowTrafficTo>
</NetworkTrafficRules>
</ServiceDefinition>
But when the UserService is attempted it seems to time out.
Server Error in '/' Application.
Connecting to via
net.tcp://myservicename.cloudapp.net:811/UserTypeService.svc timed out
after 00:00:00. Connection attempts were made to 0 of 1 available
addresses (). Check the RemoteAddress of your channel and verify that
the DNS records for this endpoint correspond to valid IP Addresses.
The time allotted to this operation may have been a portion of a
longer timeout.
I have also tried to set <AllowAllTraffic/> instead of <WhenSource ...> but that has no effect.
Second attempt:
After some feedback I have tried some variations to set a FixedPort and PortRange to 811 and the role listening to port="*".
<InternalEndpoint name="Endpoint6" protocol="tcp" port="*" >
<FixedPortRange min="811" max="811"></FixedPortRange>
</InternalEndpoint>
I have kept the NetworkTrafficRules as in previous attempts.
I also added the following code to make sure there is a listener for a dynamic port. In my WebRole.cs file:
public class WebRole : RoleEntryPoint
{
/// <summary>
///
/// </summary>
/// <returns></returns>
public override bool OnStart()
{
Trace.TraceInformation("OnStart method called. Updating information on IIS.");
try
{
// Initialize method-wide variables
var epName = "Endpoint6";
var roleInstance = RoleEnvironment.CurrentRoleInstance;
// Identify direct communication port
var myPublicEp = roleInstance.InstanceEndpoints[epName].PublicIPEndpoint;
Trace.TraceInformation("IP:{0}, Port:{1}", myPublicEp.Address, myPublicEp.Port);
// Identify public endpoint
var myInternalEp = roleInstance.InstanceEndpoints[epName].IPEndpoint;
// Create socket listener
var listener = new Socket(
myInternalEp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
// Bind socket listener to internal endpoint and listen
listener.Bind(myInternalEp);
listener.Listen(10);
Trace.TraceInformation("Listening on IP:{0},Port: {1}",
myInternalEp.Address, myInternalEp.Port);
while (true)
{
// Block the thread and wait for a client request
Socket handler = listener.Accept();
Trace.TraceInformation("Client request received.");
// Define body of socket handler
var handlerThread = new Thread(
new ParameterizedThreadStart(h =>
{
var socket = h as Socket;
Trace.TraceInformation("Local:{0} Remote{1}",
socket.LocalEndPoint, socket.RemoteEndPoint);
// Shut down and close socket
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
));
// Start socket handler on new thread
handlerThread.Start(handler);
}
}
catch (Exception e)
{
Trace.TraceError("Caught exception in run. Details: {0}", e);
}
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
return base.OnStart();
}
}
Another note is that the calling service uses port 811 to find the right service since the service runs three different WCF project sites. And the service I'm calling also uses a specified port number which I think can be a problem if it all of a sudden should be dynamic. The calling service looks like this:
<endpoint address="net.tcp://myservicename.cloudapp.net:811/UserTypeService.svc"
behaviorConfiguration="ClientContextEndpointBehavior" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_FrameworkService" contract="Users.Services.IPersonTypeService"
name="Tcp">
<identity>
<dns value="The Certificate Name" />
</identity>
</endpoint>
And on the receiving(Internal) WebRole sites I have the following types of configurations.
<service name="Core.Services.Logging.LoggingService" behaviorConfiguration="coreServiceBehavior">
<endpoint address="net.tcp://localhost:808/LoggingService.svc"
behaviorConfiguration="ContextEndpointBehavior"
binding="netTcpBinding"
bindingConfiguration="NetTcpBinding1"
contract="Core.Logging.ILoggingService">
<identity>
<dns value="The Certificate Name" />
</identity>
</endpoint>
And the other WCF site on port 811:
<service name="Users.Services.PersonTypeService">
<endpoint address="net.tcp://localhost:811/UserTypeService.svc" binding="netTcpBinding" bindingConfiguration="NetTcpServiceBinding1" behaviorConfiguration="ServerContextEndpointBehavior" contract="Users.Services.IUserTypeService">
<identity>
<dns value="The Certificate Name" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" kind="mexEndpoint">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
You could use the internal endpoint IP-addresses and instead of the external address. Here is an example:
foreach (RoleInstance roleInst in RoleEnvironment.CurrentRoleInstance.Role.Instances)
{
// Skip local role instance
if (RoleEnvironment.CurrentRoleInstance.Id == roleInst.Id) continue;
if (roleInst.Role.Name == "My Cool Role")
{
foreach (RoleInstanceEndpoint roleInstEndpoint in roleInst.InstanceEndpoints.Values)
{
// Get endpoint address using the internal endpoint's IP address
if (roleInstEndpoint.Protocol == "tcp")
SendRequest(roleInstEndpoint.IPEndpoint.Address.ToString(), command);
}
}
}

Hosting jQuery Mobile app using Web API

I've put together a very basic tutorial for a jQuery Mobile app with a very basic tutorial using the Web Api with VS 2013 and VB.NET. The Web Api is just for use with my UI within my app as a way to bridge between html and asp.net. It works perfectly on my development machine but the Web Api part fails when I move it to my hosting service (WinHost). I assume that there is a web.config entry that will fix this - but, I'm totally lost on this point. The html/jQuery code is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="css/custom.css" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-mobile/1.3.2/jquery.mobile.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css" />
<title>Boilerplate</title>
<script>
var uri = 'api/class1s';
function formatItem(item) {
return item.field1;
}
function find() {
var id = $('#prodId').val();
$.getJSON(uri + '/' + id)
.done(function (data) {
$('#product').text(formatItem(data));
})
.fail(function (jqXHR, textStatus, err) {
$('#product').text('Error: ' + err);
});
}
</script>
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>Boilerplate</h1>
</div>
<div data-role="content">
<p>Page Body content</p>
<div>
<input type="text" id="prodId" size="5" />
<input type="button" value="Search" onclick="find();" />
<p id="product" />
</div>
</div>
<div data-role="footer">
<h4>Footer content</h4>
</div>
View Full Site
</div>
</body>
</html>
The web.config is:
<configuration>
<appSettings></appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
</system.web>
<system.webServer>
<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>
</system.webServer>
</configuration>
There is also a WebApiConfig:
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web.Http
Public Module WebApiConfig
Public Sub Register(ByVal config As HttpConfiguration)
' Web API configuration and services
' Web API routes
config.MapHttpAttributeRoutes()
config.Routes.MapHttpRoute(
name:="DefaultApi",
routeTemplate:="api/{controller}/{id}",
defaults:=New With {.id = RouteParameter.Optional}
)
End Sub
End Module
There is also a class to define the data and a controller to populate data and return data via the Web Api.
These should not affect this problem (and work perfectly on my desktop PC).
Otherwise, this is just a standard VS2013 ASP.Net 4.5.1 project using an empty website with the Web Api option selected.
Is there a way to get this program to work on the hosting service?

Resources