Mini Profiler does not render scripts - asp.net-mvc-3

I've added Mini Profiler through NuGet and though in a really simple project works lovely, this is a big and existing project, and of course that I'm getting some problems with it :(
it writes the correct script tags in the source code as
<link rel="stylesheet" type="text/css" href="/mini-profiler-includes.css?v=1.9.0.0">
<script type="text/javascript">
if (!window.jQuery) document.write(unescape("%3Cscript src='/mini-profiler-jquery.1.6.2.js' type='text/javascript'%3E%3C/script%3E"));
if (!window.jQuery || !window.jQuery.tmpl) document.write(unescape("%3Cscript src='/mini-profiler-jquery.tmpl.beta1.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript" src="/mini-profiler-includes.js?v=1.9.0.0"></script>
<script type="text/javascript">
jQuery(function() {
MiniProfiler.init({
ids: ["e48fcf61-41b0-42e8-935a-fbb1965fc780","870a92db-89bc-4b28-a410-9064d6e578df","30881949-bfdb-4e3a-9ea5-6d4b73c28c1d","6bca31b8-69d9-48eb-b86e-032f4d75f646","df16838d-b569-47d0-93e6-259c03322394"],
path: '/',
version: '1.9.0.0',
renderPosition: 'left',
showTrivial: false,
showChildrenTime: false,
maxTracesToShow: 15
});
});
</script>
But when I try to open any file, I get a HTTP 404
I verified that there is a MiniProfiler.cs under App_Start and adding a break point there, the code runs, I even added
#region Mini Profiler
protected void Application_BeginRequest()
{
if (Request.IsLocal)
{
MiniProfiler.Start();
}
}
protected void Application_EndRequest()
{
MiniProfiler.Stop();
}
#endregion
to the global.asax file...
Is there something obviously that I'm missing?

This is a known issue with certain configurations of IIS.
The workaround is to ensure the UrlRoutingModule handles all the mini profiler includes in your web.config:
<system.webServer>
<handlers>
<add name="UrlRoutingModule1" path="mini-profiler*.js" verb="*" type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified" preCondition="integratedMode" />
<add name="UrlRoutingModule2" path="mini-profiler*.css" verb="*" type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified" preCondition="integratedMode" />
<add name="UrlRoutingModule3" path="mini-profiler*.tmpl" verb="*" type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
There are 2 open tickets on this issue at the moment:
http://code.google.com/p/mvc-mini-profiler/issues/detail?id=50
http://code.google.com/p/mvc-mini-profiler/issues/detail?id=60
In a future version, to avoid the issue, we will probably serve our includes extensionless.

Related

How to make an HTTP PUT with a param in an ionic 2 app to a WebAPI?

I am trying to make an HTTP PUT with an integer parameter to a MVC WebApi.
I tried to follow the angular 2 guidelines for HTTP PUT: https://angular.io/docs/ts/latest/guide/server-communication.html
My WebApi:
public IHttpActionResult Put([FromBody]int id)
{
return Ok();
}
My Http PUT in my service in my ionic 2 app:
makePut(){
let body = JSON.stringify({id:155320});
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return new Promise(resolve => {
this.http.put('API_URL', body, options)
.subscribe(
response => {
console.log(response.text());
},
error => {
//Failed to Login.
alert(error.text());
console.log(error.text());
});
});
}
And finally the call to my service from my home page:
this.service.makePut().then(data => {console.log(data);});
When I run this I get a 405 method not allowed. Is there anything I am missing?
UPDATE here is part of the web.config in my web api:
<system.webServer>
<security>
</security>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule" />
</modules>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
It might be Web Api error and you can resolve that by adding this code to your web.config file
<handlers accessPolicy="Read, Script">
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"
path="*."
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
modules="IsapiModule"
scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
preCondition="classicMode,runtimeVersionv4.0,bitness64"
responseBufferLimit="0" />
this article can give you more information about 405 error.
I was able to fix the problem, which turned out to be a CORS issue. You can view how to disable same origin policy in Chrome here: How to resolve CORS issue and JSONP issue in Ionic2
Once I disabled it in chrome, the HTTP PUT succeed.
Here is my final code:
makePut(){
let body = 155320; // this is different
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return new Promise(resolve => {
this.http.put('API_URL', body, options)
.subscribe(
response => {
console.log(response.text());
},
error => {
//Failed to Login.
alert(error.text());
console.log(error.text());
});
});
}

Url rewriting in ASP.NET Core RC2

How can I accomplish URL rewriting in ASP.NET Core RC2? Migrating from RC1 to RC2 broke my Angular 2 routing when I refresh the page.
I was using a rule like this before in my web.config located in my wwwroot. With RC2 I'm not even sure if I'm supposed to have a web.config in my wwwroot anymore, or if I'm just supposed to have the one in the base of my project.
This is my base web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="true" stdoutLogEnabled="true" />
</system.webServer>
</configuration>
And this is my wwwroot web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<!--Redirect selected traffic to index -->
<rule name="Index Rule" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_URI}" matchType="Pattern" pattern="^/api/" negate="true" />
<add input="{REQUEST_URI}" matchType="Pattern" pattern="^/account/" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
When I refresh an angular 2 route, I get a Status Code: 404; Not Found from ASP.NET
I found a working solution here.
Below is the code in my Configure method that fixed the issue for me.
But be careful, the declaration order matters.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
app.Use(async (context, next) => {
await next();
if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value)) {
context.Request.Path = "/";
context.Response.StatusCode = 200;
await next();
}
});
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseMvc(routes => {
routes.MapRoute("Default", "api/{controller}/{action}/{id?}");
});
}
I found solution by Steve Sanderson, seems to work.
he wrote extension to RouteBuilder.
You can configure it in Setup.cs by calling extension method MapSpaFallbackRoute
https://github.com/aspnet/JavaScriptServices
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
});
I had the exact same issue. In fact, for me, the IIS Express Server did not even start when the rewrite rule was included in the web.config file. Given this I dug around for some other way to do the same thing without relying on rewrite rules. I found that you can use the MapWhen function in your startup.cs file to send anything not handled by MVC back to index.html.
The below code has been added to the Configure method of the Startup.cs class after the app.UseMvc() call.
app.UseMvc();
// this serves "index.html" from the wwwroot folder when
// a route not containing a file extension is not handled by MVC.
app.MapWhen(context =>
{
var path = context.Request.Path.Value.ToLower();
return path.Contains(".");
},
branch =>
{
branch.Use((context, next) =>
{
context.Request.Path = new PathString("/index.html");
return next();
});
branch.UseStaticFiles();
});
So far this looks like its working but I need to do some more testing to see if there are any side effects. Personally the rewrite rule seemed a better solution but this does appear to get me past the issue.

Web.API works in some deployments but returns 404 in others

I have an ASP.NET WebForms app that is widely distributed. My new version adds Web.API and users have been playing with a beta. In most beta installations everything works fine, but for some installs all the Web.API calls return HTTP 404 Not Found errors. I can't figure out why the Web.API calls fail on some servers but works fine on others.
My guess is there is some kind of server configuration that is breaking the routing, but I can't figure out what it is. I've even RDP'd into one of these sites and can't find anything obvious.
This is an example API call:
GET http://site.com/api/events/27
The code:
namespace GalleryServerPro.Web.Api
{
public class EventsController : ApiController
{
public string Get(int id)
{
return "Event data for ID " + id;
}
}
}
The route definitions, which are called from the Init event of a custom HTTP module named GspHttpApplication:
private void RegisterRoutes(RouteCollection routes)
{
routes.MapHttpRoute(
name: "GalleryApi1",
routeTemplate: "api/{controller}"
);
routes.MapHttpRoute(
name: "GalleryApi2",
routeTemplate: "api/{controller}/{id}",
defaults: new { },
constraints: new
{
id = #"\d*",
}
);
routes.MapHttpRoute(
name: "GalleryApi3",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: new
{
},
constraints: new
{
id = #"\d*"
}
);
// Add route to support things like api/meta/galleryitems/
routes.MapHttpRoute(
name: "GalleryApi4",
routeTemplate: "api/{controller}/{action}",
defaults: new
{
},
constraints: new
{
}
);
}
The example GET above should match the route named GalleryApi2, and like I said in most installations it does.
I know WebDAV can cause trouble (405 errors), so I already remove it in web.config:
<system.webServer>
<modules>
<remove name="WebDAVModule" />
<add name="GspApp" type="GalleryServerPro.Web.HttpModule.GspHttpApplication, GalleryServerPro.Web" />
</modules>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
...
</system.webServer>
So it all comes down to figuring out why this configuration works for some web installs and not others.
Roger

Requested resource does not support http method "PUT"

I'm using AttributeRouting with my Web API (MVC 4).
Why does this work?
[AcceptVerbs("PUT")]
[PUT("api/v1/tokens/current")]
public MemoryToken UpdateToken([FromBody] DeviceTokenViewModel viewModel)
{...}
And this one does not?
[PUT("api/v1/tokens/current")]
public MemoryToken UpdateToken([FromBody] DeviceTokenViewModel viewModel)
{...}
Error message: The requested resource does not support http method "PUT".
Why do I have to explicitly accept the PUT verb?
I'm just confused because something similar with POST works just fine (I don't have to specify the accepted verbs):
[POST("api/v1/tokens")]
public MemoryToken CreateToken()
{...}
From various other posts I believe it has to do with the setting in my web.config. The web server section currently looks like this:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="AttributeRouting" path="routes.axd" verb="*" type="AttributeRouting.Web.Logging.LogRoutesHandler, AttributeRouting.Web" />
</handlers>
I tried a couple things like removing WebDav and stuff. But nothing worked so far (unless explicitly allowing the PUT verb in the annotation).
Oh, I am using Visual Studios built-in development server.
Thanks guys!
In this link they describe the POST method as being the default if none of the actions match. So that's why it still works for your CreateToken() method without an HttpPost attribute .
You can specify the HTTP method with an attribute: AcceptVerbs, HttpDelete, HttpGet, HttpHead, HttpOptions, HttpPatch, HttpPost, or HttpPut.
Otherwise, if the name of the controller method starts with "Get", "Post", "Put", "Delete", "Head", "Options", or "Patch", then by convention the action supports that HTTP method.
If none of the above, the method supports POST.

Large File Uploads Fails in Chrome with Valums

I am using the valums ajax upload component (http://valums.com/ajax-upload/). My site is going to have users uploading files that are greater than 500MB in size. I have a strict pure HTML requirement. I can successfully upload files of this size in Internet Explorer. However, when I attempt to use Chrome, the file is never written on the server, but only in the case of large files. For smaller files, the file is successfully written. But for larger files, I get an "Maximum request length exceeded error".
Considering I can upload files of this size with IE, I know that the settings in my web.config are correct. This leads me to believe there is something in the XHR implementation that needs to be set to accommodate for files of this size. However, i'm not sure what that is. Can anyone provide a sample of values use with ASP.NET MVC that:
Allows for large (>500 mb) file uploads in IE AND Chrome
Shows the progress of an uploaded file in browsers that support XHR
Thank you so MUCH!
I am unable to reproduce your issue. Here's my setup in which I limited the files to 1GB.
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Upload(string qqfile)
{
var path = Server.MapPath("~/App_Data");
var file = Path.Combine(path, qqfile);
using (var output = System.IO.File.OpenWrite(file))
{
Request.InputStream.CopyTo(output);
}
return Json(new { success = true });
}
}
Index.cshtml view:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test</title>
<link href="#Url.Content("~/Content/fileuploader.css")" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="file-uploader">
<noscript>
<p>Please enable JavaScript to use file uploader.</p>
</noscript>
</div>
<script src="#Url.Content("~/Scripts/fileuploader.js")" type="text/javascript"></script>
<script type="text/javascript">
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
action: '#Url.Action("upload")'
});
</script>
</body>
</html>
web.config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Version" value="1.0.0.0"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
<system.web>
<httpRuntime maxRequestLength="1048576" executionTimeout="3600" />
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages"/>
</namespaces>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Things to notice in web.config is <httpRuntime>:
<httpRuntime maxRequestLength="1048576" executionTimeout="3600" />
and if you are hosting this site in IIS7+ (<requestLimits>) as well is required:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>
With this setup I am able to upload files up to 1GB of size in the latest versions of FireFox 8.0, IE9 and Chrome 16.
I have hosted the site locally using IIS Express.

Resources