We have an app built on dotnet core (currently 5, will be upgrading to 6 soon) that has a very strange issue. 95% of the web app runs perfectly, but there is a single razor page that generates a 404 - but only when deployed to the production server. Within Visual Studio it all works as expected, but even using dotnet MySite.dll (the .exe version of that command didn't work - it said a duplicate reference existed in the deps.json file with a different extension, but targeting the .dll version did what I expected) which spins up a "development" web server on ports 5000/5001, but even that gets the 404 on this one single page. All other pages work (including partial views) as expected.
The code on the page is about as basic as it comes, because it's a partial view setup like this:
#page "/providers/information"
#model ProviderInformationChangeRequestModel
#{
Layout = null;
}
The rest of the content on the page is just HTML - it's got a form, textbox and button on it, so nothing fancy there. Behind the razor page it's also quite basic:
public async Task<IActionResult> OnGet()
{
//EntityModel is a public property exposed on our base `PageModel` class (ours extends the Microsoft one)
this.EntityModel = new ProviderChangeModel();
//this is an API call - we use this exact call all over the site, so presumably it isn't failing, since it works everywhere else
var entity = await this.GetFromJsonAsync<ProviderUserModel>("/user/me");
this.EntityModel.ProviderUserId = entity.Id;
this.EntityModel.ProviderId = entity.ProviderId.Value;
return Page();
}
Every other partial view we have using this type of structure works - both deployed and through VS - and it's just this one page that won't work. I've read that this can sometimes happen when a Razor page makes backend API calls if one of those kicks back a 404, but the only call it makes is one we use throughout the site so it can't be that.
Does anyone have any ideas that can point us in the right direction? If it was failing in VS it'd be easy to track down, but since it's only the deployed version (which I've redeployed multiple times, restarted corresponding app pools and so on), I'm at a loss.
Well that was quick. A friend looked at it and realized the Build Type on the cshtml page was set to None instead of Content - how it worked in VS I'm not sure I understand, but at least it's solved now.
Related
I have web app which is working, and only one view is creating me a problem.
That view can not be found even if though it exists in the correct folder:
I know you can use C# and .NET with Angular 2, but I've only seen it done in the layouts. Can you include C# in the component files? For example, there is a dashboard.component.html file in the Tour of Heroes tutorial on the Angular 2 website. Could you change that to dashboard.component.cshtml and include C#/Razor?
I am 90% sure you can't do this without a hack. Even though they look like a standard HTML file, they are separate as a convenience. They are typically streamed into your JS code on build.
That said, my 10% answer is that you could probably do something that would wrap a server call in a JS nugget so you could keep the actual CHTML server-side. You should be able to bake a script section that calls out like this: ASP.NET MVC rendering partial view with jQuery ajax
Can you give your scenario of why you would want to do this?
Angular 2 (Javascript/Typescript) is client side (though it still uses a transpiler to convert TS to JS.
While cshtml files are compiled through the ASP.NET compiler as they are apart of the declarative resources in ASP.Net structure.
Razor syntax needs an engine that understands what the symbols means the compiler holds references to these so that when it's interpreted it generates the correct code under the hood. However they are dynamically compiled by the ASP.NET runtime.
See more info here: Why isn't a compilation needed when updating cshtml files with .net code?
https://weblogs.asp.net/scottgu/introducing-razor
Can you include C# in (angular 2) component files? The answer is no and why would you want to do that anyway? I use Angular2 and Asp.net MVC together all the time. But it's important, conceptually, to understand a few things:
Let asp.net handle the backend, and let Angular2 handle the front end.
Otherwise don't mix the two (unless you are into Angular Universal in which your ng2 app is pre-rendered on the server, but this is a special topic).
I separate these concerns so completely that, when I am developing, I use the angular-cli within the context of Visual Studio Code, i.e. not one byte of .net is present in the Angular2 development environment.
Now of course your ng2 app is probably going to want to make calls to "the server", i.e. make http calls etc such as the following:
getMeSomeServerData(someVar: string): Promise < IGenericRestResponse > {
let headers = new Headers();
headers.append("Content-Type", "application/json");
let url = this.apiUrl + "getMeSomeServerData";
let post = this.http.post(url, JSON.stringify(someVar), {
headers: headers
}).map(response => response.json());
return post.toPromise();
}
The key thing to notice here is:
this.apiUrl
When I am in development mode I make this refer to my back-end project located at something like http://localhost:1234/ which refers to an asp.net MVC project i am running concurrently in Visual Studio. So the back-end looks something like this:
[HttpPost()]
[Route("getMeSomeServerData")]
public JsonNetResult GetMeSomeServerData(string someVar) {
GenericRestResponse response = new GenericRestResponse();
response.Error = false;
// do somthing
return new JsonNetResult(response);
}
Note: you have to configure your asp.net mvc backend for CORS or cross-origin HTTP requests since your ng2 app is not on your mvc project domain.
Now, if you like, you CAN have your backend service return text, i.e HTML. Which means you can even go so far as to return partial cshtml views, which is just text after all. Then on the front end, your ng2 app can inject the html however you like. This generally defeats the purpose of Angular 2, in my opinion, and your server can become bogged down with rendering views. But it's up to you.
In any case, when you want to deploy your app for production, then you use the the angular-cli command to bundle and optimize your ng2 app ("ng build -prod"). Then copy all the assets in the "prod" folder to your asp.net mvc project (gulp makes this fast and easy). Use ONE razor view and one razor view only to server your webpage. Here is an example of such a view, Home.cshtml:
<!DOCTYPE html>
<html>
<head>
<base href="/">
<script type="text/javascript" src="~/assets/js/styles.bundle.min.js"></script>
</head>
<body>
<app>Loading...</app>
<script type="text/javascript" src="~/assets/js/main.bundle.min.js"></script>
</body>
</html>
And THATS ALL you use razor views for: to serve your initial SPA page view. Just don't forget to change your "apiUrl" in your app to reflect the http calls are going locally.
You can create an Asp.Net MVC application and then add the Angular Libraries and setup your App to use the default Layout and default controller Index action.
Then you can create partial actions and use its URL as a template for the Angular route, ex:
templateUrl: 'YourController/YourPartialAction'
Although this will work, but I don't think it is recommended cause you mixed both MVC and Angular, Angular is supposed to be totally client side and separated from your back end
Wondering if anyone else has experienced this and what their solution was if so. In Visual Studio 2013 I create a new ASP.NET Web Application, leaving all the defaults as they are
In the next screen I pick MVC, adding folders and core references for MVC but not the other two options. Authentication is left at Individual User Accounts and I've unchecked the Host in the cloud option, as shown below.
The project wizard completes and I can see that there are 26 errors in it before I do anything else.
The first fix that removes a bunch of these errors is that the Views\Account\ _SetPasswordPartial.cshtml and _ChangePasswordPartial.cshtml files contain invalid models so I change those as follows:
[My project name here is WebApplication1, substitute your own value]
In _SetPasswordPartial.cshtml:
From #model WebApplication1.Models.ManageUserViewModel to #model WebApplication1.Models.SetPasswordViewModel
In file _ChangePasswordPartial.cshtml:
From #model Microsoft.AspNet.Identity.ManageUserViewModel to #model WebApplication1.Models.ChangePasswordViewModel
That drops me down to 4 errors, spread across 4 files
1.
Line 68, ManageController.cs
return View(linkedAccounts);
The view RemoveLogin doesn't exist
2,3.
There are two errors _SetPasswordPartial.cshtml and _ChangePasswordPartial.cshtml complaining about not being able to resolve the Manage action but when I debug and visit those URLs in the browser they work fine so I suspect they're in a route table somewhere. I have R# installed so sometimes that can be wrong if that's the case.
4.
The last one is that the _RemoveAccountPartial.cshtml has an error on line 15 where it complains about not having a Disassociate action in the Account controller, as far as I can ascertain this is to do with removing other authentication providers to the application.
Now I can fix all these by adding the required code but it just doesn't sit well with me that the templates don't work well out of the box. Are there fresh templates available or has anyone done the canonical write-up on how to get your template humming before you commence work properly on it?
EDIT 2014-11-13
I've just applied VS2013.4 and these issues appear to be fixed as part of it. If this is an issue for people then I suggest applying that update.
I do not know what is the root cause of these problems but after playing with the project the following seems to bring it to a consistent state:
Remove Views\Account\_SetPasswordPartial.cshtml
Remove Views\Account\_ChangePasswordPartial.cshtml
Remove Views\Account\_RemoveAccountPartial.cshtml
All these have counterparts under the Manage controller. And finally:
Remove the RemoveLogin() action method from ManageController. Make sure you only remove the GET method (lines 64 - 69), as the POST one is actually used. The list of logins is rendered by ManageLogins action.
Found out it's a known problem:
http://blogs.msdn.com/b/webdev/archive/2014/08/04/announcing-new-web-features-in-visual-studio-2013-update-3-rtm.aspx
When creating a default C# ASP.NET Web Application from MVC, WebAPI or SPA template with individual authentication, generated Views\Account\ _SetPasswordPartial.cshtml and _ChangePasswordPartial.cshtml files contain invalid model.
In file _SetPasswordPartial.cshtml,
#model .Models.ManageUserViewModel
Should be changed to:
#model .Models.SetPasswordViewModel
In file _ChangePasswordPartial.cshtml,
#model Microsoft.AspNet.Identity.ManageUserViewModel
Should be changed to:
#model .Models.ChangePasswordViewModel
Similar problems exist for generated VB projects as well.
In file _SetPasswordPartial.vbhtml,
#ModelType ManageUserViewModel
Should be changed to:
#ModelType SetPasswordViewModel
In file _ChangePasswordPartial.vbhtml,
#ModelType ManageUserViewModel
Should be changed to:
#ModelType ChangePasswordViewModel
I confirmed issue also in VS2013 Ultimate Update#3. Submitted bug report to Microsoft Connect under Visual Studio and .NET Framework section.
So this is going to bed a dumb question because I understand there is a simple solution, I just cannot figure it out....
At the moment I am running my MVC 5 project in visual studio 2013... Normally when I want to debug it I will just click run and the website will appear in the browser of my choice...
I just recently published it to my companys web server and now I am having all kinds of issues...
The website is just 15 buttons on the Home/Index page and I want to be able to click on the buttons and still run them on my localhost side and when I publish them, still have them find the right path..
Here is an example because I am not very good at explaining things...
I run it in visual studio my url is:
http://localhost:54641/Home/Index
I run my published site on the webserver my url is:
http://webserver/racklabels/dakkota/Home/Index
I understand this part, and in either case both of them work but when it comes to clicking on a button, or images.. the pathing is all weird and I dont understand it.
In visual studio I click my first button and my url becomes:
http://localhost:54641/RecieveTruck/AddFor
On my webserver I click it and it turns to:
http://webserver/RecieveTruck/AddFor
but gives me the 404 error because it is not the correct route ( which should be..
http://webserver/racklabels/dakkota/RecieveTruck/AddFor
)
This is how I have my button setup in my View (Index.cshtml) and I am wondering if this is what is causing the probelm (I am thinking that I may have to do it a different way other than using onclick)
<input type="button" name="receive" value="Receive Truck" style="cursor: pointer;" class="bodyText"
onmouseover="this.style.color='orangered';" onmouseout="this.style.color='black';"
onclick="document.location.href='/RecieveTruck/AddForm';">
Basically I would like for this to work regardless of how many folders I am deep after I publish it and when I click run in visual studio (so I can debug/test and just republish to the webserver when I want to update)
I have tried many different ways of sending the path... like '~/RecieveTruck/AddForm' (which just adds the ~ to the address) and '../RecieveTruck/AddForm' and just 'RecieveTruck/AddForm' but none of them find the actual root of where the project lives and just adds this to it...
Can anybody help me?
You can use
#Url.Content("~/Home/Index")
but this completely misses out the benefit of mvc routing.
if you want to generate urls for controller actions, it's much better to use
#Url.Action("Index","Home")
...so now if you set up some snappy routing rule, the url in provided by .Action will adjust automagically (such as omitting url parts that have default values in your routing rules).
You need to add "~" to the front of the url document.location.href='~/RecieveTruck/AddForm'
or if that does not work use document.location.href='#Url.Content("~/RecieveTruck/AddForm")'
I have created a website using ASP.Net and running on port 8080. When server is still running, I can some changes in the code. Interestingly, those changes are reflected on my site when I pressed refresh button. I just wondering with this because I guess we have to compile and rebuild site to see new changes.
thanks !
Yes, WebSite working in this way. WebApplication requires rebuild all because all codebehind logic are built in DLL of WebProject
See this MSDN article: Comparing Web Site Projects and Web Application Projects
Web Site Projects
Prefer dynamic compilation and working on pages without building entire site on each page view (that is, save file and
then simply refresh the page in the browser).
That depends on if you have an asp web site of a web application. Take a look at this msdn page for more info.
When you have the full source for an ASP.NET web site (not a web application) running, your site will be dynamically compiled, and changes you make will be detected.
From the MSDN documentation, Understanding ASP.NET Dynamic Compilation:
Any changes to a dynamically compiled file will automatically invalidate the file's cached compiled assembly and trigger recompilation of all affected resources. The next time a request to the code is made, ASP.NET recognizes that the code has changed and recompiles the affected resources of the Web application. This system enables you to quickly develop applications with a minimum of compilation processing overhead. (Note that depending on the change to the resources, the result can range from recompiling a single page to recompiling the whole Web site.)