I have a project with .NET Core 2.1 Razor Pages. It was built using the authentication option in the new project UI. So, when I type the URL and hit enter, the website opens the Microsoft login page, and I cannot see any page until I am signed in.
Now, I have a request to change the behavior of the authentication and I need to show the home page (Index) and other pages without the authentication process. So, I think I have to move the login page to a button and allow those pages to be accessible by anyone.
Can you please show me the right direction for this change?
I see that the [AllowAnonymous] directive is only for the controller (ASP.NET Core MVC), because it is not working in the Razor page, where the client and server code are combined in 2 files.
Also, I found a post talking about Service.AddRazorPage but I got an error showing that this method is for MVC, so I don't know if I have to continue with my research to work with this method.
Thanks!
You can try using Razor Pages authorization conventions in ASP.NET Core:
services.AddMvc()
.AddRazorPagesOptions(options =>
{
// options.Conventions.AuthorizePage("/Contact");
// options.Conventions.AuthorizeFolder("/Private");
options.Conventions.AllowAnonymousToPage("/Index");
// options.Conventions.AllowAnonymousToFolder("/Private/PublicPages");
})
// ...
;
Related
1.I have tried adding the IIS Rewrite Rule which works for local environment but not in the higher environments.
2.Sitecore redirect settings is also not working.
3.Currently (localhost)/default loads the homepage and I need this to get redirected to another page of my site.
Can somebody help me to achieve this without overriding the HttpBeginRequest Processor?
public IActionResult Privacy(){return Redirect("https://google.com"); }
As you have an MVC project, requests will all route to a controller action, you can set the redirection in the corresponding action.
I am looking at a .Net Core 3.1 project, which has one controller and a bunch of pages. I cannot navigate to any of the pages. In order to explain my issue; I have added this method to the controller:
public async Task<IActionResult> Test()
{
return RedirectToPage("/Error");
}
If I navigate to the Test method via the browser then instead of redirecting to the error page; the Test method is called in what appears to be an infinite loop i.e. the method is called many times until a 'ERR_TOO_MANY_REDIRECTS' page appears. I think this means there is a routing issue, however I am not sure. The project has a structure like this:
Controllers
Models
Pages
Error.cshtml
It is a .Net Core 3.1 project. I have never seen a project with a Pages folder before (it normally says Views) and hence the reason for the question. I have spent the last hour Googling this and have got nowhere and hence the reason for the question. I am using .Net Core 3.1.
In the Startup.cs file the Razor pages middleware needs to be configured to enable routing for Razor pages.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages()
}
It looks like the infinite loop on the Error routing had 2 parts.
The route for Test was redirecting to /Error per the controller
/Error had no routing which redirected to /Error causing an infinite loop until the runtime stopped execution and threw the error mentioned.
Problem:
Using an ASP.NET Core 2.1 MVC project, I'm receiving the following browser error message after using the browser back button to return to a form, where the form POST failed server-side validation:
Error message in Firefox:
Document Expired
This document is no longer available.
The requested document is not available in Firefox’s cache.
As a security precaution, Firefox does not automatically re-request sensitive documents.
Click Try Again to re-request the document from the website.
Error message in Chrome:
Confirm Form Resubmission
This webpage requires data that you entered earlier in order to be
properly displayed. You can send this data again, but by doing so you
will repeat any action this page previously performed.
Press the reload button to resubmit the data needed to load the page.
ERR_CACHE_MISS
Steps to reproduce:
Submit an HTML form post, where server-side validation fails
navigating to a different URL
click the browser back button to return to the page with the form
Notes:
It appears to be related to Response caching (https://learn.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-2.1) being disabled for the Antiforgery system.
The Antiforgery system for generating secure tokens to prevent
Cross-Site Request Forgery (CSRF) attacks sets the Cache-Control and
Pragma headers to no-cache so that responses aren't cached. For
information on how to disable antiforgery tokens for HTML form
elements, see ASP.NET Core antiforgery configuration.
Which I can confirm, if you remove #Html.AntiForgeryToken() from being included in the HTML form, the browser error message goes away.
This was not an issue in ASP.NET MVC5 using the AntiForgeryToken.
Question:
In ASP.NET Core 2.1, has anyone found a way to continue to use the Antiforgery system and prevent this browser error message from being displayed when the browser back button is used?
Here's my POST action:
[HttpPost]
[ValidateAntiForgeryToken]
[ActionName("Contact-Form")]
public async Task<ActionResult> ContactForm(ContactFormViewModel cfvm)
{
if (ModelState.IsValid)
{
// << Handling of the form submit code here >>
TempData["Success"] = string.Format("Your contact request was submitted successfully!");
return RedirectToAction("Contact-Form-Success");
}
TempData["Error"] = "The form did not submit successfully. Please verify that all of the required fields are filled.";
return View();
}
Update:
I posted the question on the ASP.NET Core Docs:
https://github.com/aspnet/Docs/issues/7590
This is a not a language specific issue. This is a browser behavior. To say this was 'not an issue with ASP.NET MVC 5' is incorrect.
Solutions:
A common method of solving this is the PRG pattern which has been around since 1995.
An implementation of this for ASP.NET Core, using TempData can be found here
And I think that this link would be most helpful for you, since it demonstrates a method implemented in both MVC 5 and MVC 6.
I hope this helps!
I will try and update this post soon with a sample based on a razor-page starter project, time permitting.
I completed the "Tour of Heroes" tutorial on Angular 2's website and everything is working great. If I click around, the URL changes and when I refresh, it takes me right where I was before, as you would expect with proper routing.
I want to now use .NET and C# on the backend, so I went through Angular 2's tutorial on getting the project set up with Visual Studio (I was using Sublime Text before). I completed it and got it working, but noticed that the routing only worked when pressing the back/forward buttons. Refreshing didn't work like it did when I just used Sublime and NPM. I went back to the tutorial and found a message at the bottom that concerns me:
"If this application used the Angular router, a browser refresh could return a 404 - Page Not Found. Look at the address bar. Does it contain a navigation url (a "deep link")? We'll have to configure the server to return index.html for these requests. Until we do, remove the navigation path and refresh again."
https://angular.io/docs/ts/latest/cookbook/visual-studio-2015.html#!#build-and-run
Does this mean that Angular 2's routing won't work with Visual Studio when I refresh the page no matter what? Is there no hope for Angular 2's routing to fully work when using Visual Studio/.NET/C#?
Angular 2 uses the HTML5 history API. The urls look just like any other site. When you load http://example.com/posts/23 the .NET backend will try to handle it and if it can't will return 404.
That is not what you want.
You want to return the contents of index.html and let Angular handle the rest.
Note that you don't want to redirect to http://example.com/index.html, if you do that it will load angular but you will lose the current path. That way you will never be able to share links to your site.
I assume that you are using the latest version of .NET Core and Visual Studio's templates.
What you need to do:
Install this NuGet package Microsoft.AspNetCore.StaticFiles
Go to Startup.cs and find the Configure method
Add these lines before app.UseMvc();
app.UseDefaultFiles();
app.UseStaticFiles();
Add these lines after app.UseMvc();
app.Run(async context =>
{
context.Response.StatusCode = 200;
context.Response.ContentType = "text/html";
await context.Response.SendFileAsync("./wwwroot/index.html");
});
Add this to the top of the file
using Microsoft.AspNetCore.Http;
For more information look here:
https://docs.asp.net/en/latest/fundamentals/static-files.html
https://angular.io/docs/ts/latest/guide/router.html#!#base-href
I want to run a version consistency check between the website and database on every page in the software I work on to see whether one or the other is out of sync. (background: someone could upgrade while a user is using the software, so restricting the check to the sign in page isn't realistic - also why the check is required on any page in the software).
I am not in control of the deployment, as the customer hosts the software themselves on their own hardware.
The front-end is a mixture of asp.net pages and MVC4 (gradually replacing the aspx pages with MVC) , so I can't simply just run the check on Page_Load() in our inner and outer basepages and then have something different for our MVC pages - I would rather not duplicate code for each page type.
Having a look around, I have seen filters which exist for MVC which could be an option for those pages.
I've been investigating HttpHandlers and in theory could restrict the requests down to page load and not static content.
Is there an alternative/better way to do this server side check which would have the code in just one place and would affect both aspx pages and MVC?
Depending on what it should do when its passes the check or fails the check you could set up a new controller Version with an action Check
public class Version : Controller
{
public JsonResult Check() {
return new Json((GetWebsiteVersionNumber() == GetDatabaseVersionNumber()));
}
}
You can then call this endpoint from MVC using #Html.Action in _Layout or in another view and respond accordingly. On the Web Forms side you can then call this end point using the serverside WebRequest class and take appropriate action depending upon the response from your MasterPage PageLoad event or anywhere else you prefer.
Further you could call the endpoint from a common javascript file i(ncluded on both the WebForms and MVC client side includes) and using an AJAX request get the response and deal with it there also.
Excuse syntax errors as I was writing this off the top of my head.