I have 2 distincts MVC Web Applications accessed from:
1) product.main-brand.com (solution landing page)
2) admin.product.main-brand.com (solution admin landing page)
The product is going to change the location from:
product.main-brand.com to www.main-brand-com/product
And the admin has to change from:
admin.product.main-brand.com to www.main-brand-com/product/admin
I can't create a Virtual Directory for the admin because www.main-brand-com/product is a controller.
For example, NopCommerce does that, we can go from www.shop.com to www.shop.com/admin and it's changing project and not controller/action. How does he do that?
Here are some steps to achieve a similar solution like in nopCommerce 3.9
Create your primary Web Project
Foo.Web
Properties
AssemblyInfo.cs
Foo.Web.csproj
Global.asax
Global.asax.cs
...
Create your admin Web Project inside of your primary Web project
Foo.Web
Administration
Properties
AssemblyInfo.cs
Foo.Admin.csproj
...
Administration folder must be created using "Add project wizard" or using explorer. Do not create that folder using solution explorer.
Remove Global.asax from admin project
You don't need this
Add an AreaRegistration implementation to your admin project
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName => "Admin";
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute
(
name: "AdminDefault",
url: "admin/{controller}/{action}/{id}",
defaults: new {controller = "Home", action = "Index", area = "admin", id = ""},
namespaces: new[] {"Foo.Admin.Controllers"}
);
}
}
Modify Global.asax.cs to register areas
Add this to your project. Make sure it's called before your default routes.
AreaRegistration.RegisterAllAreas();
With this, all your controllers inside of Foo.Admin are found by
~/Admin/{controller}/{action} and all your controllers inside Foo.Web
are found by ~/{controller}/{action}
Since you have 2 distinct MVC web applications I see 2 possible solutions...
a) create an Admin folder inside your main web application and set it as the root of your admin web application i.e. put your whole admin website into the admin folder. I expect this will require some tweaking of web.config of both apps so they can coexist.
b) leave each web application in it's own IIS virtual Application then add rewrite rules in the main web application for the /admin path to the true IIS path and you may need some rewrite rules in the admin app back to the main app if there is expected to be a navigation path to it.
I would recommend that you do look into attribute routing.
https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/
This allows you to do this:
[Route("/product/admin")]
That attribute decorator goes on your controller method after you setup attribute routing.
Hope that helps.
This can easily be achieved in asp.net mvc application by using the feature called Area (for detail see https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/areas).
Your main application will work for www.main-brand-com. You can add an Area for Product to be referred by www.main-brand-com/product and another Area called Admin to be referred by www.main-brand-com/admin.
You can add an Area in asp.net mvc application by right clicking on web application project then selecting Add from the quick menu and then select Area. It will ask for name of Area to be created. After giving name and clicking Ok it will create an Area with that name in Areas folder in your web application project. The newly created Area will have same folder structure like main application like Controller, Model, View etc. folders. It will also create a class (AreaRegistration.cs) for registering the routing details for this Area. The content of this class may look like below code.
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
As a rule, if you're working with an externally maintained platform, you should aim to make as few code changes as possible. You will save yourself the work of merging, testing and deploying your code changes when there's an update. This is especially important if the update is a critical one.
In this particular case, it is best to let IIS to reroute your URLs. It has no code impact and offers a major benefit. Visitors and search using deprecated urls are automatically redirected to newer ones. This is especially important for search engines. If they encounter a 404 error, they will often remove the urls and even the entire site. In other words, VocĂȘ pode perder muitas vendas!
You can reroute your urls in the IIS Manager using the Url Rewrite Module or through web.config files. I recommend web.config files since it can be uploaded and kept together with your project.
For your existing product subdomain site, add the following to the system.webServer section of the site's web.config file:
product.main-brand.com to www.main-brand-com/product
<system.webServer>
<rewrite>
<rules>
<rule name="product.main-brand.com Redirect" stopProcessing="false">
<match url="^\/?$" />
<conditions>
<add input="{HTTP_HOST}" pattern=".*product\.main-brand\.com.*" />
</conditions>
<action type="Redirect" redirectType="Found" url="http://www.main-brand-com/product/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
For your existing admin subdomain site, add the following to the system.webServer section of the site's web.config file:
admin.product.main-brand.com to www.main-brand-com/product/admin
<system.webServer>
<rewrite>
<rules>
<rule name="admin.main-brand.com Redirect" stopProcessing="false">
<match url="^\/?$" />
<conditions>
<add input="{HTTP_HOST}" pattern=".*admin\.product\.main-brand\.com.*" />
</conditions>
<action type="Redirect" redirectType="Found" url="http://www.main-brand-com/product/admin/{R:0}" />
</rule>
</rules>
</rewrite>
These addition will redirect users to the new URLs. Refer to the following article for how to setup IIS url rewrite for further information:
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/using-global-and-distributed-rewrite-rules
Changing the redirection in IIS is one part, but your application needs to understand how to route the new url scheme internally. Without your app's specific routing code, I can't be of much help. If your application, however, is using subdomain's url parameter and you want to change it, refer to the following article:
https://benjii.me/2015/02/subdomain-routing-in-asp-net-mvc/
Related
I have searched around for the answer to this but cant find anything that fits my exact scenario.
Currently have the below set up :
RootApplication(sitea.bla) .NET 3.5
- ChildApplication (sitea.bla/service1) .NET 3.5
The root application is being rewritten in .NET 4.5 but the service1 application will not be being updated in this current phase and will be removed as an child application.
I have moved the service1 application to a sub domain (service1.sitea.bla)so it can run in an legacy application pool.
This works perfectly though I have multiple other applications/services/clients that reference the original endpoint. I have set up a IIS redirect which works perfectly in the browser
sitea.bla/service1/exampleservice.asmx gets redirected to service1.sitea.bla/exampleservice.asmx
Though when making a call through a client application it fails unless I manually change the endpoint to the new sub domain . I have also tried achieving through a reverse proxy.
What is the best method to achieve this without manually changing all the endpoints to the new sub domain?
You need to setup correct rewrite rule:
1) You need to install ARR module (you need it, because you rewriting requests to different application)
2) In IIS manager you should enable reverse proxy
2.1) On server node click "Application Request Routing Cache"
2.2) Click "Server proxy settings" and click "Enable proxy", then "Apply"
3) In web.config of application sitea.bla add this rewrite rule:
<rule name="rewrite service1" stopProcessing="true">
<match url="^service1(.*)" />
<action type="Rewrite" url="http://service1.sitea.bla{R:1}" />
</rule>
4) Try to make a call to sitea.bla/service1/exampleservice.asmx
I'm new to URL Rewrite.
I created a WCF Rest service, and I'm trying to set a rewrite rule that will allow invoking the service when the svc extension is hidden.
I have a method named "Test" on that service, that I invoke successfully with the svc extension present.
What I did:
Created a rule in the web config:
Checked the Rule shows in IIS under ReWrite features.
Validated it works as I expect by clicking the "test pattern" button and entering the URL details:
Did IISReset (Several times).
I'm getting a 404 when trying this URL:
http://localhost/WcfTestApp/Service1/Test
Additional Stuff:
I also enabled "Failed Request Tracing Rules" But I see no logs created in the folder.
Any Ideas why it isn't working as I expect?
Thanks in advance for any help.
What I did to resolve it:
I fixed the failed request tracing log files not appearing, turns out you need to configure in the IIS settings the status codes for which the trace should occur, as it's not smart enough to select all by default.
Then via the trace file (which I opened in IE), I noticed my rewrite rule needed a slight modification, as I was able to see what URL I got, and what it was rewritten to (which did not work).
Eventually, that's what I used.
<rule name="RemoveSvcExtension" stopProcessing="true">
<match url="^(.*)Service1/(.*)$" />
<action type="Rewrite" url="{R:1}Service1.svc/{R:2}" logRewrittenUrl="true" />
</rule>
I am moving a website from a static website to MVC 5. I need to create controllers/actions to respond to requests with old URLs. ( and return a redirect, page moved ) If I just hardcode the old URL in attribute routing, I get
HTTP Error 404.0 - Not Found The resource you are looking for has been removed, had its name changed, or is temporarily unavailable
What is the best way of approaching this. ( what I mean is that how could I make a route for a url with .html extension, and ASP.net respond to it)
I think right now IIS sees that .html and tries to send the file to the client without going through the application. How could I remove that behavior on a shared hosting ?
the html files that are being served right now are in different folders.
example:
I need to map this URL to a controller/action:
example.com/services/Renovations.html
we will be mapping it to controller => services , and action => renovations
example.com/contactus.html
we will be mapping it to controller => contact , and action => index
Write your application using MVC Controllers/Actions as appropriate for your new architecture, then implement a set of URL Rewrite rules at the IIS level to map the old URL's to new ones. The Rewrite rules will be stored inside your web.config file which is handy for moving the configuration from Dev to Staging to Live environments.
If you give some examples of your old URL's and their new corresponding routes, I could give you some sample IIS Rewrite rules to match. This works best if your old URL's followed a pattern, e.g. /products/{skucode}.html etc
EDIT: Some sample rewrite rules to match the requested redirects.
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="Static rewrites" enabled="true" stopProcessing="true" >
<match url="^(.*?\.html)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Redirect" url="{static site rewrites:{R:1}}" appendQueryString="true" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="Static site rewrites" ignoreCase="true">
<add key="contact.html" value="contact" />
<add key="services/renovations.html" value="services/renovations" />
</rewriteMap>
</rewriteMaps>
</rewrite>
</system.webServer>
</configuration>
It should be clear how to add more keys to the rewriteMap for other pages you'd like redirected. To clarify, these are Redirects and will return HTTP 301 Moved Permanently response codes to the browser and transparently redirect it to the new route.
The title says it all. There's actually a ton of information on how to do this and I'm very close. I've read several things on google as well as the following stackoverflow posts:
How can I properly handle 404 in ASP.NET MVC?
How can I properly handle 404 in ASP.NET MVC?
Custom error pages on asp.net MVC3
http://blog.davebouwman.com/2011/04/21/custom-404-pages-for-asp-net-mvc-3/
I've got 404's working at the action level. And I'm using the *.aspx suffix on my controllers. If you have a url like
"http://blahblah/AppName/idontexist.aspx"
The custom Error controller is loaded. My issue comes down to controller's that don't have the .aspx and also do not exist. This yields the typical IIS Server 404 html page, which I don't want. Another kink in the works is that I can't really change the IIS configuration itself. I have to handle this via the code/web.config/global.asax (or some other part of the project I haven't thought of).
Here are my web.config entries (this is the root web.config, not the view one):
<httpErrors defaultPath="/Error.aspx/HttpError" errorMode="Custom" existingResponse="Replace" defaultResponseMode="ExecuteURL">
<remove statusCode="500" subStatusCode="-1" />
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="500" path="/Error.aspx/HttpError" responseMode="ExecuteURL" />
<error statusCode="404" path="/Error.aspx/NotFound" responseMode="ExecuteURL" />
</httpErrors>
<customErrors mode="On" defaultRedirect="~/Error.aspx/HttpError">
<error redirect="~/Error.aspx/NotFound" statusCode="404" />
</customErrors>
And here are my routes in global.asax:
routes.MapRoute(
"Default", // Route name
"{controller}.aspx/{action}/{id}", // URL with parameters
new { controller = "StartController", action = "StartAction", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"NotFoundController", // Route name
"{controller}.aspx", // URL with parameters
new { controller = "Error", action = "NotFound" } // Parameter defaults
);
routes.MapRoute(
"NotFoundController2", // Route name
"{controller}", // URL with parameters
new { controller = "Error", action = "NotFound" } // Parameter defaults
);
routes.MapRoute(
"Root", // Route name
"", // URL with parameters
new { controller = "StartController", action = "StartAction", id = UrlParameter.Optional } // Parameter defaults
);
I also think that one snag with using routes to catch these is that I lose the 404 status code; however, because the route points to an action specifically designed for this purpose, I suppose that point is moot.
Anyhow, any thoughts, suggestions, or criticisms would be welcomed. I'm very close here. Thanks!
EDIT 1
I've still been researching this. Is there a way I can define a custom route constraint that will redirect to the Error Controller if the text ".aspx" is not found in the url?
EDIT 2
Doesn't look like that's how constraints are intended to be used. I also tried implementing the
protected void Application_Error()
{
}
method per the implementation at http://blog.davebouwman.com/2011/04/21/custom-404-pages-for-asp-net-mvc-3/, but when I don't specify .aspx for the controller, it looks like the application never gets a chance to throw an error. It looks like that is handled by IIS before my app can even respond to it.
If I could make IIS changes, preferably to just this application's virtual directory entry, would that allow for a more viable solution to this?
If there was just somewhere I could grab the url, search for .aspx, and if it's not found throw a 404 not found, but redirect to the application level 404 page instead of the IIS default, that would be pretty close to ideal.
Thoughts?
EDIT 3
I'm of the opinion that handling this scenario is just not possible unless your application is the root site for the IIS server and not a virtual directory. I noticed that, within IIS 6.0, you can tweak the default IIS error pages. Not only that, you can replace certain cases with a URL. I've tried doing this with a virtual directory site but the default IIS 404 Not found page displays.
So it amounts to: you can handle this on IIS 6 if you have a stupid amount of control over your setup and the site you're doing this for is the root site.
Not very applicable in real world scenarios I imagine.
I don't think this is possible without being able to make changes to IIS. With IIS 6, requests don't enter the ASP.Net realm unless they are mapped to the ASP.Net ISAPI handler (aspnet_isapi.dll). For normal ASP.Net extensions, the mapping is already setup in IIS6 when .Net is installed (.ashx, .aspx, etc). This is why your 404 for a controller that doesn't exist gets the normal IIS 404 page. IIS is looking for a folder that doesn't exist on disk.
In order to get your 404 page handlers to work as expected (this is assuming you COULD make changes to IIS), you'll need to setup what is called a wilcard mapping. This sends all requests to the ASP.Net ISAPI. IIS also needs to be instructed to bypass the check for a physical file, since none will exist in this case. There's a checkbox for that option. I no longer have IIS 6 in front of me, but Option 1 on this site walks you through it:
http://blog.stevensanderson.com/2008/07/04/options-for-deploying-aspnet-mvc-to-iis-6/
I have done this before, it does work. There are some tradeoffs from sending everything to the .Net ISAPI. All static files will be handled by ASP.Net (even images) instead of IIS directly, so just be aware of the implications there.
Hope this helps
How to do it:
When you access a certain page (like a folder), you can view information specific user, for example:
www.page.com/user001
Opens the default page www.page.com/userinfo.aspx in which that user get "user001" and display certain information. And the user see www.page.com/user001
I can do this with asp.net or IIS7?
something like subdomains
You can do this by adding the URL Rewrite Module to IIS. Check this out
http://www.iis.net/learn/extensions/url-rewrite-module/using-rewrite-maps-in-url-rewrite-module
You can store the URL Rewrite rules in the web.config file. For example:
<configuration>
<system.webServer>
<rewrite>
<rules>
****(Your URL Rewrite Rules)****
</rules>
</rewrite>
</system.webServer>
</configuration>
But if it's not possible for you to store it in web.config due to security or maybe for some performance issues, then you can store the URL Rewrite Rules in IIS.
I hope it helps.
you can use routing in global.asax file at application_start event instead of rewrite the url also this will redirect every this to the profile page