Building querystring in routing webforms .net 4.0 - asp.net

I'm trying out .net 4.0 routing with Webforms for the first time and I'm running into a problem. The page I'm routing to is looking for a querystring based on the route url.
For Example:
routes.MapPageRoute(
"Rule2", // Route name
"news/{day}/{month}/{year}/{.*}.aspx", // Route URL
"~/mynews.aspx" // Web page to handle route
);
I want the final route to send mynews.aspx?story={day}{month}{year}. But I can't figure it out. I found this to be some help http://msdn.microsoft.com/en-us/library/cc668177.aspx but request.querystring("story") gives me nothing.
Any words of wisdom?

Normally you wouldn't have 'aspx' in the route URL because you'd want a user friendly one. So, the route URL would be "news/{day}/{month}/{year}/{.*}" and a valid URL 'news/25/5/2012', for example.
Then to access the data you use
string day = (string) RouteData.Values["day"].

Related

Restrict Direct Pathing

I have a project in VS 2015. There is a page called home-program.aspx.
This is the route I set up for that page:
Dim sDestinationRegExp As String = "^(world|land|line|run|club)${2,}"
routes.MapPageRoute("landing", "destinations/{destination}", "~/home-program.aspx",
True,
New RouteValueDictionary(New With
{.destination = "world"}),
New RouteValueDictionary(New With
{.destination = sDestinationRegExp}))
Now, the route works. However. the user is still able to access that page by using /home-program or /home-program.aspx. Is there a way to prevent them from accessing those pages using those urls and instead use the mapped route instead?
I suspect you can add a "catch-all" route at the tail-end of the route mapping that will map everything to a 403 or 404 page (whatever you think is best).
This answer shows how to create a catch-all route mapping. Make sure it is at the end of the maps -- the last thing you add.
This should prevent the rest of the pipeline modules from trying to process the URLs. Another IIS module (from ASP.NET) will get invoked by default if your route maps don't match a URL. This is how the request for /home-program.aspx gets handled. If you handle it with a route map entry, the default module shouldn't interfere.

Html.RouteLink to a Web API Route - possible?

My site is largely a suite of web services exposed via the Asp.Net Web API. There are also pages, designed to support the webservices (testing etc), written in Razor (and implicitly Asp.Net MVC 4).
For the XML versions of the webservices I have a schema-export action (uses the XsdDataContractExporter) which is picked up by my standard API route (although note - I've flipped the precedence of the Web API and Pages):
//page routes
routes.MapRoute(
"Default", // Route name
"pages/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional
} // Parameter defaults
);
//an additional route for my Schema controller action
routes.MapHttpRoute("XSD", "schema.xsd",
new { controller = "schema" });
//API Catch-all Route
routes.MapHttpRoute("APIMain", "{controller}/{id}",
new { id = RouteParameter.Optional });
Now on a razor page I want to emit a link to the 'friendly' schema URL ~/Schema.xsd. Anticipating issues with route discovery I immediately went for hitting the route directly by name:
#Html.RouteLink("Schema", "XSD");
However this just emits a link equivalent to ~/.
I've tried some other combinations of route values - but it appears MVC's HtmlHelper and UrlHelper simply don't want to pick up Web API routes.
I'm sure if I cracked open the source of Asp.Net MVC 4 I'd find the reason - but I'm hoping somebody already knows, and since I can't find another SO about such cross-linking I figured it'd be a good addition to the SO library.
I should add that browsing to ~/Schema and ~/Schema.xsd do correctly display the XML schema produced by the API action.
Update
Post-RC a method was added to MVC's UrlHelper, HttpRouteUrl, which does exactly the same thing I suggest here in this answer. This is my discussion thread over on CodePlex where I was told this. So there is no need for you to use the magic string mention here in generating links to Web API routes.
Original answer
I've managed to get it to work - although it might not by the time MVC 4 is RTMd (disclaimer disclaimer!)
I changed my Html.RouteLink call as follows:
#Html.RouteLink("XML request schema", "XSD", new { httproute = true })
I didn't originally intend to answer my own question straight away - but having done some research I found an answer.
First I verified that the HtmlHelper's route collection is the same as the RouteTable.Routes collection (i.e. contained all routes).
Following the call-chain through, I remembered having trawled through the current Web API and page MVC 4 source code from CodePlex, that HttpRoutes (in System.Web.Http.Routing) need a 'hidden' route value to be added otherwise they will never match. Here's the source code from lines 21-25 of HttpRoute class (correct as of 8th June 2012 source):
/// <summary>
/// Key used to signify that a route URL generation request should include HTTP routes (e.g. Web API).
/// If this key is not specified then no HTTP routes will match.
/// </summary>
internal const string HttpRouteKey = "httproute";
A bit of further analysis of the code showed that it expects this route value to be a boolean.
Clearly, this is something that can be turned into extension methods - perhaps Html.HttpRouteLink (and Html.HttpActionLink) - with extra extensions on UrlHelper for hiding the magic string for the route data value.

Accessing Query string in postback event while using URL rewrite 2.0 in asp.net 4.0

I am in a trouble working with URL Rewrite 2.0 (in IIS7) for Web form web-app. In application there are job postings whose URL was not earlier SEO friendly and not in readable form as
*"http:www.mySite.com/candidate/JobDetails.aspx?ref=h_hj&JobPostingID=10049"*
I wrote Inbound Rule for that page i.e. for JobDetails.aspx as
Pattern to match: ^candidate/JobDetails\.aspx$
Conditions : {QUERY_STRING} and pattern: ^ref=([^=&]+)&JobPostingID=([^=&]+)$
Action : type: Rewrite and Rewrite URL: {C:1}/{C:2}
And it gave me new url string as
http://www.mySite.com/h_hj/10049
Now the problems are
1) I am unable to get query string values from URL as it is giving me problem during post back event as "Input string was not in a correct format."
if (!string.IsNullOrEmpty(Request.QueryString["JobPostingID"]))
return Convert.ToUInt32(Request.QueryString["JobPostingID"]);
2) How to hide referral query string parameters only from URL as "ref" in my case.
Access your RouteData variable using RouteDataand Also refer this link Asp.net Routing
int JobPostID= Convert.ToInt32(Page.RouteData.Values["JobPostingID"]);
// do Some fun with your JobPostID

Returning Requested URL within Custom Error Page in ASP.net

Working in ASP.net 3.5 and MVC 1.0.
What I would like to do is return the requested URL, which generates a 404 error, within the custom error page. Much like Google does on their error pages (http://www.google.com/test).
eg.
We're sorry, but the requested address "http://www.domain.com/nonexistantpage.aspx" does not exist on this server.
What would be the best way to accomplish this kind of soft 404?
Also, as a side note: Anyone familiar with returning the custom error page in place of the ugly ...notfound?aspxerrorpath=/awdawd nonsense, while keeping the requested URL in a browser's address bar? ...I suspect something to do with a server.transfer?
Check out these resources related to this topic:
ASP.Net MVC Custom Error Pages
Three common ASP.NET MVC URL routing issues
To summarize, you can accomplish a google-like implementation with keeping the requested URL by defining a catch-all route that executes a particular controller action.
//defined below all other routes
routes.MapRoute(
"Catch All",
"{*path}",
new { controller = "Error", action = "NotFound" }
);
public ActionResult NotFound(string path)
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
ViewData["path"] = path; //or Request.Url.ToString() if you want full url
return View();
}
This is not a complete solution, though. Assuming you've left the default route mapping, anything that matches {Controller}/{action}/{id} is still going to a throw a traditional 404 or custom error. You'd have to explicitly define all possible routes if you truly wanted to have the catch-all route pick up anything that didn't map to a specific controller/action or parameter type - not necessarily a trivial task.

Asp.Net MVC routing diffrence in www.Mysite.com/Employee and www.Mysite.com/Employee/ while using JqGrid

I am using ASP.NEt MVC for one of my project.
In this I have Employee controller which can be called by www.Mysite.com/Employee/ url.
Also I have used JqGrid which uses followng to fetch data
url: "GetGridData"
While testing the same I found that
If i type www.Mysite.com/Employee/ in browser a call is made to
www.Mysite.com/Employee/GetGridData
If i type www.Mysite.com/Employee in browser a call is made to
www.Mysite.com/GetGridData
Note: the missing / at the end in second call.
How to rectify this as the chances are end user can type any of this url in browser.
I'd take a look at how you're asking JqGrid to make it's web service call - because it won't know anything about MVC's routing engine by default - and this is all happening client side.
Stepping outside of MVC for a minute, if I have a page:
example.com/page1.aspx
And have a relative link to another page on there:
Click here
The browser will look for page2.aspx at the same level as page1.aspx, i.e.
example.com/page2.aspx
If I move page1 to a new folder:
example.com/NewFolder/page1.aspx
The browser will ask for
example.com/NewFolder/page2.aspx
when a user clicks on the link.
The same thing is happening to your GetGridData call - these are being made by the web browser to your server based on the information it has available to it.
So if your page responds on:
example.com/Employee
And asks for a relative request to:
GetGridData
The browser will send that request to the same level that Employee appears to be on:
example.com/GetGriddata
Which then fails because the routing engine can't find a route for that request.
You should look at generating the URL for the GetGridData call dynamically through the routing system, which will ensure that it's built as:
url: "/Employee/GetGridData"
Final edit to add
Forgot to mention, you should probably use the UrlHelper Action methods for this:
url: <%=Url.Action("GetGridData")%>
This will generate a path to the GetGridData method on the current controller. If you need to access a different controller, or pass some values, there are overloads to help.
Try debugging your route:
Phil Haack's: ASP.NET Routing Debugger

Resources