MVC3 parameter use by layout - asp.net-mvc-3

I have a custom section that uses a custom layout. This section is dynamic and all the actions will receieve a YEAR parameter. I don't want setup navigation via section from inside the views. What would be the best way to get this parameter in a navigation action utilized by the layout? If the year is in the URL as ?year=2012 then I can get it via query string. My problem is that this may be in there as controller/action/2012. How can I get the year now in navigation action?

controller/action?year=2012 and controller/action/2012 are basically same if you have defined your route as
{controller}/{action}/{year}
In the action
public class MyController:Controller
{
public ActionResult MyAction(int year)
{
:
:
:
}
}
If you have defined above route along with the default route ( {controller}/{action}/{id} )
Both the url MyController/MyAction?year=2012 and MyController/MyAction/2012 will be treated equally.

Related

Web Api Routing: Multiple controller types were found that match the URL for parameter VS constant paths

My issue is similar to Web Api Routing : Multiple controller types were found that match the URL but I want to keep them in separate controllers.
From the comments, 2 preexisting answers are good workarounds but do not solve the actual issue I'm trying to resolve.
The URLs I'm making up are similar to nested directories in a file system OR are very similar to Firebase URLs.
/BiggestSet/{BiggestSetCode}/Subset1/{Subset1Code}/SubsetOfSubset1/{SubsetOfSubset1}
... etc all the way down to where ever the tree stops. Think of it as a tree of data.
/Collection/{Instance}/Collection/{Instance}
The issue I have is that at the /Collection level I want to also provide specific collection level operations. Like Add and search and other collection specific Operations Collection/ProccessData
Collection Controller:
/Collection/Add
/Collection/ProcessDataOnTheColleciton
Instance Controller:
/Collection/{InstanceCode}
/Collection/{InstanceCode}/ProcessOnTheInstance
The problem I'm having is the Collection/ProcessData clashes with the instance Collection/{InstanceCode}
NOTE: 1 is an parameter and the other is a constant.
If you setup the controllers so that collection and Instance are in the same controller. the /{InstanceCode} doesn't clash with the /ProcessData
BUT
If you setup so the controllers are split into logical functions WebAPI gives the error Multiple controller types were found that match the URL.
Does anyone know how to modify attribute routing to somehow behave as if they are in the same controller OR to prioritize the constant over the parameter across controllers?
To keep two separate controllers and still have such routes you can use regular expression route constraints. This way you can specify for the instanceCode you accept everything except the actions from the other controller.
Here is a sample of how to configure routes like that:
public class CollectionController : ApiController
{
[HttpGet]
[Route("Collection/Add")]
public string Add()
{
return $"CollectionController = Collection/Add";
}
[HttpGet]
[Route("Collection/Process")]
public string Process()
{
return $"CollectionController = Collection/Process";
}
}
public class InstanceController : ApiController
{
[HttpGet]
[Route("Collection/{instanceCode:regex(^(?!Add$|Process$).*)}")]
public string Get(string instanceCode)
{
return $"InstanceController = Collection/{instanceCode}";
}
[HttpGet]
[Route("Collection/{instanceCode:regex(^(?!Add$|Process$).*)}/Process")]
public string Process(string instanceCode)
{
return $"InstanceController = Collection/{instanceCode}/Process";
}
}
Here is also a link to the post that explains the regular expression used in the sample.
An even better option would be if you have a specific format for the instanceCode and set the regular expression to accept only this specific format. Then you would not need to modify the regular expression for every new action added. I include also a link to the documentation for all available Route constraints. There you can see all the available options. For example if your instance code is a number you don't even need a regular expression you can just restrict with the int constraint like this [Route("Collection/{instanceCode:int}")].

How to make my codigniter url seo friendly

How to make my codigniter url seo friendly.
this is my url
http://localhost/picker2/web/search?category=doctor
i want url like this
http://localhost/picker2/web/search/doctor/
read this article www.askaboutphp.com/58/codeigniter-mixing-segment-based-url-with-querystrings.html
to create url like this : http://heloo.com/article/codeigniter-based-url
add this code in routes.php
$route['article/(:any)'] = "article/readmore/$1";
description :
article : class name
readmore : method from class article
$1 : get value from uri segment 2 value
Actually you have two options
1) Using Routes (this one already denyptw discussed right ?)
2) use the URL Helper url_title function
Note : You can use Parameter instead of query string
http://localhost/picker2/web/search?category=doctor
http://localhost/picker2/web/search/doctor/
web controller , search function , doctor parameter
example :
class Web extends CI_Controller
{
public function search($value)
{
//use this $value in your searching logic
}
}
You need Example of URL Helper
check this link Codeigniter URL: How to display id and article title in the URL
you can do this using routes.(Elislab)
as a simple trick.(Using Controllers)
each and every page create a controller. (ex: if contact create contact controller, if product create product controller.) So each and every link will be look like(if you click product) www.example.com/product,(if you click contact) www.example.com/contact.
If you want something to do with your product then write that method inside the product controller.(ex if you create cart then URL show www.example.com/product/cart )

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)

ASP.NET MVC 3 won't recognise .cshtml view files

I have ported an mvc 3 app from vs 2010 to vs2012.
The ported app is using .NET 4.
All the old bits work, but with a new view, created in vs 2012, the view engine is not looking for .cshtml files for the view.
For example, when the user requests the index action on the Welcome controller in the Solicitors area, the url is:
mysite.com/solicitors/welcome/gg
(where gg is the user name). In that case, the error that comes back is:
The view 'Index' or its master was not found or no view engine
supports the searched locations. The following locations were
searched: ~/Areas/Solicitors/Views/Welcome/Index.aspx
~/Areas/Solicitors/Views/Welcome/Index.ascx
~/Areas/Solicitors/Views/Shared/Index.aspx
~/Areas/Solicitors/Views/Shared/Index.ascx ~/Views/Welcome/Index.aspx
~/Views/Welcome/Index.ascx ~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx ~/Areas/Solicitors/Views/Welcome/gg.master
~/Areas/Solicitors/Views/Shared/gg.master ~/Views/Welcome/gg.master
~/Views/Shared/gg.master ~/Areas/Solicitors/Views/Welcome/gg.cshtml
~/Areas/Solicitors/Views/Welcome/gg.vbhtml
~/Areas/Solicitors/Views/Shared/gg.cshtml
~/Areas/Solicitors/Views/Shared/gg.vbhtml ~/Views/Welcome/gg.cshtml
~/Views/Welcome/gg.vbhtml ~/Views/Shared/gg.cshtml
~/Views/Shared/gg.vbhtml
I have already added the following key to appsettings in web.config, but it makes no difference.
<add key="webpages:Version" value="1.0" />
EDIT:
Route in SolictorAreaRegistration.cs:
context.MapRoute(
"Solicitors_Welcome",
"Solicitors/Welcome/{nameUser}",
new { controller = "Welcome", action = "Index", nameUser = UrlParameter.Optional }
);
EDIT 2:
Using RouteDebug, I can see that the correct controller and action are found.
Route Data
Key Value
nameUser: gg
controller: Welcome
action: Index
Data Tokens
Key Value
Namespaces: System.String[]
area: Solicitors
UseNamespaceFallback: False
EDIT 3:
The route is found correctly, as I can see from debugging: the Index action is hit.
The problem happens when the line call the view is called:
namespace MyApp.Areas.Solicitors.Controllers
{
[Authorize]
public partial class WelcomeController : Controller
{
//
// GET: /Solicitors/Welcome/
public virtual ActionResult Index(string nameUser)
{
return View("Index", nameUser);
}
}
}
OK, got to the bottom of it:
The Problem:
The problem is that the model of my view is of type string. In my action, I was passing in a string as the model parameter:
public virtual ActionResult Index(string nameUser)
{
return View("Index", nameUser);
}
This will clash with one of the overloads of Controller.View(...):
View(string, string)
The second parameter expects the name of a layout file. When you do this, MVC goes off looking for a layout file with a name of the value of your string, which could be, for example:
"Hello, World. I'm an idiot, but if you give me a decent error message, I might be able to fix the bug."
Obviously, a layout file with that name doesn't exist. Nor does a layout file called "gg" either (my (test) solicitor's username).
The Solution:
The solution is simple:
Specify that the second parameter is the model, not the layout.
public virtual ActionResult Index(string nameUser)
{
return View("Index", model: nameUser);
}
Useful Article:
To view an extended discussion of this very issue, see the following article:
MVC Gotcha: Beware when using your view's model is a string
Many thanks to heartysoft.com for the enlightenment.
It is looking as you can see from the error message:
~/Areas/Solicitors/Views/Welcome/gg.cshtml
If you need to look for the Index view then you need to specify it:
http://mysite.com/solicitors/welcome/index/gg

MVC3 URL Parameters

I have some parameters in URL, which I would like to be present in the URL for all pages in my MVC3 app. For example:
mycompany.com/home?param=1
mycompany.com/cart?param=1
mycompany.com/logout?param=1
Whether the user is navigating to a new page or submitting a form, how can I have my parameter
be present in all my pages? Right now the only way I can think off is somehow reconstruct the URL for every new view I need to render. Is there built in functionality in MVC to do this?
Thanks
That sounds like something you should store in Session instead of updating all of your links to add the same parameter.
You could use a Session variable as the other poster suggested, or you could use a base view model which holds this static param value.
So your base view would be something like this:
public class BaseViewModel
{
public static int ParamValue = 1;
}
then in each view model you use for each view, you'd have something like this:
public class PageViewModel : BaseViewModel
{
// properties
}
This way, in each view, you can just reference #Model.ParamValue whenever you need to access it:
#Model Namespace.PageViewModel
My param value is <b>#Model.ParamValue</b>

Resources