I have a paged list using unobtrusive ajax that looks like this.
#Html.PagedListPager(Model, page => Url.Action("Images", "Admin", new { imageLibrary = image.ImageLibrary, page }),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new AjaxOptions()
{ InsertionMode = InsertionMode.Replace, UpdateTargetId = "imagesContainer" }))
My controller looks like this:
public ActionResult Images(ImageModels image, int? page, string imageLibrary)
{
// do stuff here
}
I was trying to pass a model to my controller, so instead of imageLibrary = image.ImageLibrary, I should have only needed to pass image = imageModel, but when I pass the model itself, the controller gets a null value (yes the model name was spelled correctly). When I try to get a property of the model and pass it to the controller (that's the imageLibrary = image.ImageLibrary) the controller receives both the model and the imageLibrary string value! This works fine for the end result, I just don't understand why it works, and I shouldn't have to pass the string value imageLibrary to my controller - especially if I'm not really using it.
Any insight on this would be appreciated.
Related
I have some checkboxes and a button (not in a form).
When the button is clicked, I have some jQuery and I am creating a post model which contains the values of the checked boxes and posting to a controller.
The controller then creates view models and I want to redirect the user to the correct view, passing the view model in to the view.
jQuery:
$.ajax({
url: AppSettings.baseUrl + "BOM/getMultiBOM",
type: 'POST',
data: JSON.stringify(data)
});
Controller:
[HttpPost]
public ActionResult getMultiBOM(multiBOMPostModel multiBomsPostModel)
{
BOM bom = null;
foreach (int value in multiBomsPostModel.bomsArray)
{
bom = db.BOMs.Find(value);
}
BOMViewModel viewModel = getViewModel(bom, null);
return RedirectToAction("OpenMultiBOM", new { viewModel = viewModel, bom = bom });
}
public ActionResult OpenMultiBOM(BOMViewModel viewModel, BOM bom)
{
viewModel.projectModel = new ProjectViewModel
{
project = bom.Project
};
return View(viewModel);
}
It is probably a bit of a mess.
I think the jQuery is necessary to pass the checkbox values to the controller.
When I use RedirectToAction to the method which then returns the view, the model is not being passed through, presumably as it is sending the model as a query string.
The view model is not simple and contains lists, IEnumerables, and nested models.
Can anyone help with the most efficient way to redirect/return the view while passing the view model?
Answer: I kept the ajax to post my checkbox values to the controller
$.ajax({
url: AppSettings.baseUrl + "BOM/getMultiBOM",
type: 'POST',
data: JSON.stringify(dataArr),
}).done(function (result) {
location.href = "/BOM/OpenMultiBOM";
});
In my controller, I assigned the posted values to a postModel and then stored them in TempData. The key here was to return a Json value which would then allow the redirect on the client side to take place.
public ActionResult getMultiBOM(multiBOMPostModel multiBOMPostModel)
{
TempData["BOMs"] = multiBOMPostModel;
return Json("success");
}
I then had another HttpGet method which would load after the page is redirected by the Ajax result and cast the TempData to an object.
[HttpGet]
public ActionResult OpenMultiBOM(int? BomMarkupMessage = null)
{
var bomIds = TempData["BOMs"] as multiBOMPostModel;
}
I would persist the viewmodel server side, perhaps in a session variable, or perhaps as a TempData (TempData typically only lives until the next request), and pass a key for the session variable to the second controller in the case of session variable, or use the TempData directly in your view in the case of TempData. This would avoid passing the whole object back and forth multiple times.
So the way that i have done this before is to have an empty div in DOM.
<div id="partialViewContent">
<!-- Content will be loaded later. -->
</div>
If you have a default view, you'll need to set it to load from URI using the below snippet.
$("#partialViewContent").load("Controller/Action",
function (response, status) {
if (status !== "success") {
console.log("An error has occured when attempting to load partial view.");
}
});
When you post to your controller action via JQUERY, have the action return a partial view with the model. (Assume model is relevant to each partial view).
Then when your ajax is complete, replace the content in partialViewContent with the POST response.
new to MVC so here goes.
I am currently loading up HTML.Partial on my Index.cshtml page like so:
#Html.Partial("~/Views/Switchb/editPerson.cshtml")
However, I am in need of customizing that in the controller depending on the current users category number.
So as an example, if the user has a category of 3 then I would need to do this:
#Html.Partial("~/Views/Switchb/3.cshtml")
Is there any type of call in the "code behind" in the controller that I can use in order to do that? Or would I just need to place the code within the cshtml page and pass its category number via the controller over to the cshtml page?
You can render a partial view from a controller action. You can pass the view name as string.
public ActionResult Switchb(string categoryNumber) {
var viewModel = new MyViewModel { CategoryNubmer = categoryNumber };
// additional processing, backend calls, formatting ....
return PartialView(categoryNumber, viewModel);
}
To call this action from View:
#{
var routeValues = new RouteValueDictionary(new {
categoryNumber= "3",
});
Html.RenderAction("Switchb", "MyController", routeValues);
}
Determine the category in the controller (via url parameter, from a database, or whatever) and then set that value as a property on your view's Model. Then in your line of code you can do this
#Html.Partial("~/Views/Switchb/" + Model.Category + ".cshtml");
I have this on my cshtml page
<div class="liveMatch-timer">
#Html.Sitecore().Controller("Blog", "LiveBlogHeader")
</div>
And this is my controller
public PartialViewResult LiveBlogHeader()
{
var matchHeader = GetMatchDayHeader();
return PartialView(BlogConstant.LiveBlogHeaderPath, matchHeader);
}
I have one hidden field with the name "liveMatchItemId" on my cshtml page. I would like to pass its value to controller so that I can access it inside controller. I am expecting to change controller definition something like this
public PartialViewResult LiveBlogHeader(string liveMatchItemId)
Anyone can help me understand on how can I do this? I am new to sitecore and MVC.
EDIT: I am able to achieve this using below code
#Html.Action("LiveBlogHeader", "Blog", new { liveMatchItemId = "12" })
But how can I set hidden field value instead of static field "12"?
Probably you could use something like:
#Html.Action("LiveBlogHeader", "Blog", new { liveMatchItemId = Model.LiveMatchItemId })
Where Model.LiveMatchItemId is the property that you want to pass to the controller.
Please assist, I have the following Ajax code
#Ajax.ActionLink(linkText: "Call An Action",
actionName: "GetCoverDate",
routeValues: new { appd = Model.AppDate },
ajaxOptions: new AjaxOptions
{
UpdateTargetId = "ajaxtarget",
InsertionMode = InsertionMode.Replace
})
My Controller Action
public string GetCoverDate(DateTime appd)
{
return appd.AddMonths(6).ToString();
}
What this does is it takes the contents of Model.AppDate and adds 6 months to it via ajax and controller's method and displays the results in a div
I'm trying to have the following changes to the code.
Insert the returned results (date) to the appropriate EditorFor (at
the moment I'm displaying the result in a div - ajaxtarget)
The routeValue as it is, passes a date that was set as default when
the view was loaded, how do I pass the value currently contained on
the EditorFor (in case the user has selected a different date)?
Thank you in advance
I have the following in partial view
<%= Ajax.ActionLink("Plunder Again", "Resources", new { controller = "Resource", parent = Model.ToJson() }, new AjaxOptions { UpdateTargetId = Model.ResourceType })%>
going to the controller method:
public ViewResult Resources(/*ModelResource parent*/)
{
Debug.Assert(Request.Params["parent"]!=null);
var jss=new System.Web.Script.Serialization.JavaScriptSerializer();
var parent=jss.Deserialize<ModelResource>(Request.Params["parent"]);
return View(parent.PlunderAmount);
}
but it throws an exception because the json doesn't properly pass via url, it can't find the 'Type' parameter.
I tried simply having the ModelResource as a parameter to the Action but it came in as null
This action will also be returning a partial view if that matters in any way.
ActionLink is used to create an anchor to a URL -- the URL must be valid! In general, you don't pass a whole object to an Action because the route values have to be bound back into the model and passed to the action. You might pass an ID of object though so the Action can get the object using that key.
If you want to send Model to controller instead of Ajax.ActionLink use Ajax.BeginForm