Call controller without "clicking" in asp.net MVC - asp.net-mvc

Is there a way to call a controller without clicking on a link?
By this I mean, without using #Html.ActionLink for example, something automatic that's call after a condition.
Thanks in advance !
Edit :
There is some code :
if (IsPost)
{
if (!Request["idInterventions"].IsEmpty())
{
string[] AllStrings = Request["idInterventions"].Split(',');
List<int> list = new List<int>();
foreach (string item in AllStrings)
{
int value = int.Parse(item);
list.Add(value);
}
Model.toFacture(list);
isDone = true;
//Need to call a controller method here
}
}
So my code is triggered after a POST.

In Razor, you can use
Html.RenderAction("ActionName", "ControllerName", new { Area = "SomeArea", someParameter = Model.SomeParameterValue });
This renders the view returned by the action directly.
In controllers, you can use
return RedirectToAction("ActionName", "ControllerName");
This will result in a HTTP 302 Found redirect.

Related

asp.net mvc - Rewrite Url after return view

I have a problem like this. In RouteConfig.cs, I set routes
routes.MapRoute(
"NewsDetails",
"news/details-news/{title}-{id}",
new { controller = "News", action = "Details", id = "", title = "" }
);
In my Index.cshtml of NewsController I have a link
#Html.RouteLink(item.Title, "NewsDetails", new {
title = MyWeb.Classes.PrettyUrlHelper.PrettyUrl(item.Title),
id = item.Id
})
In my NewsController:
public ActionResult Details(string title,String id)
{
if (id == null && title == null)
return RedirectToAction("Index");
try
{
int ID = Int32.Parse(id);
var result = NewsConnectionDB.GetInstance().Single<LifeStory>(ID);
return View(result);
}
catch (InvalidOperationException) {
return View("~/Views/Error/Error404.cshtml");
}
catch (FormatException) {
return View("~/Views/Error/Error404.cshtml"); }
}
So if a user click on link in View, that link will route to action Details to process, and the link is Seo Url Friendly (localhost:9224/news/details-news/ten-things-2). But a user types a link instead of clicking to a link in View:
localhost:9224/news/details-news/ten-thingsblahblahblah-2
The url above is correct with id but title is not. So how can I update the url after I return View if a user types the wrong title but right id?
Any help would be appreciated.
P/S: my English is not good, so I hope you understand it.
If title is incorrect then you can send correct url in response headers. If it's ajax call then on completion check for correct url in response header. If correct url exists then change your browser url using window.history.pushState javascript method.
In Details action method use below code to set response header.
HttpContext.Current.Response.AppendHeader("CorrectUrl", "YourUrl");
Use HttpServerUtility.UrlEncode(string);
javascript code can be replace url, I think it will be working :).
C# code
string _entitle = HttpServerUtility.UrlEncode(_strTitle);
string _strCorUrl = "http://example.com/"+ _entitle + "-" + _intID.toString();
script code
top.window.location.replace('CorrectUrl');
or C# code redirect url
Response.Redirect(url);
Update
possible 1 solution with Context.RewritePath
https://msdn.microsoft.com/en-us/library/sa5wkk6d(v=vs.110).aspx
void Application_BeginRequest(Object sender, EventArgs e)
{
string originalPath = HttpContext.Current.Request.Path.ToLower();
if (originalPath.Contains("/page1"))
{
Context.RewritePath(originalPath.Replace("/page1", "/RewritePath.aspx?page=page1"));
}
if (originalPath.Contains("/page2"))
{
Context.RewritePath(originalPath.Replace("/page2", "/RewritePath.aspx"), "pathinfo", "page=page2");
}
}
It code is example, You can use it
I hope it help

Umbraco Surface Controller or RenderMvcController

Hi I have my 'home' controller and a 'sort' controller in umbraco 7. The 'home' controller works fine for the index action as it is overridden from RenderMvcController. Firstly I am confused which controller I should using in which instance i.e a surface controller or a rendermvccontroller. I cant seem to access the twitter action below which is something I need for ajax. Do I need to put the twitter action in a surface controller or could I use a regular mvc controller in umbraco?
public override ActionResult Index(RenderModel model)
{
var storedProcedure = new StoredProcedure()
{
ConnectionString = ConfigurationManager.ConnectionStrings["CentralDbContext"].ConnectionString
};
DataSet ds = storedProcedure.ExecuteProcedureToDataSet("GetHomePage");
IMapSetup map = new MapHomePage();
HomePage homepage = map.Setup<HomePage>(ds);
homepage.Slideshow = CurrentPage.AncestorsOrSelf(1).First().Descendants("SlideshowItem").Take(5).AsMany<Slideshow>();
this._weatherSettings.DefaultLocation = "warrington";
homepage.Forecast = new Forecaster(this._weatherSettings, this._cacheHelper).GetWeather(this._weatherSettings.DefaultLocation);
return CurrentTemplate(homepage);
}
public ActionResult TwitterSort(int? page)
{
int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
var storedProcedure = new StoredProcedure()
{
ConnectionString = ConfigurationManager.ConnectionStrings["CentralDbContext"].ConnectionString
};
DataSet ds = storedProcedure.ExecuteProcedureToDataSet("GetHomePage");
IMapSetup map = new MapHomePage();
HomePage homepage = map.Setup<HomePage>(ds);
if (Request.IsAjaxRequest())
{
return PartialView("umbTweets", homepage.Twitter.ToPagedList(currentPageIndex, DefaultPageSize));
}
return PartialView(homepage.Twitter.ToPagedList(currentPageIndex, DefaultPageSize));
}
My Approach is:
Render controller is only for displaying data to user.
Surface controller is for interaction (I use this for interaction mainly ajax, or forms)
For rendering child action you can use following example:
http://our.umbraco.org/documentation/Reference/Mvc/child-actions
Update:
To implement custom routing you can have a look on
http://cpodesign.com/blog/umbraco-implementing-routing-in-mvc/

Calling RazorEngine.Parse() in Controller Action fails with bad HttpContextBase

Perhaps I'm not calling RazorEngine in the correct place.
In my controller action I use the following code to call RazorEngine. But I think this may not be correct as when it calls through to .Execute() and then into MVC's GetActionCache() the HttpContextBase.Items fails with a "method not implemented" exception.
Am I calling RazorEngine in the wrong way? #Html.LabelFor() works fine.
string template = "#Html.EditorFor(model => model.OldPassword)";
string result = string.Empty;
var config = new RazorEngine.Configuration.TemplateServiceConfiguration
{
BaseTemplateType = typeof(System.Web.Mvc.Helpers.HtmlTemplateBase<>)
};
using (var service = new RazorEngine.Templating.TemplateService(config))
{
// Use template service.
RazorEngine.Razor.SetTemplateService(service);
result = RazorEngine.Razor.Parse(template, model);
}
powercat97 over on the github issues page has a workaround for an issue that addresses this.
https://github.com/Antaris/RazorEngine/issues/46
The reason I've had much trouble is that there is no context set. Creating a new ViewContext is not sufficient.
Therefore by calling a view that in turn calls our RazorEngine code via RenderAction() we get the context and the MVC framework has everything it needs when it is called by RazorEngine.
Using the AccountController as an example (HtmlTemplateBase comes from RazorEngine issues with #Html and http://www.haiders.net/post/HtmlTemplateBase.aspx):
public ActionResult Test()
{
var model = new MySite.Models.LocalPasswordModel();
model.OldPassword = "MyOldPwd";
model.NewPassword = "SomeNewPwd";
return PartialView(model);
}
[ChildActionOnly()]
public string TestTemplate(MySite.Models.LocalPasswordModel vm)
{
string result = string.Empty;
string template = "#Html.EditorFor(model => model.OldPassword)";
var config = new RazorEngine.Configuration.TemplateServiceConfiguration
{
BaseTemplateType = typeof(HtmlTemplateBase<>)
};
using (var service = new RazorEngine.Templating.TemplateService(config))
{
// Use template service.
RazorEngine.Razor.SetTemplateService(service);
result = RazorEngine.Razor.Parse(template, vm, "MyTemplateName");
}
return result;
}
and in Test.cshtml:
#model TestRazorEngine.Models.LocalPasswordModel
#{ Html.RenderAction("TestTemplate", new { vm = Model }); }

Redirect page in c# mvc

I have link
http://localhost:3163/PaymentOrder?AgentCode=&InvoiceNo=&AgentName=&FromDate=&fromDate=12%2F11%2F2013&FromDate=12%2F11%2F2013+9%3A08%3A01+SA&toDate=12%2F11%2F2013
after click button "Delete" the page should be redirect to "Index"
return RedirectToAction("Index","PaymentOrder");
But i want keep link same as first, i don't know what method, please help me. thanks
I can fix it, i save session in
public ActionResult Index{
Session["LastPage"] = Request.Url.ToString();
}
after I'm
return Redirect(Session["LastPage"] as String);
You can pass the query strings to the third parameter of RedirecToAction
return RedirectToAction("Index","PaymentOrder", new { fromDate = model.FromDate });
Or pass the entire model as well, that contains the properties similar to your query strings
return RedirectToAction("Index","PaymentOrder", new { paymentModel = model });
As your query string is quite long, it would probably be better to write an extension method and use that instead, to keep your controllers thin. I haven't tested this, but something like this should work:
public static RouteValueDictionary ToRouteDictionary(this NameValueCollection nameValues)
{
if (nameValues == null || nameValues.HasKeys() == false)
return new RouteValueDictionary();
var routeValues = new RouteValueDictionary();
foreach (var key in nameValues.AllKeys)
routeValues.Add(key, nameValues[key]);
return routeValues;
}
Then in your controller:
return RedirectToAction("Index","PaymentOrder", Request.QueryString.ToRouteDictionary());
Just don't redirect but return the view, the URL will remain the same.

How to display the result of another controller action without using RedirectToAction

I have two ASP.NET MVC controller actions as included below and would like RenderComponent to display the contents of RenderComponentPublic without calling RedirectToAction.
Instead, I would like the content to be revealed under RenderComponent and for no redirect to take place.
Could anybody suggest a way to achieve this?
Controller Action 1 - RenderComponent
[Authorize(Roles = "user")]
public ActionResult RenderComponent(
string ckey,
string ukey)
{
return RedirectToAction("RenderComponentPublic", new
{
ckey,
ukey
});
}
Controller Action 2 - RenderComponentPublic
public ActionResult RenderComponentPublic(
string ckey,
string ukey)
{
return PartialView("_ThisContent");
}
You can always call the other action within C#.
[Authorize(Roles = "user")]
public ActionResult RenderComponent(
string ckey,
string ukey)
{
return RenderComponentPublic(ckey,ukey);
}
One way that might suit your needs is to call Html.RenderAction So within your RenderComponent view, just call;
#(Html.RenderAction("RenderComonentPublic", new { ckey = Model.ckey, ukey = Model.ukey });)
or
#Html.Action("RenderComonentPublic", new { ckey = Model.ckey, ukey = Model.ukey })
You would have to pass your ckey and ukey into the view within the Model, or a ViewBag or something.
Your RenderComponentPublic view would need to have it's layout page set to null in order for it not be be rendered within a layout.
Not sure if this is what you are looking for.

Resources