I'm using this MVCDonutCaching Nuget package because in the tutorial they said this was possible with child actions.
This question didn't work for me or I didn't understand it correctly.
If someone knows how to delete the child cache with the standard OutputCache attribute, then that is alright as well!
I've searched for this but I can't find it. See here an example:
Index action of the HomeController (homepage):
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
ChildAction of the NewsController:
[AllowAnonymous]
[ChildActionOnly]
[DonutOutputCache(Duration = 600, Location = OutputCacheLocation.Server)]
public PartialViewResult LastArticles(int numberOfArticles)
{
return PartialView("_LastArticles", db.NewsArticles
.Include(i => i.Tags)
.Include(i => i.SeoTags)
.Where(n => n.Status == PublishStatus.Published)
.OrderByDescending(n => n.PublishDate)
.Take(numberOfArticles)
.ToList());
}
Index view of the HomeController:
#{ Html.RenderAction("LastArticles", "News", new { numberOfArticles = 2 }); }
To clear the cache I have an Admin area in my application with a controller and action in it to update the data stored by the child action. So when a news article is updated. The cache should get refreshed on the homepage.
In that action I have the following code:
var cacheManager = new OutputCacheManager();
cacheManager.RemoveItem("News", "LastArticles", new { area = "", numberOfArticles = 2 });
cacheManager.RemoveItem("News", "LastArticles", new { area = "" });
I tried multiple versions but without luck. Can anybody help me?
I believe you shouldn't explicitly define the (empty) area. Although the area's an important part of the routing, MVCDonutCaching does something weird in defining an internal key. Perhaps MVCDonutCache has a bug concerning area's.
Related
I have form that a user submits. For some reason, in our production environment when they click submit, the form is cleared and they lose all that they filled in when they click submit. I've been lost on this for awhile so any input would really help.
I've tried on multiple browsers and this occurs on each one (Chrome, Safari).
The first action creates the view model for the form, the second one takes that data/model and submits an application:
[Authorize(Roles = "Applicant")]
public IActionResult Application()
{
var vm = _applicantManager.GetApplicationViewModel(CurrentUser.UserName);
return View(vm);
}
[HttpPost]
//[ValidateAntiForgeryToken]
[Authorize(Roles = "Applicant")]
public IActionResult Application(ApplicationViewModel model)
{
var saved = false;
model = _applicantManager.RebuildApplicationViewModel(model);
if (ModelState.IsValid)
{
saved = _applicantManager.SubmitApplication(model, CurrentUser.UserName);
return RedirectToAction("Index");
}
return View(model);
}
I'm thinking if I remove the ValidateAntiForgeryToken that maybe this would solve issue, but am not sure.
Is it possible that the first action needs a route? On testing, it goes to the action with the HttpPost attribute when I click submit on my local environment.
Note: This is a problem on the production server, this does not occur on the local. This leads me to believe that may a possible IIS setting that needs changed?
JavaScript on the Page:
<script>
require(['jquery', 'jqueryui'], function($, jqueryui) {
$(function() {
$("#preHealthAreaDiv input:radio").click(function () {
var selectedVal = $("#preHealthAreaDiv input:radio:checked").val();
if (selectedVal == "Yes") {
$("#preHealthAreaDetail").show();
}
else {
$("#preHealthAreaDetail").hide();
}
})
});
});
</script>
I have two URLs, both should resolve to the same page. One doesn't and returns 404
http://localhost:xxx/Assets = 404 not found
http://localhost:xxx/Assets/Index = works as intended
Here's my index action:
[HttpGet]
public IActionResult Index()
{
var vm = new AssetsIndexModel()
{
/* snipped, not important */
};
return View(vm);
}
and this is my only route in Startup.cs:
app.UseMvc(routes =>
{
routes.MapRoute("default", "{Controller}/{Action}/{id?}", defaults: new { Controller = "Home", Action = "Index" });
});
This is the only action with this problem. All other actions in the same controller resolve properly. Also, my Home/Index route DOES work if I just surf to "/Home". I can omit "/Index" there, but not in my Assets controller.
Does anyone have any ideas what I may be overlooking?
EDIT:
Also, I create the link to the Index action using the following code
<a asp-controller="Assets" asp-action="Index">Manage Assets</a>
This produces "/Assets", so MVC seems to understand that it can omit "Index", but then that link just doesn't work and returns 404.
I have found the answer after finding another problem (that at first seemed unrelated).
In my HomeController, an action was added like this:
[HttpGet("{assetId}")]
public IActionResult AssetDetail(Guid assetId)
{
return View();
}
This was the problem. I suppose any action anywhere was resolving to this action. Changing the route above to this solved it:
[HttpGet("Detail/{assetId}")]
I have a view that has multiple partial views on it. It is a settings page. They can click a site on the left panel, ad it will display all the settings for managing that site in the partial view on the page. When I build the links of the sites, I use the following Razor code as an example:
List<Site> siteList = Site.GetSites(new SiteQuery());
foreach (Site site in siteList)
{
<li>#Html.ActionLink(#site.Name, "SelectSite", "SettingsController", new { id = Model.EnvironmentID, siteId = #site.SiteID}, null)</li>
}
And here is the ActionResult I am trying to hit in the SetitngsController controller:
public ActionResult SelectSite(int id, int siteId)
{
//..code here
}
The error occurs thhough, because my URL it outputs is as follows:
~/SettingsController/SelectSite/1?siteId=1
instead of being ~/SettingsController/SelectSite/?id=1&siteId=1344
Am I obvioulsy misunderstanding how to be able to update the current view on the page with a new url and adding params to it this way. Is this wrong in MVC theory, or am I just missing somthing? Thanks in advance!
It is because of your routing table. By default it looks like {Controller}\{Action}\{id}, so your id param is right after action.
You can either change param name or change routing (but the last solution has much more complexity), for example:
#Html.ActionLink(site.Name,
"SelectSite",
"SettingsController",
new { environmentID = Model.EnvironmentID, siteId = site.SiteID}, null)
public ActionResult SelectSite(int environmentID, int siteId)
{
//..code here
}
I have a single controller and view working that calls a web service, and returns a result. At the moment, it's my default controller, called Home, and it uses the Index view page.
It's working. I can post data and then put something on the refreshed screen. It reloads the same view.
Now, once I submit, and I get a good reply, I want to load a different controller/view.
My routes look like this right now:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Home",
"{lang}",
new { controller = "Home", action = "Index", lang="English" });
routes.MapRoute(
"Location",
"{lang}",
new { controller = "Location", action = "Index", lang = "English" });
I created a controlled called Location, and it just has this:
//LocationController
public class LocationController : Controller
{
public ActionResult Index()
{
return View();
}
}
In my home controller, I am doing the logic, and then attempting to load the new page.
[HttpPost]
public ActionResult Index(HomeModel model)
{
var proxy = new Proxy();
var r = proxy.GetLocationByAddress(model.SearchString, o.ToString());
if(r==null)
{
ViewBag.Error = "Error during search";
return View(model);
}
ViewBag.Error = string.Format("Found {0} at {1}, {2}", r.StreetName, r.Latitude, r.Longitude);
return RedirectToAction("Index", "Location");
}
But when I run it, submit it, step through, it hits the RedirectToAction - but ... the Home screen simply refreshes. I never see the new Location view. What am I doing wrong here? I have't grasped Routes yet... I need to pass a new object to the Location.Index screen to display...
Your route mapping is incorrect, check this out: http://www.asp.net/mvc/tutorials/controllers-and-routing/creating-custom-routes-cs
routes.MapRoute(
"Location",
"Location/{lang}",
new { controller = "Location", action = "Index", lang = "English" });
I don't think so you need to make any changes. As in your case you want to load different controller with its respecting view you need below change only
replace this code return RedirectToAction("Index", "Location");
with this code return Redirect("http://www.yoursite.com/Location/Index");
Your change is like redirection from one page to another therefore you need to put your complete path here
please try & reply if any problem
My story is: I have a couple of forms in separately views that post description info to edit. And every description belongs to different places. So I'm sending also refTypeId info in my forms to decide which description belongs where. So far ok. but I want to return back to edit description view where form was sent from after editing description. So I need to know where form came from that I just edited in my EditDescription action. My EditDescription action method following code:
[Authorize]
[HttpPost]
public ActionResult EditDescription(string descriptionToEdit, int refTypeId)
{
var entity = _entities.Descriptions.Where(e => e.Id == refTypeId).Select(e => e).FirstOrDefault();
entity.Description = descriptionToEdit;
_entities.SaveChanges();
var Description = _entities.Descriptions.Where(e => e.Id == refTypeId).Select(e => e).FirstOrDefault();
ViewData["Description"] = Description.Description;
TempData["Message"]="Description has been saved";
return (?);// i need to know which view that form was sent from
}
send another parameter called ReturnUrl and redirect to it on success.