rewrite URl from www.m.example.com to m.example.com - url-rewriting

I am trying to do a redirect in ASP.NET web.config which contains like www.m.example.com to m.example.com; I have tried different approaches but wasn't able to do it.

Instead of the web.config, you could apply the following to your page:
<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location","http://www.new-location.com");
}
</script>
Read more here
If you do still want to use the web.config file, you can do the following:
Open web.config in the directory where the old pages reside
Then add code for the old location path and new destination as follows:
<configuration>
<location path="services.htm">
<system.webServer>
<httpRedirect enabled="true" destination="http://domain.com/services" httpResponseStatus="Permanent" />
</system.webServer>
</location>
<location path="products.htm">
<system.webServer>
<httpRedirect enabled="true" destination="http://domain.com/products" httpResponseStatus="Permanent" />
</system.webServer>
</location>
</configuration>

Related

Sitecore AJAX POST: Could not invoke action method

We have developed a site with multiple controllers that accept GET and POST and return views and JSON, and everything works fine in our Development environment.
But on the client's acceptance server we have an issue: all the GETs return well their results, but the POSTs return an error described here by John West. The Stacktrace is identical.
System.InvalidOperationException: Could not invoke action method: askquestion. Controller name: Assistance. Controller type: [Namespace].Assistance.Controllers.AssistanceController
We use the approach of defining the route for each controller:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<initialize>
<processor type="[Namespace].Assistance.Pipelines.RegisterWebApiRoutes, [Namespace].Assistance"
patch:before="processor[#type='Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc']" />
</initialize>
</pipelines>
</sitecore>
</configuration>
The processor is like this:
public class RegisterWebApiRoutes
{
public void Process(PipelineArgs args)
{
RouteTable.Routes.MapRoute(
name: "Assistance.Api",
url: "api/assistance/{action}",
defaults:new {controller = "Assistance" });
}
}
The action method is like this
[HttpPost]
public ActionResult AskQuestion(AskQuestionViewModel model)
{
if (ModelState.IsValid)
{
....
return View("Confirmation");
}
else
{
return View(model);
}
}
What is happening? Somehow Sitecore blocks AJAX POST requests. Definitely, this is the configuration issue. Where should I look?
OK, I have found the source of the issue.
They had URL Rewrite Module with one rule: LowerCaseRule1 (or it may be any other). But when it made it's work, the request turned to GET. Then the controller could not find the corresponding GET action and voila: could not invoke the action method.
I simply added the exception in rewrite rules and it worked.
<rewrite>
<rules>
<rule name="LowerCaseRule1" stopProcessing="true">
<match url="[A-Z]" ignoreCase="false" />
<action type="Redirect" redirectType="Permanent" url="{ToLower:{URL}}" />
<conditions>
<add input="{URL}" pattern="^.*\.(axd|ashx|asmx|lic|ico|swf|less|aspx|ascx|css|js|jpg|jpeg|png|gif)$" negate="true" ignoreCase="true" />
<!-- here is my exception -->
<add input="{URL}" pattern="/api/assistance" negate="true" />
</conditions>
</rule>
</rules>
</rewrite>

Passing DateTimeOffset to WebAPI

My WebAPI method looks like this:
[Route("api/v1.0/Profile/Test/{offset}")]
public async Task<ServiceResult> GetTest(DateTimeOffset offset)
{
...
}
Calling it like this works:
http://localhost:54295/api/v1.0/Profile/Test/2016-04-05T13:30:44-11:00
However, this call won't work:
http://localhost:54295/api/v1.0/Profile/Test/2016-04-05T13:30:44+11:00
What's the trick here?
In my Web.config in the system.web section I have this entry:
<httpRuntime targetFramework="4.5" requestPathInvalidCharacters="<,>,%,&,*,\,?" />
I found a solution:
In my web.config in the system.webServer section I added this block:
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
Now the plus sign works as desired.

Downloading file with webapi

I'm trying to write an action in a webapi controllers to allow downloading a file.
But for some strange reason, the code doesn't works.
Here is my code:
<RoutePrefix("api/files")>
Public Class PermitFilesController
Inherits ApiController
<Route("download")>
public function GetFile() As HttpResponseMessage
Dim fStream as FileStream = File.Open("C:\Projects\1234.pdf", FileMode.Open, FileAccess.Read )
Dim response = Request.CreateResponse(HttpStatusCode.OK)
response.Content = new StreamContent(fStream)
'response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
'response.Content.Headers.ContentDisposition.FileName = Path.GetFileName(fStream.Name)
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf")
return response
End Function
I try to download simply using the url in browser:
localhost:<myport>/api/files/download
The error (in Chrome ) is Error code: ERR_CONNECTION_RESET
In FF, it is even stranger: it redirects me to www.localhost.com:/... with the same error - connection reset by host
I put a breakpoint in my code, and I noticed the code gets called twice (as soon as I exit from trace from last line, it gets called again to the first line).
I have several other actions in this controller, and they all work ok.
Anyone having any idea what am I doing wrong?
EDIT
I started Fiddler, and now my browser shown this error:
[Fiddler] ReadResponse() failed: The server did not return a response
for this request. Server returned 0 bytes.
EDIT
I want to mention that webapi is integrated into a legacy classic asp.net application
The initialization code is as follows:
In global.asax.Application_Start
WebApiHelper.Initialize
....
....
Public Class WebApiHelper
Public Shared Sub Initialize()
GlobalConfiguration.Configuration.MessageHandlers.Add(New BasicAuthMessageHandler() With { _
.PrincipalProvider = New MPNAuthProvider() _
})
AreaRegistration.RegisterAllAreas()
WebApiConfig.Register(GlobalConfiguration.Configuration)
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters)
RouteConfig.RegisterRoutes(RouteTable.Routes)
GlobalConfiguration.Configuration.EnsureInitialized()
End Sub
....
MPNAuthProvider is used to ensure authenticated access to some webapi controllers
Public Class MPNAuthProvider
Implements IProviderPrincipal
Public Function CreatePrincipal(username As String, password As String) As IPrincipal Implements IProviderPrincipal.CreatePrincipal
Dim userID As Integer = 0
If Not UserData.ValidateUser(username, password, userID) Then Return Nothing
Dim identity = New GenericIdentity(userID)
Dim principal = New GenericPrincipal(identity, {"User"})
Return principal
End Function
End Class
Anything else I should check to see what happens?
Thank you
Initial Solution
After suggestion from Julien Jacobs, I tested my code into a separate, stand alone webapi project, and indeed the code proved to be correct.
So I started to investigate the web.config.
And I found the following settings that I had to comment out:
<system.web>
....
<httpModules>
<add name="RadUploadModule" type="Telerik.Web.UI.RadUploadHttpModule" />
<add name="RadCompression" type="Telerik.Web.UI.RadCompression" />
</httpModules>
and
<modules runAllManagedModulesForAllRequests="true">
<remove name="RadUploadModule" />
<remove name="RadCompression" />
<add name="RadUploadModule" type="Telerik.Web.UI.RadUploadHttpModule" preCondition="integratedMode" />
<add name="RadCompression" type="Telerik.Web.UI.RadCompression" preCondition="integratedMode" />
</modules>
After I commented them, the code started to work ok.
But this proved to not be the ideal solution, so please read on...
Updated solution
After more tests with the application, I realized that RadCompression, while not absolutely required, is very useful to web applications with Telerik Ajax, because it provides transparent, on the fly compression for all ajax traffic (plus viewstate, is configured).
Because I disabled it, the application started to be slower.
So I had to find a way to re-enable RadCompression, but disable it for certain requests (like webapi endpoint for files download).
And the solution is:
Add special config section for RadCompression configuration
<configSections>
<sectionGroup name="telerik.web.ui">
<section name="radCompression" type="Telerik.Web.UI.RadCompressionConfigurationSection, Telerik.Web.UI, PublicKeyToken=121fae78165ba3d4" allowDefinition="MachineToApplication" requirePermission="false"/>
</sectionGroup>
....
</configSections>
Add handlers in system.web\httpModules
<system.web>
....
<httpModules>
<add name="RadCompression" type="Telerik.Web.UI.RadCompression" />
</httpModules>
Add handlers in system.webServer\modules
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<add name="RadCompression" type="Telerik.Web.UI.RadCompression" preCondition="managedHandler" />
</modules>
</system.webServer>
And the critical part, to disable RadCompression for specific requests (URIs), add a new config section as below
<telerik.web.ui>
<radCompression enablePostbackCompression="true">
<excludeHandlers>
<!--This will match every api/permitfiles/download file regardless of its location in the web site--> <add handlerPath="api/permitfiles/download" matchExact="false"/>
</excludeHandlers>
</radCompression>
</telerik.web.ui>
With those changes, RadCompression is empowered globally in the app for all requests, but restricted for specific requests (like webapi files download)

MVC3 Custom Error Pages work in dev, not on server

I am using the solution detailed in this SO Question. I've used this on other sites before and its worked fine, and it works on my dev box. However, when I publish to a our Windows VPS, errors return the standard IIS error page.
I have never administered a web server before, and I am not sure what settings I need to check to figure out why its not returning the custom errors I have set up. I have tried setting .net error pages for the app to off and on, with the default page set to the root site, as well as just '/'.
I have also tried setting the error pages (under iis in 7.5) to custom and detailed.
None of these seem to have any effect on the error page that is returned. What am I doing wrong here?
I remember having similar problem and I added this line to the code
protected void Application_Error()
{
var exc = Server.GetLastError();
var httpExc = exc as HttpException;
Response.Clear();
Server.ClearError();
var routeData = new RouteData();
routeData.Values["controller"] = "Error";
routeData.Values["action"] = "General";
routeData.Values["exception"] = exc;
Response.StatusCode = 500;
if (httpExc != null)
{
Response.StatusCode = httpExc.GetHttpCode();
routeData.Values["action"] = "Http404";
routeData.Values["exception"] = httpExc;
}
Response.TrySkipIisCustomErrors = true; //this fixed it
IController errorsController = new WWS_Website.Controllers.ErrorController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
You can replace the standard IIS error pages by using the httpErrors section in the system.webServer section in your web.config file. This is in addition to the customErrors section in system.web.
<system.webServer>
...
<httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
<remove statusCode="400" subStatusCode="-1" />
<error statusCode="400" prefixLanguageFilePath=""
path="/errors/400" responseMode="ExecuteURL" />
<remove statusCode="404" subStatusCode="13" />
<error statusCode="404" subStatusCode="13" prefixLanguageFilePath=""
path="/errors/file-upload-too-large" responseMode="Redirect" />
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath=""
path="/errors/404" responseMode="ExecuteURL" />
<remove statusCode="403" subStatusCode="-1" />
<error statusCode="403" prefixLanguageFilePath=""
path="/errors/403" responseMode="ExecuteURL" />
</httpErrors>

asp.net mvc 3 and elmah.axd - yet another 404

Hi all I know that this has been posted as a prior question several times, but I've gone through each question and their proposed solutions and I'm still not able to surmount my 404 issue. I'm running Elmah 1.1 32-bit. I've referred to ASP.NET MVC - Elmah not working and returning 404 page for elmah.axd but I haven't had any luck after applying the suggestions.
I'm running ASP.NET MVC 3. Here's my web.config:
...
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
...
<errorLog type="Elmah.SqlErrorLog, Elmah"
connectionStringName="dbconn" />
<errorFilter>
<test>
<jscript>
<expression>
<![CDATA[
// #assembly mscorlib
// #assembly System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// #import System.IO
// #import System.Web
HttpStatusCode == 404
|| BaseException instanceof FileNotFoundException
|| BaseException instanceof HttpRequestValidationException
/* Using RegExp below (see http://msdn.microsoft.com/en-us/library/h6e2eb7w.aspx) */
|| Context.Request.UserAgent.match(/crawler/i)
|| Context.Request.ServerVariables['REMOTE_ADDR'] == '127.0.0.1' // IPv4 only
]]>
</expression>
</jscript>
</test>
</errorFilter>
I have my .axd routes ignored using:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
I'm running the site on IIS7, 32 bit mode enabled. I've tried many different configuration options but all to no avail. Any ideas?
Thanks
Shan
My bad. My .axd ignore route rule was ordered after the default route mapping. The default route mapping rule was matching the URL elmah.axd. I guess I didn't realize that the ignore rules had to be listed above this route. Thanks everyone for your help!
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
} // Parameter defaults
);
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
Simply moving routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); before the Default route mapping resolved this issue.
Copy the .dll to your bin and reference... add the elmah defaults to configSections
Don't put the handler inside the system.webServer as mentioned above, try system.web section like this instead in your web.config.
<system.web>
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
</system.web>
just leave your global.asax as default:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
browse to the axd locally
then if working, lock it down with the config section Gedas mentioned above.
Have you tried this?
<configuration>
<system.webServer>
<handlers>
<add name="elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</handlers>
</system.webServer>
</configuration>
also make sure to secure elmah.axd location from regular users:
<location path="elmah.axd">
<system.web>
<authorization>
<allow roles="Admin" />
<deny users="*" />
</authorization>
</system.web>
</location>
I was getting a 404 error due to the SQLServer Compact database being over the default max file size. Just deleted the SDF data file and 404 went away.
In asp.net mvc 3 global.asax.cs file
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute());
}
HandleErrorAttribute will swallow all exceptions, leaving nothing for ELMAH to handle.
See Joe's blog http://joel.net/wordpress/index.php/2011/02/logging-errors-with-elmah-in-asp-net-mvc3-part1/

Resources