Use RESTful URLs in a non-MVC site - rest

I started the site using AST.NET Razor template, not ASP.NET MVC template.
I recall seeing somewhere on the Internet that even without MVC, it's possible to use RESTFul URLs in the razor-based ASP.NET site. It appears to work without the CHTML extension names right out of the box -- www.test.com/car automatically redirects to www.test.com/car.cshtml.
But, what if I used www.test.com/car/2, how would I get to the "2" inside the View without using MVC? I really hope that's something already baked in.

Found it -- it's in UrlData
http://beta.asp.net/web-pages/tutorials/aspnet-razor-pages/18-customizing-site-wide-behavior
section "How Routing Works"

Look at the WebGet Attribute. It has a UriTemplate.
Example:
WebGet(UriTempate="{Id}")<br>
public JsonResult Get(int Id)
{
}

Related

Running both aspx and .Net Core (.Net 5) webpages on same server and domain

I am about to move a webshop from old webforms to new .Net Core (.Net 5) site.
The old urls have a lot of good rating on google and I would like to be able to make a permanent redirect from an aspx page to .net core page.
Etc.:
www.mydomain.com/products/great-backpack-1234.aspx
to
www.mydomain.com/great-backpack
I believe that requires that I have both .net core and aspx site running on the same domain.
Is this possible?
Or do any one have any other solution ideas?
Best regards
Thats probably not needed to run both on the same domain or space. It seems everything will end in .aspx, and assuming you are using MVC, a controller function to catch-all requests that don't match other routes, then check to see if it ends in aspx, should do it for you. You can put it in an existing controller, but I personally would put it in a new one to separate concerns
public class RedirectController : Controller
{
[Route("{**url}", Order = 999)]
public IActionResult RedirectPage(string url)
{
//Redirect logic based on the URL given, making sure it ends in aspx
}
}
The url would come across in the url parameter as a string and you can check to see if it ends in aspx, and what the page name was to determine where to send them. So "www.mydomain.com/products/great-backpack-1234.aspx" would come across in the url parameter as "products/great-backpack-1234.aspx". Note that the order field in the route attribute assures that it will be the last match checked for patterns, so it shouldn't mess with anything else.

How to configure resetpassword

I am using IdentityServer3 for authentication. Users are stored using AspnetIdentity framework. I wanted to provide reset password functionality to users. I want to provide this functionality in IdentityServer hosting application. I have gone through several posts here here here and this what I have done so far:
1>I have created custom user service derived from AspNetIdentityUserService.
2>Created resetpassword.html and put it in template folder. (documentation)
3>It's not necessary to create a CustomViewService, so I added LoginPageLink in AuthenticationOptions and now the link is available on login page.
4>Created ResetPasswordController
public class ResetPasswordController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ResetPassword(string username)
{
// call customservice here and reset password
return View();
}
}
Issue
when i click on the resetpassword link, i get error
The view 'Index' or its master was not found or no view engine
supports the searched locations. The following locations were
searched: ~/Views/resetpassword/Index.aspx
~/Views/resetpassword/Index.ascx ~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx ~/Views/resetpassword/Index.cshtml
~/Views/resetpassword/Index.vbhtml ~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
I know why the error is, its because we don't have corresponding view in Views folder where MVC framework in looking for. My view resetpassword.html is in template folder. And that's the confusion. Identity server is using Angular to build its views.
If I decide to use angular then
1>How do I create and pass model to resetpassword.html.
2>How do I wire-up my CustomUserService to controller.
If I use ASP.NET MVC then
1>I need to add resetpassword.cshtml in Views folder and also a new Layout.cshtml in shared folder.
2>Doing so MVC scafolding will add bootstrap resources (css,js, jquery). The version may not match with IdentityServer's embedded resources.
I am comfortable coding ASP.NET MVC but worried adding bootstrap resources twice in the solution.
What is the best and easy approach here. Any sample example will be greatly appreciated.

App with no DB: You must call the "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class

First things first. I'm a complete OAuth newbie. This will be my first stab at it, and things are getting hairy...
I'm writing a single page application using Durandal & Web API.
The user needs to be able to login using any social network.
I don't have access to a database whatsoever, I have to call an unprotected 3rd party web service which I consume server-side, and need to protect using OAuth.
So I've managed to add the files to my solution which generates the login using facebook contol/button (created a new MVC4 web application, and did a manual copy and paste of all the auth related files, updated bootstrappers etc..), and the code seems to work for the most part.
When facebook redirects back to
[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(this.Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
if (!result.IsSuccessful)
{
return this.RedirectToAction("ExternalLoginFailure");
}
if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
{
return this.RedirectToLocal(returnUrl);
}
//code removed for brevity ....
}
I get the error specified once the following line tries to execute.
OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false)
I've removed the [InitializeSimpleMembership] attribute from the controller, as I don't have a database.
Please forgive me if this is the dumbest question ever, but...
Why does the login fail? I mean at that point, isn't the app trying to log into facebook, why does it need a databse? Or am I correct in saying I can remove/replace that code section, with a login/authorise call on the web-service I'm using?
Not the dumbest question ever. Not by a long shot. But you are getting the error because your membership provider is still set to use the SimpleMembershipProvider and OAuthWebSecurity will use the default membership provider. If you don't want to use a database you will have to create or find a different membership provider to use.
EDIT:
I know you said you don't have access to a DB but if you can use SQL Compact you can just stick with the default SimpleMembershipProvider(check out Hanselman's blog) or DevArt has a SQLLite provider. Also the MemFlex Project has a RavenDb provider. If none of those work I think you might just have to write your own.

ASP.NET Web API Authorization with AuthorizeAttribute

Using the new ASP.NET Web API beta. I can not seem to get the suggested method of authenticating users, to work. Where the suggested approach seems to be, to add the [Authorize] filter to the API controllers. For example:
[Authorize]
public IEnumerable<Item> Get()
{
return itemsService.GetItems();
}
This does not work as intended though. When requesting the resource, you get redirected to a login form. Which is not very suitable for a RESTful webapi.
How should I proceed with this? Will it work differently in future versions?, or should I fall back to implementing my own action filter?
Double check that you are using the System.Web.Http.AuthorizeAttribute and not the System.Web.Mvc.AuthorizeAttribute. This bit me before. I know the WebAPI team is trying to pull everything together so that it is familiar to MVC users, but I think somethings are needlessly confusing.
Set your authentication mode to None:
<authentication mode="None" />
None Specifies no authentication. Your application expects only anonymous users or the application provides its own authentication.
http://msdn.microsoft.com/en-us/library/532aee0e.aspx
Of course then you have to provide some sort of authentication via headers or tokens or something. You could also specify Windows and use the built in auth via headers.
If this site is mixed between API and actual pages that do need the Forms setting, then you will need to write your own handling.
All the attribute does is return an HttpUnauthorizedResult instance, the redirection is done outside of the attribute, so its not the problem, its your authentication provider.
Finally, I've found a solution at:
ASP.NET MVC 4 WebAPI authorization
This article shows how you can fix this issue.
You are being redirected to login page because forms authentication module does this automatically. To get rid of that behavior disable forms authentication as suggested by Paul.
If you want to use more REST friendly approach you should consider implementing HTTP authorization support.
Take a look at this blog post http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-membership-provider/
ASP.NET 5 Introduced the new Microsoft.AspNet.Authorization System which can secure both MVC and Web API controllers.
For more see my related answer here.
Update:
At that time 2 years ago it was Microsoft.AspNetCore.Authorization.
As #Chris Haines pointed out. now it resides on
Microsoft.AspNetCore.Authorization.
From .NET core 1.0 to 2.0 many namespaces have been moved i think.
And spread functionality between .net classic and core was obscure.
That's why Microsoft introduced the .net standard.
.net standard
Also, look at my answer for:
How to secure an ASP.NET Web API
There is a NuGet package I have created which you can use for convenience.
If you're using a Role, make sure you have it spelled correctly :
If your role is called 'Administrator' then this - for instance will not work :
[System.Web.Http.Authorize(Roles = "Administator")]
Neither will this :
[System.Web.Http.Authorize(Roles = "Administrators")]
Oops...
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Produces("application/json")]
[Route("api/[controller]")]
public class CitiesController : Controller
{
[HttpGet("[action]")]
public IActionResult Get(long cityId) => Ok(Mapper.Map<City, CityDTO>(director.UnitOfWork.Cities.Get(cityId)));
}
Use
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Filter with authentication type

How to RESTful delete record Asp.Net Mvc 2

I have delete links in my Asp.Net Mvc2 application.
/{controller}/Delete/{id}
It seems using link to delete has a security risk. Don’t use Delete Links because they create Security Holes
I found this Implementing RESTful Routes & Controllers in ASP.NET MVC 2.0 but I am not sure how to implement a simple delete functionality using the new HttpDeleteAttribute class.
Are there any examples on deleting, the RESTful approach?
The RESTful approach to a Delete is to send enough information to identify the resource and use the HTTP command DELETE (or some alternative for web pages). But all of that is detailed in the article, so I don't think that's what you're really asking.
If you mean "What do I do instead of a Delete link?", the answer is usually to go to a "Are you sure you want to delete Product 8496?" form where the button's action POSTs the delete request. That form can either be on a new page or a modal popup, or both if you want to combine usability and accessibility.
It's a (more of) a security risk if you dont use the [HttpPost] attribute on the controller.
Besides that, your approach isn't a restful one.
The idea is that you have just one Url that can be passed different Http Verbs which are implicit
Return all: /Product/ [HttpGet]
Return One: /Product/43 [HttpGet]
Add : /Product/ (Product info in form post) [HttpPut] or [HttpPost]
Delete: /Product/43 [HttpDelete]
You can do this using MVC in the standard form or JQuery
And to answer the question:
Add a delete link like this Delete Product but hook into it using the JQuery live events so that it hijacks the click using .preventDefault, then call the url as an ajax request with a DELETE verb.
Need more help let me know