Is it possible to have a single URL that points to two different pages? - c#

I have one url (/settings) that needs to point to two different pages depending on the users security on login. One page is the existing webforms page the other is a new MVC page. Is this even possible?
Additional Info:
When the user is on either page the url needs to say website.com/settings
Solution:
Convinced the PM to change the requirements.

The short answer, yes. You can do this several ways.
Javascript
Model View Controller (Controller)
ASP.NET Web-Forms (Method)
It is often poor practice to do such an event, as it can expose data. It is indeed possible:
Javascript:
$(document).ready(function () {
if($("#Account").val() != '') {
$(".Url").attr('href', 'http://www.google.com');
}
});
Pretend #Account is a hidden field that is populated from your database. If the field is not null then modify the .Url element to navigate to link. That approach for Web-Forms is the most simple.
Web-Forms:
protected void btnAccount_Click(object sender, EventArgs e)
{
if(User.IsInRole("Account"))
Response.Redirect("~/Admin.aspx");
else
Response.Redirect("~/User.aspx");
}
That would use the default Windows Authentication for the domain, you could bend and contort to use the database to pull data. An example, the Model View Controller would be similar as the Controller will simply handle that capability.
Hope this points in right direction.

This is a redirects based approach. Create a web page mapped to /settings, and have this code run on page load.
if(User.IsAdministrator()) //I take it you have some way of determining who is an Admin, so this is just example code
{
Response.Redirect("~/AdminSettings.aspx");
}
else
{
Response.Redirect("~/UserSettings.aspx");
}
Note that you'll need security on the Admin page to make sure a regular user can't just navigate directly there.

Related

Is there a way in a Razor Pages app to change the default starting route to an Area?

When you create an ASP.Net Core Web App with Individual Accounts it adds an Identity Area along with the regular Pages folder.
Since I don't want to be working between the Pages folder along with the Area folder, I want to create a Home Area that my app's default route "/" will route to.
I was able to accomplish this for the Index page by adding this to Program.cs:
builder.Services.AddRazorPages(options =>
{
options.Conventions.AddAreaPageRoute("Home", "/Index", "");
});
Obviously, this just takes care of the single Index page, but if I wanted to have an About or Privacy page, I would have to add AreaPageRoutes for them as well. I tried a couple different things with AddAreaFolderRouteModelConvention that I am too embarrassed to show here, but was ultimately unable to find out how to make it work.
Is it possible and secondly, is it bad practice, to map the default routing of Pages to a specific Area?
You can use a PageRouteModelConvention to change the attribute route for pages in an area:
public class CustomPageRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
foreach (var selector in model.Selectors.ToList())
{
selector.AttributeRouteModel.Template = selector.AttributeRouteModel.Template.Replace("Home/", "");
}
}
}
Generally, my advice regarding areas in Razor Page applications is don't use them. They add additional complexity for no real gain at all. You have already found yourself fighting against the framework as soon as you introduced your own area. QED.
The only place areas serve a real purpose is within Razor class libraries, so you have to live with an area when using the Identity UI. But you don't have to use the Identity UI. You can take code inspiration from it and implement your own version in your existing Pages folder.

Pass and verify data between different razor pages

i'm using Asp.net Core2.1 Razor pages technology.
i want to ask about passing and verifying parameters between razor pages.
please not that i'm asking about the concept not about coding:
now suppose i have blogs, and each blog owned by a user who can manage it.
the user enter the manage page using this url :
https://localhost:44368/blogs/1/settings
as you see, the id of the blog is in the url:
public async Task<IActionResult> OnGetAsync(int? id)
{
// here i check that the blog is exist by the id
// and i check if the current user own the blog
}
then in the settings page i have links for several pages, for example (articles)
and the user can manage these articles.
https://localhost:44368/blogs/1/settings/articles
as you see still i have the blog id in the url :
public async Task<IActionResult> OnGetAsync(int? id)
{
// now this function in the articles page
// again i check if the blog is exist
// and again i check if the current user can manage the blog or not
}
is this correct and good practice ? to check and verify in each page
or should i check only when i enter the settings page ?
or should i think in an approach to check only once when the user enter the settings page, then the user can't enter other pages based on the first check !
It is good practice to keep web endpoints stateless.
So your approach of passing the Id to every child action, and validating this input, is correct.
To implement the other approach where you only check the Id once, you would need to pass state between the actions, e.g. as session state. This approach is less flexible. Maybe you want to be able to open the settings from another page than the blog details someday in the future?
Also remember that just because the user does not see a certain link on a page, nothing prevents her from entering e.g. https://localhost:44368/blogs/1/settings/articles directly into the address bar of the browser. So you will need some from of validation for every action in any case.

Moving data from one web form to another ASP.NET C#

I am trying to move the content of a textbox on the from StudentRegistration to the form MyProfile by following a tutorial on YouTube. However when I try to reference the StudentRegitration Page in my code, I get the error that the type or namespace cannot be found.
In the tutorial I can see that in their code they have a namespace, however my website does not. Could anyone tell me what to do in order to be able to reference StudentRegistration without getting an error?
I should have stated that I have a website not a web app. I have found that websites do not have a default namespace. How would I go about accessing the StudentRegistration without referencing a namespace?
public partial class MyProfile : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
StudentRegistration LastPage = (StudentRegistration)Context.Handler;
lblEmail.Text = StudentRegistration.STextBoxEm;
}
}
}
Rather than answer your question directly, I'd like to point out another issue with your code that will probably prevent it from working. You should refer to the documentation on the PreviousPage property at: http://msdn.microsoft.com/en-us/library/system.web.ui.page.previouspage%28v=vs.110%29.aspx
It does NOT work like this:
user visits /StudentRegistration.aspx
user does stuff
user submits the form on /StudentRegistration.aspx
server redirects the user to /MyProfile.aspx
MyProfile class knows that PreviousPage = the class from /StudentRegistration.aspx
Instead, the description from the msdn reference page linked above stipulates that the PreviousPage property only works on this scenario:
user visits /StudentRegistration.aspx
user does some stuff
user submits form on /StudentRegistration.aspx
server transfers request to the MyProfile class
this does not mean that the url has changed to /MyProfile.aspx for the user, this means that the server is going to treat the current request to /StudentRegistration.aspx as if it were actually a request to /MyProfile.aspx
the user ends up seeing the result of what would normally be /MyProfile.aspx on /StudentRegistration.aspx
Now, your code may actually want that, but the fact that you have:
if (PreviousPage != null)
{
StudentRegistration LastPage = (StudentRegistration)Context.Handler;
// this should be
// StudentRegistration LastPage = (StudentRegistration)PreviousPage;
}
makes me think that you have misinterpreted the somewhat misleadingly named PreviousPage property. For a sample of how to persist state across multiple page loads in .NET, I would recommend reading up on SessionState. It has a somewhat complicated name, but does more of what you would want in this scenario:
http://msdn.microsoft.com/en-us/library/ms178581%28v=vs.100%29.aspx
An added bonus is that you do not need to reference one class from another, so you fix your current bug later on. Additionally, even if you did resolve your potential namespace error, the issue that I outlined earlier will cause the value of the text field to be blank if your code is working as I suspect.
You are sending data from a source to a target - e.g. StudentRegistration -> MyProfile
You have options because at the end of the day, it is HTTP. Aside from "persistence" (Session), and the tutorial you are following, a "simpler" way is to use ButtonPostBackUrl.
All it means is that you are POSTing data to the target page. The target page (MyProfile) will have to validate and parse the posted data (Request.Form). This way you don't have to manage things like Session state.

Inject JavaScript code from asp.net page into html page in another domain

How can I inject a JavaScript code from asp.net page into html page in another domain e.g http://www.codeproject.com/ . how to inject a JavaScript into this html page from my application
I am currently working on making a plugin just like Pinterest when the html page opens from my application it shows a bookmarklet just like Pinterest automatically on the page.
Below is the code I am using to inject JavaScript
public partial class ViewPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string script = "javascript:(function(){var jsdom = document.createElement('script');jsdom.src = 'http://localhost:15064/Script/delete.js';document.body.appendChild(jsdom);})();";
Response.Redirect(Server.UrlEncode(script));
}
}
Below is the Error I get After the execution of above code
Same Original Policy will not allow you to run scripts in someone else's domain.If this did not exist anyone could run scripts in any domain which would be a major security risk.
There are a couple *legal exceptions to this rule which you can read below
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
The only other way to accomplish outside of an agreement with both sides would be a violation of Same Origin and probably illegal.
Xss attacks are pretty common and do what you are describing.
The closest you will probably be able to get is a bookmarklet:
http://www.mattcutts.com/blog/javascript-bookmarklet-basics/
which is basically a shortcut to inline javascript.
An example in the wild is the X-Ray Goggles bookmarklet. You can add it by creating a new bookmark and pasting the location as:
javascript:(function(){var script=document.createElement('script');script.src='https://goggles.webmaker.org/en-US/webxray.js';script.className='webxray';script.setAttribute('data-lang','en-US');script.setAttribute('data-baseuri','https://goggles.webmaker.org/en-US');document.body.appendChild(script);})();
This won't let you inject from your application but it is a way of injecting into a doc from your browser.

MVC OutputCache based on Session values

Is it possible to vary the output cache in MVC based on certain values in the session? I've read a lot about using the varybycustom functionality and overriding GetVaryByCustomString in Global.asax but the session is not available at this point.
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (custom == "somekey")
//Want to check the session here (but it isn't available).
return base.GetVaryByCustomString(context, custom);
}
I understand this is because the Session isn't created until later in the request pipeline.
My concern is that without varying the cache based on the user's session, the page (which changes based on what the user has in the session, has additional HTML specific to that user etc) will get cached (as the URL is the same) and served by our load balancer, proxy servers etc. and then served to other requests with other people's session information on the page!
The reason the URL is the same is that the user comes in as a 'guest', enters some information (POST), this is validated and stored in the session and then they are re-directed back to the same page (which should now be specific to the user based on the session data).
The page itself should be cached normally because if a 'guest' visits the same URL, it should serve the same 'standard' page every time.
Is is possible to vary the caching in this way?
If you want to personalize the cache output per user, it is better you set the Location to OutputCacheLocation.Client as below. More information here
[OutputCache(Duration=3600, VaryByParam="none", Location=OutputCacheLocation.Client, NoStore=true)]
public string GetName()
{
return "Hi " + User.Identity.Name;
}
Would a Output Cache ActionFilter help at all?
Or perhaps you could refactor your view in to a layout page plus partial views for anonymous and authenticated sections, then utilize Partial Caching.
You should look into "Donut Caching", but this isn`t supported by ASP.NET MVC 3, at least not out of the box. Fortunately somebody already solved this problem for you see MvcDonutCaching
I read that ASP.NET MVC 4 will include "Donut Hole Caching" out of the box, but i cant tell if it's in the current RC or not.

Categories

Resources