How to RESTful delete record Asp.Net Mvc 2 - rest

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

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.

Workaround for more REST verbs

I'm developing a game website where accounts have characters. I'm using the routes:
account/{action} //execute `action` on the current account
character/{name}/{action} //execute `action` on specific character
But I need to delete and undelete (they are soft-deleted) characters, and while using a form is the right way for delete, it becomes unnecessary (is it?) bloat when I can use just a GET link to character/{name}/delete. Also, there is no verb for undeleting/restoring.
What is the correct and easy way (or both if there isn't the perfect way) to workaround this?
You could have a RESTful version if your URLs have nouns instead of verbs, such as :
character/{name}/achievements or
character/{name}/travels
To solve your active/inactive account problem, you could do :
GET/PUT account/activity
Already not restful, in which you are determining the action based on the route, not based on the verb. So that said, make a new route that is undelete (i.e. character/{name}/undelete), your already not REST so another route shouldn't matter. If you are looking for RESTful then the route should stay account/{character} and the verb determines the action(i.e. GET,PUT, POST DELETE to the same route). Now since you are not actually deleting, I would learn towards a POST (or perhaps PUT) for both i.e. updaing the entity to delete (or inactive), or updating it to undelete (active again)

RESTful URL for search vs admin

I have a scenario where I have to either
Pull the data from backend as search
Pull the same data from backend to administrate
The URLs I am using are -
/cars
/cars/management
The search can be then subsequently filtered as
/cars?color=blue
The concern that I have is that management is not a resource - it is actually an action. The management page contains links for other functionality associated with car management [add a car/delete a car/list cars/modify cars etc]
Has somebody else faced this issue? Can you let me know your solution?
There is nothing wrong with having a management resource that is a page showing management options for cars. Just because "cars" is the only thing in your database doesn't mean that is the only resource you can present to the user. You could have a resource that is just a form to pick a color (that makes a POST or PUT to the car resource). You could have a resource that is just a form to fill out the address you want the car delivered to. You could have a resource that is just a check box whether you want leather seats or not. You can have as many resources as you like and that make sense, even if all the resources are are pages with forms or links back to the car resource.
Just don't put any verbs in your URLs. You should still be using state transfer using HTTP verbs to change the state of the resources. Don't have a link like
GET /cars/123/deleteCar
on the management page. Instead there might be a link on the management page that (probably using Javascript since browsers have poor native support for HTTP verbs) performs a HTTP request along the lines of
DELETE /cars/123
when the user clicks the link. Something like jQuery can help with that. So long as the management page is using the HTTP verbs to change the state of the resources you are following REST since HTTP is a REST constrained protocol. REST doesn't say don't have actions, it says the actions should be constrained to state transfer.
There is no such concept as a "RESTful URL";
There is no issue with your URLs(/cars, /cars/management)
"/cars/management" is valid resource and it is not an action at all.
The RESTfull way to do this is to use the same URL with different HTTP verbs:
GET /cars for search/listing.
POST /cars for insert.
PUT /cars?id=123 (or /cars/123) for update.
DELETE /cars?id=123 for delete.

Use RESTful URLs in a non-MVC site

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)
{
}

Question regarding fine-grained authorization and MVC2

Background: Completely new to MVC2. Has C# experience, but limited web experience.
I need more fine grained access than simply assigning a Role to a user. The user may have the role at 0+ points in a tree.
/
/Europe
/England
/France
/USA
For example, a user might be moderator of all forums under "Europe" and have access to posting news in France.
The two example controllers have actions as these:
ForumController:
public ActionResult DeletePost(int id) { ... }
NewsController:
[HttpPost]
public ActionResult Post(int treeID, ...) { ... }
How should I approach this? From what I gather Membership+RoleProvider cannot do this level of fine-grained control.
Previously I have written custom user/role/auth system which supported all this, but it was incompatible with "the standard" controls such as LoginView.
The goal would be to have roles allowing access like so:
NewsAdmin
Add news
Edit news
Delete news
NewsPoster
Add news
Therefore, the Post action of News controler should check: Does user have "Add news"-access where he is trying to post?
I would really like to somehow specify this using attributes, so the actual action code could be cleaner and just assume that the caller has appropirate access.
Hope the question makes sense, and I can get some pointers on where to read.
(Oh, and I'm sure this question has been answered in some variant before. I just can't seem to find it. I won't mind single-link replies, if you feel they might be helpful to read)
I think you're being too quick to dismiss the role provider. If a user had a role called NewsAdmin_Europe_AddNews that would pretty much answer the question, wouldn't it?
Once you've made your authentication scheme work with the role provider, you need to tie that into MVC. Subtype AuthorizeAttribute and override AuthorizeCore. Warning: Your code here must be thread-safe and re-entrant. Call base.AuthorizeCore and then test for the specific role based on the URI/query (you won't get route values since this can be served from cache, bypassing MVC altogether).
This is some work, but will be more secure in the end than trying to reinvent membership.