Is it safe to use DateTime.Now as a default route value in ASP.NET MVC? - asp.net-mvc-3

I have the following in an Area Registration of my ASP.NET MVC 3 project running on .NET Framework v4.0:
context.MapRoute(null,
"YardJob/{location}/{from}",
new { controller = "YardJob",
action = "List",
from = DateTime.Now });
My question is:
If the routing engine uses the default route value for 'from', will the List method on the controller always be invoked with the current date and time?
Is there any caching in the routing engine that may cause the default route value to be reused among requests?
Thanks,

As the accepted answer explains, this isn't possible. However, for the sake of completeness, here is how you would work around this:
Route:
context.MapRoute(null,
"YardJob/{location}/{from}",
new { controller = "YardJob",
action = "List",
from = UrlParameter.Optional }
);
Controller action:
public ActionResult List (string location, DateTime from)
{
if (from == null)
from = DateTime.Now;
}

the process of register the routes is executed when the application starts, so if you put DateTime.Now the default parameter for from field would be the time when the application starts, change only when the AppPool recycles
when application starts?
when the first resource (such as a page) in an ASP.NET application is requested. The Application_Start method in Global.asax is called only one time during the life cycle of an application. You can use this method to perform startup tasks such as loading data into the cache and initializing static values.
check out the life cicle

Related

View from custom controller overriding default view

I'm using orchardcms 1.9 (no tag created jet). I am writing a custom module that implements its own controller that calles a service wich check some information and based on the service response I either redirect or let the user stay on the page.
The module is on the default layer in other words it is on everypage. So when user tries to log in or register this module checks information normally.
This is my route:
new RouteDescriptor {
Priority = -1,
Route = new Route(
"{*path}", // this is the name of the page url
new RouteValueDictionary {
{"area", "modulename"}, // this is the name of your module
{"controller", "controllername"},
{"action", "Redirect"}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"area", "modulename"} // this is the name of your module
},
new MvcRouteHandler())
and this is my controller:
public ActionResult Redirect()
{
String response = _authService.VerifyRegistration(_orchardServices.WorkContext.CurrentUser);
if (response.Equals("2"))
{
Response.Redirect("~/Registration");
}
else if (response.Equals("3"))
{
Response.Redirect("~/Users/Account/LogOn");
}
return View();
}
What happens is that when I go to registration or login controller triggers, checks the infromation, says no redirect needed then returns view. But because the view is empty my page is blank instead of its default login/registration form.
How can I solve this? Am I making a mistake in routing that I somehow override the default view (I tried different priorities but same response).
Your route overrides all routes ({*path}. So when you redirect, you redirect to....your redirector I guess. Therefore the view you are rendering is the one for your controller, not the page you were after.
Whatever the logic flaw - this is not a good way to globally control authorization type scenarios on your site. If you meant to have a single page that people might go to (e.g. http://www.mysite/welcome) then your problem is that your route is too global. However, if, as your code suggests that you want to create a "all pages" check to see if you should go to login or register, then you should implement an authorization filter. An example of an authorization filter (for a slightly different purpose) can be found at https://stackoverflow.com/a/30377097/1638254 . You are looking to fill in the OnAuthorization method with suitable code to redirect the user (or let them through

Web API 2 - Unity IOC - Shared instance per request variable

I am using web api with unity IOC.
web api client passes client-id in request header and based on this value dependencies are resolved to create a external dll's method instance.
creation of this instance take around 6-7 seconds which is creating performance issues in web api.
What I want is to prevent instance creation for call with same client-id in header.
This is how I have implemented till now:-
//========================== ArchiveFactory ==========================
ArchiveFactory archiverFactory = (HttpRequest httpRequest) =>
{
container.RegisterType<IArchive, Archive>("Archive",
new HierarchicalLifetimeManager(),
new InjectionConstructor(
new ResolvedParameter<IStoreClient>(),
Helper.GetArchiveContext(httpRequest))
);
return container.Resolve<IArchive>("Archive");
};
container.RegisterInstance(archiverFactory);
To be specific in my requirement - I am calling amazon services to retrieve images and there is a corporate dll which invokes amazon.
You can use caching mechanism at the controller/API layer(e.g Strathweb.CacheOutput.WebApi2) and you can decorate the controller method like this below. It's can cache based on parameter so if request comes in with same parameter, it will return results from cache.
[HttpGet]
[Route("")]
[CacheOutput(ServerTimeSpan = 60, ExcludeQueryStringFromCacheKey = true)]
public IHttpActionResult GetProducts(string clientId)
{
var product = new List<Product>();
return Ok(product);
}
Also, you might want to check the class constructor that you are trying to instantiate for issues that is taking it too slow. You may want to consider using lazy loading too if that will apply.

ASP.NET MVC Routing - Thousands of URL's

My ecommerce application stores URL's for item pages in the database. There are thousands of these URL's, which are all root level (i.e. domain-name.com/{item-page-url}).
If I add all of these URL's to the route table by using a simple for loop to call RouteCollection.MapRoute for each URL site performance degrades exponentially. Why? The reason for this is here.
How should I properly handle this situation? Adding all of the routes to the route table doesn't seem right (not to mention the performance pretty much confirms that). I've seen a few ideas about inspecting all incoming URL's and then trying to match that to the URL's in the database but don't fully understand how I'd implement that, nor am I sure if it's the best approach.
Any ideas or suggestions? This seems like it would be not so uncommon, but I haven't found a concrete way to handle it.
If you can change your route to
mycreativeshop.com/product/my-product-name then adding following route to the top of your route config file can help you.
routes.MapRoute(
"CustomRouteProduct",
"product/{id}",
new { controller = "yourcontrollername", action = "Index" }
);
and in the action map the parameter value with name of your product name
public ActionResult Index(string id)
{
//var prdName = id.Replace("-", " ");
//look up prdName in database
return View();
}
Update
Added following as a top route
routes.MapRoute(
"CustomRouteProductZX",
"{id}",
new { controller = "Content", action = "Index" }
);
and by accessing http://localhost:12025/Car-Paint I was directed to Index action of ContentController where I accessed "Car-Paint" in parameter id
But, above having above blocks patterns like http://localhost:12025/Home/ (here Home is also treated as a product)

Generating url for a resource in asp.net web api outside of ApiController

Looking for a way to construct or generate a url for a specific resource in asp.net web api. It can be done in the controller since it inherits from ApiController hence you get the UrlHelper.
I am looking to construct resource url out of the context of the ApiController.
Here is what I did:
Requires HttpContext/Request, so might not work in Application_Start.
Only tested in WebApi 1
Only works for routes registered in GlobalConfiguration (but if you have some other one, just pass it in instead)
// given HttpContext context, e.g. HttpContext.Current
var request = new HttpRequestMessage(HttpMethod.Get, context.Request.Url) {
Properties = {
{ HttpPropertyKeys.HttpConfigurationKey, GlobalConfiguration.Configuration },
{ HttpPropertyKeys.HttpRouteDataKey, new HttpRouteData(new HttpRoute()) },
{ "MS_HttpContext", new HttpContextWrapper(context) }
}
};
var urlHelper = new UrlHelper(request);
What about the UrlHelper classes:
System.Web.Http.Routing.UrlHelper;
System.Web.Mvc.UrlHelper
The MVC one has some useful static methods accepting routing information or it can be used as an instance created by passing in a RequestContext (which is available in most MVC filters and various other places). The instance methods should be exactly what you need to generate urls.
The HTTP one accepts a ControllerContext (which is also available in most HTTP filters and various other places).
I'm not sure about the ApiController, as I haven't used it before. This may then be redundant for you, but then again, it may not be. Check out your Global.asax.cs file, specifically the RegisterRoutes function. Initially, you should see the following mapping:
routes.MapRoute ("Default", "{controller}/{action}/{id}", new { controller = "MyController", action = "Index", id = "" });
So by default your application is set up to handle routes in the following format:
{ControllerName}/{ActionName}/{ResourceId}
A controller class set up like the following should enable you to receive requests in that format.
class {ControllerName}Controller : ApiController
{
public ActionResult {ActionName} (string id)
{
// fetch your resource by its unique identifier
}
}

Delete Action not working MVC 3

Route I have defined is:
map.Route(new Route("Cars/{id}/Delete",
new RouteValueDictionary(new { controller = "Car", action = "Delete"}),
new MvcRouteHandler()));
In my view I've got:
Delete
Which when run tries to send a request to http://oursite/Car/122/Delete
My delete action in this Car controller looks like this:
public ActionResult Delete(int id)
{
//code is here
}
I noticed a couple things:
If I run this same code locally via my PC, the delete works flawlessly and is able to get to my action method. I'm running this over IIS 7 / Win 7
On our dev server, it's setup obviously via IIS7 but this route fails and says it can't find the route on our route table. But this is the SAME route table class I am using locally...so why would I get this:
No route in the route table matches the supplied values.
But why would that not work on a dev server? I see the setup identical in IIS for the most part as far as I can see when I compare my local setup to the server's.
I noticed that also whether localhost or server, if I try and put an [HttpDelete] attribute on my delete action, it doesn't find my action method and I get an error saying it can't find that method. So not sure why when I take that off, the delete works (localhost only)
Use a helper to generate your link:
#Html.ActionLink("Delete", "Delete", "Car");
The first parameter is your link text, the second is your Action method name, and the third is your Controller name.
See this MSDN Reference on ActionLink().
Could you please share code for the View. How do you build the 'a' tag in the view?
Regarding the [HttpDelete] attribute, it means that the method needs the HTTP 'DELETE' request. The 'a' tag always has a GET request.
Please refer this link
I think you answered your own question. There is no route in the route table that matches your supplied values. You could write that route to do that by writing this in your Global.asax.cs file:
public class Global : System.Web.HttpApplication
{
protected void Application_Start()
{
// Specify routes
RouteTable.Routes.Add(new Route
{
Url = "[controller]/[id]/[action]",
Default = new { controller = "Car" },
RouterHandler = typeof(MvcRouteHandler)
});
}
}
Or, you can use existing routes (my personal recommendation) to use the Delete function in your Car controller. To do that, try switching your code to this:
Delete
First name that route
map.Route("DeleteCar",new Route("Cars/{id}/Delete",
new RouteValueDictionary(new { controller = "Car", action = "Delete"}),
new MvcRouteHandler()));
Then
Delete
Unless that link goes to a warning screen, I strongly suggest that a delete should be a POST or even a DELETE(I think it can be set via ajax)
There's likely a difference in the URL paths between localhost and oursite. The path "/Car/#Model.Id/Delete" is hard-coded, not resolved and may not work in all environments. As suggested in other answers, use an MVC helper like #Html.ActionLink or #Url.RouteUrl to resolve the path for the local environment.

Resources