Getting canonical url based on route data from outside MVC project - c#

I have a MVC4 project and I have an external project that sends emails out that refer to areas of the site.
Rather than hardcoding urls into the emails I want to be able to make sure that I get the canonical url from the routing. I can reference the MVC project which means I believe I should be able to get any compile time information that it has (which includes routes and things).
I have managed to create a RouteCollection and fill it with my routes but I am now struggling with how I can query this collection. The only way I have found is the RouteUrl method on UrlHelper but this needs a UrlHelper with the appropriate routing data which I am having trouble creating. I also would hope that there would be better methods available to query a routecollection.
Essentially I have this route:
routes.MapRoute
(
"ShowBlog",
"blog/{shortcode}/{slug}",
new { controller = "Blog", action = "ShowBlog", shortcode = "", slug = "" }
);
And I want some code like GetUrl("ShowBlog", new {shortcode = "foo", slug="bar"}) that will return blog/foo/bar.
So how can I do this?

If you can wire up a UrlHelper from a test project, you can do it from any other external project. However you need to register the routes in the external project just like you do during Application_Start in the MVC project.
You will also need to mock up an HttpContextBase and a RequestContext, which means your external project will at least need to know the application path where your MVC project is installed. This would be easier if your external project could use a mocking library just like a test project would. Is that a possibility, or not?
If so, here is a link for how to do it with Moq. You don't need the controller, but you can use similar code for your HttpContext, RequestContext, and UrlHelper.

Related

.net-core WebApp Dynamic Route to Controller

I'm trying to migrate an existing asp.net website to dotnet-core (version: 1.0.3), and have some trouble with the routing of the requests.
The old Structure was: web.site.com/[categorie]/{id?}
Now with the new envoirment it should be the same, but i cant get it work.
Since the [categorie] field comes out of the Database, and the position in dotnet-core is usualy the controller.
If this would be static i could proberly just define x Routes, but this can be changed on the fly.
So i need a hint or maybe a Solution how to route a dynamic set of [categorie] to the same Controller.
Cheers Isparia

How do I get a list of all configured WebApi routes in asp.net MVC?

I'm trying to pass configuration values to bootstrap a single page AngularJs app hosted within an MVC app that utilises WebApi (see below from the Razor view, this is achieved by inheriting a BasePage and dependency injecting a Serializer/FinancialYears service).
<script>
var angularInitConfig = #Html.Raw(Serializier.Serialize(new {
financialYears = FinancialYearsService.GetFinancialYears()
}));
</script>
This works perfectly, however I would really like to be able to extend it to include the routes from my WebApi app to avoid having to configure the endpoints in both the WebApi app AND the AngularJs app individually.
Having poked around in the RouteTable.Routes class I can see that the information I require is available and accessible from within the view, however I've been unable to extract it.
So what I'd ideally like to do is generate a collection of objects as defined below from the RouteTable.Routes class, serialize them and spit them out in the bootstrap config for the AngularJS app to consume.
new {
name = "SomeService",
route = "api/{financialYearId}/someservice",
method = "POST"
}
Does anybody have an idea how to extract this information from RoutesTable.Routes? Is there an easier way to generate the data required?
NB. All WebApi routes are configured explicitly using the Routes attribute as such:
[HttpGet]
[Route("api/{financialYearId}/someservice")]
If you create default template asp.net Mvc or WebAPi using Visual Studio, you will get Help in Folder > Areas\HelpPage...and if you access your application in : Http://yourportapplication/api/Help if project webapi...
then, you can see the code how to get information...just for started what you looking for,....

Getting an external webapi url given a list of routes it uses

I have a WebAPI (v1) app that I'm creating. It has various custom routes, that all work fine.
I have a client application I'm creating (which is MVC+webapi itself), which calls the webapi app using HttpClient. Currently I've hard-coded the urls to call, but I'd like to calculate them automatically based on a list of routes (which I could put in a shared library).
So, in my shared library I would have a list of a class that contains Name, RouteTemplate and Defaults, which in my webapi I'd iterate through that list to create my routes and in the client application i'd somehow use to calculate the url to get HttpClient to call.
How do I calculate the url to call an external webapi app from a client app (that could itself have its own routing)?
So since I know what you want, I give it a try
So I assume you have a routes table for your api which has the colums: route, controller, action, verb. An example row could be:
/foo/bar/{id}, fooController, barAction, GET
In the client app you have access to that data so you can compose an url of that when you know which controller and action to call with which verb. The combination of controller, action and verb is unique in mvc.
So you filter on fooController , barAction and verb GET and you get the route. You replace {id} with your id parameter and you have an url.

How to generate URL in service layer of ASP.NET MVC 3 project

I am looking for a simple way (if it exists) to generate a URL in a service class for a specified controller and action in an ASP.NET MVC 3 web application. I want to do this in the service layer because of needing to encode this URL in a QR code.
This is simple in a View or in a controller because of the UrlHelper available through System.Web.Mvc so I could create the beginning of the URL in the controller action that uses my service class but I was hoping to do it at the point of QR code generation.
Thanks in advance.
A major reason for having distinct layers is separation of concerns. The service layer should not concern itself with request routing.
I would pass the URL into the service layer and have the service layer return the generated QR code.
I understand the separation of concerns but sometimes a developer has to do what a developer has to do!
So here is what I have done:
var Url = new UrlHelper(HttpContext.Current.Request.RequestContext);
var myUrl= Url.RouteUrl("routeName", new { controller="ControllerName", action="Index", area="", otherDictionaryEntries="otherId"});
Regards!

MVC Rendering (RenderPartial, RenderAction) Html from another MVC Application

I am working in an environment with many teams who are responsible for specific content on pages. Each team is sharing specific information (common class libraries, and master pages) that each are going deliver different types of content.
Is it possible for an MVC application to do something similar to RenderPartial and pass a model to another MVC application Controller/Action to return content?
So the code for this might look like:
(http://www.mydomain.com/Home/Index)
<% Html.RenderAction("ads.mydomain.com", "Home", "Index", AdModel) %>
Maybe this is not a good idea as another thread has to spin up to server a partial view?
No, RenderPartial/RenerAction can only load views that it can access via reflection, not via HTTP requests to external resources.
If the MVC app for 'ads.mydomain.com' is available to you at compile them then you can utilise its resources via Areas, however it won't pickup the changes if they release a new version to the 'ads.mydomain.com' website without you getting their latest assembly and re-compiling and deploying your app as well.
You can do similar stuff with AJAX where you can load a fragment from another site, however it wouldn't be done server side, and would require the client to have javascript enabled. Also the model would need to be converted to JSON and posted to the request, so its a bit of a hacky solution.
You could write an extension method (lets call it Html.RenderRemote) which does all the work for you of creating an http connection to the target and requests the URL. You'd have to serialize the model and send it as part of the request.
public static string RenderRemote(this HtmlHelper, string url, object model)
{
// send request to 'url' with serialized model as data
// get response stream and convert to string
// return it
}
You could use it as :
<%= Html.RenderRemote('http://ads.mydomain.com', Model');
You wouldn't be able to take advantage of the routes on the remote domain, so you'd have to construct the literal URL yourself, which means if they change your routing rules your URL won't work anymore.
In principal yes, though your question is a little vague.
Have a look at "portable areas" within MvcContrib on codeplex. This technique allows separate teams to develop separate MVC apps that would then be orchestrated by a central application.

Categories