I am trying to create a Url after a certain operation and this url should point to a different controller and actions. I also need to include some parameters so they provide the target controller with information needed. so lets say I have a controller called:
DoWorkController.cs
and an Action
public void Add(params...){..}
I am using UriBuilder in my homepage controller like this:
UriBuilder builder = new UriBuilder();
builder.Host = System.Web.HttpContext.Current.Request.Url.Host;
builder.Port = System.Web.HttpContext.Current.Request.Url.Port;
//got stuck here
Uri ret = builder.Uri;
return ret;
I want it to pull the controller name and action name and assign it to builder then add parameters, I am not sure how to do this. Suggestions??
EDIT
I solved the path-to-controller-to-action problem, I am still stuck on adding parameters to the url.
UriBuilder builder = new UriBuilder();
builder.Host = System.Web.HttpContext.Current.Request.Url.Host;
builder.Port = System.Web.HttpContext.Current.Request.Url.Port;
string path;
if (operation == 1)
path = Url.Action("Add", "DoWork");
else if(operation ==2)
path = Url.Action("Delete", "DoWork");
else
throw new ArgumentException("Operation is neither Add or Delete");
if (path != null)
{
builder.Path = path;
}
Uri ret = builder.Uri;
You can add parameters to your Url.Action in following way:
Url.Action("GetByList", "Listing", new { name = "John"})
If you are on the home page controller, then you already know the controller name, no?
But to answer your question, the way to get the controller and action name is to get it from the routeData:
RouteData rd = ViewContext.RouteData;
var controllerName = rd.GetRequiredString("controller");
var actionName = rd.GetRequiredString("action");
Related
This is my code below
public IHttpActionResult Post([FromBody]EnquiryInfo webEnquiry)
{
//some code
if (result.ToString() == "true" || result.ToString() == "True")
{
//UriBuilder builder = new UriBuilder("~/ApplicationForm/Success");
//String url = "http://localhost:65041/ApplicationForm/Success";
//System.Uri uri = new Uri(url);
//return Redirect(uri);
return Redirect("~/ApplicationForm/Success" );
}
}
Applicationform is a different controller which has the view Success.
A Redirect (the are you are using) points to a url not a file/action.
You could use a RedirectToAction and point to the controller and action by name.
I have a controller which performs certain action. Now, i need certain functionality (send an email) to happen in middle of the above mentioned controller.
try
{
using (HttpClient client = new HttpClient())
{
// Add an Accept header for JSON format
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
response = client.PostAsJsonAsync(URLForReportsapi + "InsertOrUpdatePortal", criteria).Result;
}
// Throw exception if not a success code.
response.EnsureSuccessStatusCode();
// Parse the response body.
var pVMRslt = response.Content.ReadAsStringAsync().Result;
var pVMRsltDsrlz = JsonConvert.DeserializeObject<List<PortalInfoVM>>(pVMRslt);
portalVMList = pVMRsltDsrlz.ToList();
var newnumids = portalVMList.Where(c => c.isNewStatus == "NEW").Select(c => c. numid).ToList();
//-------- Here I need to call another action which is residing inside another controller.
return PartialView("AddToPortalConfirmation", portalVMList);
}
In the above piece of code before calling the partialview I need to call another action which is residing inside a different controller and return back to PartialView("AddToPortalConfirmation", portalVMList)
I was trying to do something like this but this is not working.
var resp = RedirectToAction("Create", "EmailReport", new { numids = newnumids , To = toEmail});
In my routeconfig.cs I have
routes.MapRoute(
null, // Route name
"EmailReport/Create/{To}/{numids }", // URL with parameters
new { controller = "EmailReport", action = "Create", To = string.Empty, numids = string.Empty } // Parameter defaults
);
Try :
return RedirectToAction("Create", "EmailReport", new { numids = newnumids , To = toEmail});
I have a bunch of custom routes defined using AttributeRouting. I have a function in a controller that is trying to access one of these API functions at /api/GetBatchItems.
GetBatchItems is a function of the controller APIController, similar to:
[RouteArea("api")]
public sealed class APIController : ApiController{
[GET("GetBatches")]
public IEnumerable<PRAT.Models.EF.EFBatchItem> GetBatches() { ... }
}
In another controller, I am trying to get the result. When browsing directly everything is fine if I do it this way, but I want to be able to use my already defined route, is there a way to do that? I saw someone mention HttpAttributeRoutingConfiguration but I could not find that class anywhere. I don't want to have to use the MapHttpRoute method this way...
var config = new HttpConfiguration();
config.Routes.MapHttpRoute("default", "api/{controller}/{id}", null);
var server = new HttpServer(config);
var client = new HttpClient(server);
string url = Request.Url.GetLeftPart(UriPartial.Authority) + "/api/APIController/GetBatches";
var result = client.GetAsync(url).Result;
var content = result.Content;
var model = content.ReadAsAsync<IEnumerable<PRAT.Models.EF.EFBatchItem>>().Result;
if (model == null) return View();
else return View(model);
TO MAKE YOUR SAMPLE CODE WORK
Your existing code sample needs two changes to work:
make {id} optional, since GetBatches() has no parameter:
config.Routes.MapHttpRoute("default", "api/{controller}/{id}", new { id = RouteParameter.Optional });
since HttpConfiguration routes match {controller} to a class named {controller}Controller, change your url calculation to:
string url = Request.Url.GetLeftPart(UriPartial.Authority) + "/api/API/GetBatches";
SIMPLER VERSION
Your can use your existing route /api/GetBatches
var client = new HttpClient();
string url = Request.Url.GetLeftPart(UriPartial.Authority) + "/api/GetBatches";
var result = client.GetAsync(url).Result;
var content = result.Content;
var model = content.ReadAsAsync<IEnumerable<MyViewModel>>().Result;
if (model == null) return View();
else return View(model);
EVEN SIMPLER (IF YOU DO NOT NEED HTTP)
Replace your sample code with this Add this extension class:
var model = (new APIController()).GetBatches();
if (model == null) return View();
else return View(model);
i have a set of routes defined in System.Web.Routing and in need to get the actual url's with the .aspx extension. i've tried this code but i'm doing something wrong here:
var path = RouteTable.Routes.GetVirtualPath(null, item.Link, null);
var link = path.Route.GetVirtualPath(null, null);
if (link.VirtualPath.ToLower().Contains("~/displaycmspage.aspx?pagename="))
{
//do work on url here
}
any idea on how i can do this? The item.link is a custom object where i have the route.
ok, so i found the answer :
var path = RouteTable.Routes[item.Link];
Route ruta = path as Route;
var link = ruta.RouteHandler as PageRouteHandler;
if (link.VirtualPath.ToString().ToLower().Contains("~/displaycmspage.aspx?pagename="))
{
//do work on url here
}
How can I get the controller action (method) and controller type that will be called, given the System.Web.Routing.RouteData?
My scenario is this - I want to be able to do perform certain actions (or not) in the OnActionExecuting method for an action.
However, I will often want to know not the current action, but the "root" action being called; by this I mean I may have a view called "Login", which is my login page. This view may include
another partial view "LeftNav". When OnActionExecuting is called for LeftNav, I want to be able to determine that it is really being called for the "root" aciton of Login.
I realise that by calling RouteTable.Routes.GetRouteData(actionExecutingContext.HttpContext), I can get the route for the "root" request, but how to turn this into
method and type info?
The only solution I have so far, is something like:
var routeData = RouteTable.Routes.GetRouteData(actionExecutingContext.HttpContext)
var routeController = (string)routeData.Values["controller"];
var routeAction = (string)routeData.Values["action"];
The problem with this is that "routeController" is the controller name with the "Controller" suffix removed, and is not fully qualified; ie it is "Login", rather than "MyCode.Website.LoginController".
I would far rather get an actual Type and MethodInfo if possible, or at least a fully qualified type name.
Any thoughts, or alternative approaches?
[EDIT - this is ASP.Net MVC 1.0]
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var type1 = filterContext.Controller.GetType();
var type2 = filterContext.ActionDescriptor
.ControllerDescriptor.ControllerType;
}
OK, sorry, I missed the "root" part.
Then, another way, you can save controller type to thread storage. Pseudocode:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!Thread.LocalStorage.Contains("root_controller"))
Thread.LocalStorage["root_controller"] =
filterContext.ActionDescriptor
.ControllerDescriptor.ControllerType;
}
Just an idea. I'm sure thread local storage is available in C#. The key idea here is that you save it only for first request, thus it's always root controller.
Here is the solution I compiled from various sources. The url variable should contain the URL of the action:
url = "YOUR URL";
// Original path is stored and will be rewritten in the end
var httpContext = new HttpContextWrapper(HttpContext.Current);
string originalPath = httpContext.Request.Path;
try
{
// Fake a request to the supplied URL into the routing system
httpContext.RewritePath(url);
RouteData urlRouteData = RouteTable.Routes.GetRouteData(httpContext);
// If the route data was not found (e.g url leads to another site) then authorization is denied.
// If you want to have a navigation to a different site, don't use AuthorizationMenu
if(urlRouteData != null)
{
string controllerName = urlRouteData.Values["controller"].ToString();
string actionName = urlRouteData.Values["action"].ToString();
// Get an instance of the controller that would handle this route
var requestContext = new RequestContext(httpContext, urlRouteData);
var controllerFactory = ControllerBuilder.Current.GetControllerFactory();
var controller = (ControllerBase) controllerFactory.CreateController(requestContext, controllerName);
// Find the action descriptor
var controllerContext = new ControllerContext(httpContext, new RouteData(), controller);
var controllerDescriptor = new ReflectedControllerDescriptor(controller.GetType());
var actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
}
}
finally
{
// Reset our request path.
httpContext.RewritePath(originalPath);
}
public Type ControllerType(string controllerName)
{
var fullName = controllerName + "Controller";
var assemblyName = Assembly.GetExecutingAssembly().FullName;
return Activator.CreateInstance(assemblyName, fullTypeName).GetType();
}
public MethodInfo ActionMethodInfo(string actionName, Type controllerType)
{
return controllerType.GetMethod(actionName);
}
Are you thinking of an implementation similar to this? Some Try/Catches required!
MvcSiteMapProvider does this. Here is the code for this particular thing.
Here is the code