System.Web.HttpException when using [Authorize] - c#

I am facing a very weird problem that I am unable to solve.
I have this button onclick of which I go to the controller action method where I need to use [Authorize], when I use [Authorize] I get the following error.
The following sections have been defined but have not been rendered for the layout page "~/Views/Shared/_Layout.cshtml": "Scripts".
System.Web.HttpException
However, when I don't use [Authorize] it works fine. Why does it behave like that? Any help would be highly appreciated.
[Authorize]
public async Task<ActionResult> Calendar(int id, string start, string end)
{
//code
}

On your ~/Views/Shared/_Layout.cshtml page you have likely a required section that has to be included on every view, it will be something like this:
#RenderSection("scripts")
You need to change it to this:
#RenderSection("scripts", required: false)
Which means the section will be optional on pages using your layout page.
Old but still relevant:
https://weblogs.asp.net/scottgu/asp-net-mvc-3-layouts-and-sections-with-razor

Related

Razor Pages override route getting RoutePatternException despite seemingly correct

I am using Razor Pages, and everything has been going smoothly so far.
Now I wish to create a page with an override route. Like the override routes that are shown possible here.
I am, however encountering the following exception, despite I don't seem to have the issue in my code that it describes:
RoutePatternException: There is an incomplete parameter in the route template. Check that each '{' character has a matching '}' character.
I must be somehow misunderstanding how this routing works, but I haven't been able to find someone encountering the same issue in my preliminary searches.
This is my entire code on this page so far:
#page "/layouts/{layoutId:int}/save/{revisionId:int}"
#model Project.Web.Pages.TenantBased.Layouts.SavePageModel
#{
Layout = "_TenantLayout";
ViewData["Title"] = "Title";
}
And this is the code-behind:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Legalit.Web.Pages.TenantBased.Layouts
{
public class SavePageModel : PageModel
{
public void OnGet(int layoutId, int revisionId)
{
}
}
}
This gives the following exception when running the project:
RoutePatternException: There is an incomplete parameter in the route template. Check that each '{' character has a matching '}' character.
If I remove the first / from the route as so:
#page "layouts/{layoutId:int}/save/{revisionId:int}"
Then it stops generating the exception, but I of course get the wrong routing from it. Now my page is reachable by the directory path with this route added to the end of it.
I am using .NET 6.0.
The project type is Microsoft.NET.Sdk.Web
The project had a custom Convention in the Program.cs that was specified under the AddRazorPagesOptions configuration method.
After removing this, it worked fine.

ASP.NET MVC - How do I Call a Controller Method from within a View to Redirect to Multiple Other Views?

I am trying to add a single link in my navbar that redirects the user to a different webpage depending on their account type. I am having issues doing this and could use some help.
The Controller code that I am calling looks like this:
public IActionResult Attendance(char accountType)
{
if (accountType.Equals("m") || accountType.Equals("a"))
{
return RedirectToAction("FacultyAttendance");
}
else
{
return RedirectToAction("StudentAttendance");
}
}
public IActionResult StudentAttendance()
{
// More functionality will be added later
return View();
}
public IActionResult FacultyAttendance()
{
// More functionality will be added later
return View();
}
Following this answer for calling the Controller method, I have this code snippet in the View file:
Attendance
This gives me the following error:
Bad Request - Invalid URL
HTTP Error 400. The request URL is invalid.
I also tried following this answer by removing the <%: and %>.
Attendance
If I do this, I just get blank webpage.
My first problem lies in which style I should use for this method call within the View file. Are either of these correct, or should I use something else entirely? Might the issue be with the way I have the Controller code set up?
Any help would be appreciated, as I am new to the MVC framework for ASP.NET.
Edit: The solution I found is a bit different than what I originally posted. I used this tag in my View and got it to work:
<a asp-controller="Home" asp-action="Attendance" asp-route-accountType='s'>Attendance</a>
I also followed ThisGuy's suggestions for improving the code since I had mismanaged some variables and that may have been part of the problem.
accountType is a char, but you are passing a string:
new {accountType = "m"}
Change the Controller to take a string instead of char for accountType.
public IActionResult Attendance(string accountType)
Also, I'd write it like this:
public IActionResult Attendance(string accountType) =>
RedirectToAction(
accountType.Equals("m") ||
accountType.Equals("a")
? nameof(FacultyAttendance)
: nameof(StudentAttendance));

How do I redirect to HTML page from within a controller?

Users receive an email with link that they must click on in order to certify their email address. Once the link is clicked, the user should be redirected to one of two static HTML pages, one saying "You're certified" the other stating "The link is expired"
I have attempted a few options. The first I added a Response.Redirect to my controller with a path to the View. I also tried where I added a routes.MapPageRoute to my RouteConfig file and changed my redirect call to attempt to use this name, but that doesn't work either. I looked at this example for that fix ( Redirect to an html page inside Views Folder )
Here is my code attempting to access the HTML file with the redirect:
EmailCertification.UpdateDBEmailCertified(userName, int.Parse(memberNumber), certSentDT);
return Redirect("~/Views/EmailCertification/EmailCertified.html");`
The error I get is that:
Path to /Views/EmailEmailCertification/EmailCertified.html is not found. I verified the spelling and the path is all is correct.
If I changed my code to include MapPageRoute in RoutesConfig it still doesn't work.
Here is my route config:
routes.MapPageRoute("HtmlPage", "EmailCertifiedURL", "~/Views/EmailCertification/EmailCertied.html");`
Here is my controller:
return Redirect("EmailCertifiedURL");
Here is my controller in action, it is a HttpPost
public ActionResult EmailCertify(string userName, string memberNumber, string certSentDate)
{
DateTime certSentDT;
long lngCertSent = long.Parse(certSentDate);
certSentDT = new DateTime(lngCertSent);
if (certSentDT < DateTime.Now.AddDays(-14))
return Redirect("EmailOldURL");
EmailCertification.UpdateDBEmailCertified(userName, int.Parse(memberNumber), certSentDT);
return Redirect("~/Views/EmailCertification/EmailCertified.html");
}
The error I get on this is that
the controller doesn't have a action EmailCertifiedURL. This code I took from the above mentioned StackFlow article.
All I want is the email link to fire off the controller action EmailCertify and redirect me to a static HTML page.
https://localhost:44344/EmailCertification/EmailCertify?userName=IS&memberNumber=3000050&certSentDate=636959314302036120
That seems strange. A work around could be adding a new action that returns your entire html with no layout. I mean, try with this
public ActionResult CertifiedEmail(){
return View();
}
Then you should create a view for your action with the same name ( CertifiedEmail.cshtml ), and inside your View paste all your html. At the beginning you should add this code to remove the Layout
#{
Layout = null;
}
I tend to use RedirectToAction() methods instead of just Redirect()
The 2nd parameter will need to be the name of the controller if it is a different controller.
return RedirectToAction("EmailCertifiedURL", "EmailCertification");
public ActionResult Questionnaire()
{
return Redirect("~/MedicalHistory.html");
}

Adding HttpPost getting error 'The Resource Cannot Be Found' in MVC

I'm getting the error
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /ClientEdit/ClientEdit/1104
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272
when I add HttpPost attribute to a controller. I've looked into this and corrected my code with posted(no pun intended) answers but nothing I've tried works. Here's my controller header:
[HttpPost]
public ActionResult ClientEdit(int id,FormCollection formCollection)
I added HttpPost so I can populate my FormCollection object. As with other SO posts, this causes the error. Removing it solves the issue but my FormCollection doesn't populate any key/value pairs.
My view has its form tag's method set to POST which solved other dev's issues but it doesn't solve mine. I tried adding 'name=' properties to my textbox controls as well as 'id=' but that doesn't work either.
<body>
<form method="post" action="1104" id="form1">
I don't know what else to try.
You need to provide you view that renders the <form> as well. The action on what you show as your HTML looks wrong to me. I would think it would be something like action="/Controller/ClientEdit".
you have given wrong value in the attribute action="1104".
Either you can specify proper route in action attribute or leave it if the route is same as of get.
This should work if GET and POST route are same
<form method="post" id="form1">
.....
</form>
use this:
#using(Html.BeginForm()){
<!--Your form field-->
}
Basically what is happening is that your action attribute is just pointing to the Id you have and not the url to post to.
You can do it manually like this:
<form action="ClientEdit/ClientEdit/1104>
<!--form fields-->
</form>
Yes, you are all correct. I was passing a userid as the action. This was legacy code that 'worked' for another feature but doesn't conform to the MVC pattern. I did some other research (as I'm not too familiar with MVC either) and started again from scratch using MVC as it should be. Thanks everyone.

MVC Form Submit - Redirecting to an action that is not accessible from the browser directly

I am learning MVC 3 after hours right now and last night I ran into an issue that seems like it would be very simple to solve but I can't seem to locate a solution for it.
I have a simple contact form. The end user fills out the form and submits it. When they submit the form I redirect the end user to a different action in the same controller which renders an "inquiry submitted" page/view which is basically a "Thank you page".
The controller is setup like so.
public ActionResult ContactUs()
{
return View();
}
[HttpPost]
public ActionResult ContactUs(ContactInfo contactInfo)
{
if (!ModelState.IsValid)
{
return View();
}
//perform some business logic
return RedirectToAction("InquirySubmitted",contactInfo);
}
public ActionResult InquirySubmitted(ContactInfo contactInfo)
{
return View(contactInfo);
}
The problem:
I do not want end users navigating directly to the InquirySubmitted action via the browser.
I only want the ContactUs action in the controller to be able to send users to the InquirySubmitted View.
I have attempted to make the InquirySubmitted action private so that only the controller can call it like so:
private ActionResult InquirySubmitted(ContactInfo contactInfo)
But this produces an error which I fully understand because I am forcing the browser to request InquirySubmitted by using RedirectToAction().
So my question is simply: What is the best "MVC 3 style" solution to this issue.
You will need to put logic in your InquirySubmitted ActionResult in order to prevent users from viewing the page if they are not supposed to.
You are already passing the InquirySubmitted method your model (ContactInfo). Could you simply inspect the data passed to the method and if it is absent then redirect the user to an error page (or some other page of your choice)?
An alternate solution would be to set a boolean in session that indicates that the user completed the "ContactUs" form. Then you could check for that session object within InquirySubmitted.
First, I would have to say.. Who cares if someone can navigate directly to the Inquiry submitted page? Is there any confidential information, or something sensitive there? If not, so what? What does it hurt?
However, if you're determined to do so. The answer to your question of "How to make an action not accessible directly from the browser" is that You can simply use Html.Action() to render the page, and then decorate the action method with a [ChildActionOnly] attribute.
This doesn't actually solve the problem though, since making the action indirectly accessible only answers your question, not solves your problem. Ultimately, you need to redirect the user to a url to load the page, so you will need some logic that determines if they can view the page or not. This is
Not sure if this still applies in MVC3, but in MVC2 it worked.
your global.asax file has your url structuring in it. You can add your InquirySubmitted to the list of urls that isn't accessible there.

Categories