Deployed mvc app not including sitename in href links - asp.net-mvc

I have an asp.net MVC web app using Kendo UI Grids with client templates. The client template specifies an href as follows:
.ClientTemplate("<a href='[controller]/[action]/[parameters]' />")
In a debug run, the link is correctly generated as follows:
http://localhost:[port]/[Controller]/[Action]?[parameters]
works beautifully.
However, in a deployed environment, the link generated is as follows:
http://[server]/[Controller]/[Action]?[parameters]
And that fails because it is missing the website name. So what I need is for it to generate the links as follows:
http://[server]/[WebSite]/[Controller]/[Action]?[parameters]
How do I need to specify my href links for this to work?

Don't hand-code your url's instead of use the UrlHelper which will take care of including the virtual directory into your urls:
.ClientTemplates(string.Format("<a href='{0}' />",
Url.Action("action", "contoller", new { param1, param2})))
If you want to use the client template value in the url you have to build the url dynamically because the Kendo UI template syntax won't inside the route value:
columns.Bound(m => m.Id)
.ClientTemplate(string.Format("<a href='{0}&Id=#= Id #'>Click me<a>",
Url.Action("action", "contoller", new { someNotTemplatedParam })));

Related

IIS deployment Issue - my web app fails when clicking a function link. I get 'This localhost page can't be found'

I have on my development machine (Windows 10 Pro) and the IIS Web Server installed.
I used VS 2017 to develop a .NET web application. It works fine when it is run in VS. The menu links find their correct action methods. It performs as expected.
I have a problem in IIS whereby I have published the .NET (.NET framework 4.8) web application.
The publish to IIS created the folder on my C drive: inetpub\wwwroot\ProfileAndOrBlog.
I launch the web app in the browser with this URL: http://localhost/ProfileAndOrBlog.
I then sign into the web app using a top menu item just fine. That menu link is coded in the view as:
<li>#Html.ActionLink("Sign In", "SignIn", "SignIn", routeValues: null, htmlAttributes: new { id = "signinBtn", #class = "btn btn-primary my-signin-btn" })</li>
The URL generated is: http://localhost/ProfileAndOrBlog/SignIn/SignIn
After sign in, I get this page.
The URL generated is: http://localhost/ProfileAndOrBlog/User
I can now click on any side bar menu (a function of the app) - a link.
When I use the side bar menu link 'Make Suggestions' coded in the view as:
<i class="fa fa-edit fa-fw"></i> Make Suggestions
I get a 'This localhost page can't be found'.
The URL generated is: http://localhost/UserSuggestionMaint/Index.
It does not have the ProfileAndOrBlog/ as part of the route.
Note: if I manually add in the missing part of the route to the URL, it works.
http://localhost/ProfileAndOrBlog/UserSuggestionMaint/Index
So, why is that route part missing?
I don't quite get your question but it seems your problem is simply about routes.
When using links
<li>#Html.ActionLink("Sign In", "SignIn", "SignIn", routeValues: null, htmlAttributes: new { id = "signinBtn", #class = "btn btn-primary my-signin-btn" })</li>
Simply means it should display "Sign In" on a button and the link will be mapped to something like below:
"/SignIn/SignIn"
and
"/UserSuggestionMaint/Index"
In simple terms routes are usually "/Controller/action" in MVC.
So make sure you are referencing the right action method and it will work.
Using "/UserSuggestionMaint/Index" means the controller should be something like UserSuggestionMaintController and the Index action which will render the Index View.
Something you need to know about using absolute and relative paths in hyperlink <a href>,
Beginning with http:// or //. The browser will resolve the link as an
absolute URL.
Beginning with a single /. The browser will resolve the link as
relative to the domain.
Beginning with text. The browser will resolve the link as relative to
the page.
Beginning with #. The browser will look for an HTML element on the
same page (by ID) and scroll to it if found.
So when you use <a href="/UserSuggestionMaint/Index">, it adds this content after domian not current url.
But when you use #Html.ActionLink, it returns a specified link text according to an anchor element.
In my test, I use #Html.ActionLink in layout page. When I set the MVC application as a separate site, #Html.ActionLink generates a hyperlink likes this:
If I set the MVC applciation as a sub application under a site, it likes this:
Part of /ProfileAndOrBlog url is necessary so that IIS can know which application you want to access. Then asp.net route can know UserSuggestionMaint is controller and index is action.
The solution is:
Not use relative URL of hyperlink but absolute URL. <a href="http://domain name/ProfileAndOrBlog/UserSuggestionMaint/Index">.
Deploy the mvc application as a separate site not a sub application under default web site.
Not use but #Html.ActionLink to dynamically generate a hyperlink.
Thanks all for the insight.
To not change each of the href's to add in the tilde to the beginning of the path as suggested, I instead changed my Publish Profile. I had 'ProfileAndOrBlog' as part of the Site name (Default Web Site/ProfileAndOrBlog) and the Destination URL (http://localhost/ProfileAndOrBlog). I removed it in both places and it resolved the URL problem. Here is how my Publish Profile is now:
I now can successfully access all the functions of my web app when I launch the web site in the browser with this URL: http://localhost
So for my 'Make Suggestions' link, the URL is now: http://localhost/UserSuggestionMaint/Index.

Routing in MVC, "Specify a root relative path with a leading '/'"

I had a razor page called Submit that was giving me a Value cannot be null. Parameter name : viewData error so I removed the #page at the top of my code as this post directed. My issue now is that when I load the page I the following error:
InvalidOperationException: The relative page path 'Index' can only be used while executing a Razor Page. Specify a root relative path with a leading '/' to generate a URL outside of a Razor Page. If you are using LinkGenerator then you must provide the current HttpContext to use relative pages.>
I want my page to have a URL of https://localhost:44369/Submit How would I do this? Here is my routing in my Startup.cs file:
app.UseMvc(routes =>
{
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
The reason you are getting the error is because of incorrect syntax. In one of your Razor Views, you probably have an anchor tag that might look like:
<a asp-page="Index">Index</a>
That syntax (without the forward slash /)is meant for a Razor Page. In the Razor View, prefix the Page name with a forward slash:
<a asp-page="/Index">Index</a>
If everything else is correct you should be able to browse https://localhost:44369/Submit and it should show the whatever is written in your Submit page
You might use Razor Pages asp-action in a MVC project.
For MVC
1> Using tag asp-action but not asp-page to redirect.
<a asp-action="Submit" class="btn btn-success form-control">Submit</a>
2> use Route Attribute to route to the specified view .
Controller.cs
public class HomeController : Controller
{
[Route("/Submit")]
public IActionResult Submit()
{
return View("~/Views/Home/Submit.cshtml");
}
}
Test:
https://localhost:44307/Submit
https://localhost:44307/submit
The screenshot of result:
There are some articles it might help you to figure out Razor Pages and MVC.
How Does Razor Pages Differ From MVC In ASP.NET Core?
Building Your .NET App - Razor Pages vs. ASP.NET MVC

Angularjs inside MVC Razor

i am very new to angular and have been doing some basic stuff.
I am trying to convert some view to use angular and i am stuck
can someone with help how i would do the following using angular
<img data-original="img/property/pic (2).jpg" alt="#item.Description" src="#Url.Action("GetImage", "Home", new { id = item.RentalID })" class="img-hover">
i want to repleace the "item" with a data repeater {{i.Item}} for example
I've tried this but it wont work
<img data-original="img/property/pic (2).jpg" alt="{{i.Description}}" src="#Url.Action("GetImage", "Home", new { id = {{i.RentalID }}})" class="img-hover">
You can't, because the #Url.Action is rendered on the server whereas the angular stuff is done later, on the client.
You could however try this:
<a ng-href="#Url.Action("Details","Home",new { PropertyType="Rentals" })&propertyID={{i.RentalID}}"><img data-original="img/property/pic (2).jpg" alt="{{i.Description}}" ng-src="#Url.Action("GetImage", "Home")?id={{i.RentalID}}" class="img-hover"></a>
Please note that I used ng-href and ng-src since we are now using dynamic properties in the URL:
Using Angular markup like {{hash}} in an href attribute will make the
link go to the wrong URL if the user clicks it before Angular has a
chance to replace the {{hash}} markup with its value. Until Angular
replaces the markup the link will be broken and will most likely
return a 404 error. The ngHref directive solves this problem.

ASP.NET MVC Base Address changes when publishing to IIS 7

I published an MVC4 app on IIS and my base adrress changed to localhost/somevirtualdirectory/Home/Index.
That works fine however when I click on a ActionLink ( tag) I'm being redirected to localhost/someController/Action and that fails since the somevirtualdirectory is missing in the url.
How can I set the the action will redirect to the baseadrress with the virtual directory?
This happens because in your action link you have entered your URL hard coded starting with slash which will throw you to the parent directory and thus excluding the subdirectory. Use Url.action to form the URL which will include your sub-directory when you hit :
#Url.Action("Action_Name", "Controller_Name")
there is a difference. Html.ActionLink generates an tag whereas Url.Action returns only an url.
For example:
#Html.ActionLink("link text", "someaction", "somecontroller", new { id = "123" }, null)
generates:
link text
notice this slash at the beginning of the href which will take you to the root .
and Url.Action("someaction", "somecontroller", new { id = "123" }) generates:
/somecontroller/someaction/123
Now when you click It will append it on the sub directory

Another ASP to MVC migration > routes

Migrating our classic ASP site to ASP.Net 4.5 MVC. Our site is pretty large, hundreds of file, and SEO optimized. All URLs are SEO friendly, via web.config, eg.:
www.ourdomain.com/articles/2013/120/the-best-article
www.ourdomain.com/blog/2013/122/the-best-blog
www.ourdomain.com/video/2013/123/the-best-video
ie. www.ourdomain.com/{contenttype}/{year}/{id}/{url encoded title}
The ASP files to render are stored in a folder like /render/content.asp
We don't want to change any URLs in this migration. The new files of the MVC app will be in all new directories than the existing site. For example, a view: /MVC/content.vbhtml
How would you go about adding links in your Views, with ActionLink or other, to use the existing SEO friendly path instead of the default path, without hardcoding the path in the links in the view (adopt from currently URL, more or less). For example:
#Html.ActionLink("Edit", "Edit", New With {.id = currentItem.ID})
That creates an Edit link like : /MVC/Edit/120
But, what I would like is: /article/edit/120.
Any help appreciated.
Use
#Html.RouteLink("Edit", "myRouteName", New With { ... route params ... } );

Resources