I have a post method that has my view model and all of its data
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SpecialOrderSelection(JobOrder job, ItemViewModel model)
{
return RedirectToAction("SpecialOrderSummary", "JODetails", model);
}
The 'special order selection' page is where a user is shown a list of parts and must choose if the part should be transferred, harvested, or disposed of. It returns the correct data to the controller. But after the submit happens I want to give the user a summary page of everything that they have done. To do this I tried passing the view model to a 'Order summary' page. With the get method looking like this
public ActionResult SpecialOrderSummary(ItemViewModel model)
{
return View(model);
}
Here is my Model
public class ItemViewModel
{
[Required]
public int ID { get; set; }
public string ItemId { get; set; }
public string ItemName { get; set; }
public string MFGNumber { get; set; }
public IList<ItemPartViewModel> Parts { get; set; }
public IList<ItemComponentViewModel> Components{ get; set; }
public IList<ComponentPartViewModel> ComponentParts { get; set; }
public IList<ComponentSubCompViewModel> ComponentSubComps { get; set; }
public IList<SubCompPartViewModel> SubCompParts { get; set; }
public IList<SubCompSubCompViewModel> SubCompSubComps { get; set; }
public IList<SubCompSubCompPartViewModel> SubCompSubCompParts { get; set; }
}
And then I want the view to do something like this
#model PIC_Program_1._0.Models.ItemViewModel
#using PIC_Program_1._0.Models
#{
ViewBag.Title = "SpecialOrderSummary";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#*#Html.HiddenFor(model => model.ID)*#
#Html.HiddenFor(x => x.ID)
<h2>Special Order Summary</h2>
<p style="color:red" class="noprint">Please review and verify </p>
<h2>
Transfers
</h2>
<h3>
Parts
</h3>
foreach (var part in Model.Parts) // part is null here
{
<p>#part.PartName</p>
}
}
But Model.Parts always has a count of 0. So I'm wondering how I can pass the data of a view model around.
Any help is appreciated.
As David suggested, I tried doing it through AJAX but it won't go to the view page that I want it to go to, just reloads the same page. Here is my AJAX method
$(document).ready(function () {
$("button").click(function () {
$.ajax({
url: '#IGT.baseUrl/JODetails/SpecialOrderSummary',
data: $('#form').serialize(),
type: 'GET'
});
});
});
I am assuming that the client passes job and model in the request body.
I'll show what happens with this sequence: https://swimlanes.io/#pZLBbhNBDIbv+xRWLgUpTQq9rUQPBKjgkopEQj06u25notlxGHuT5u3xzCQpSHDitDP2rP35969eA7WwGFOiqPCRHO49j6lpmkXwOXR9BytKe0otONVdO5/3PKCPs46H+ZZ7UvRB5rKjzmPg1FMSCtSp59g0kZXaRp0XSPRzJFE4+BDA2hD4CDmx4f4I6gi2vAGMfTkPVjnMYJ2PpI574Cf4o44dH5artZFWvkxamVv4Tr1PxgDKgAUFvi0/VdQFR00cAqXZqkIvM/RqHAZMR7ggE/Bmm2tMCssEjjwCJoIdivj4DI7s0jNJvFL7wsGhlkf0YnV11mR4qWyJZMdR8j0Wqly/qwo7FOisBdzevCvzo+lCaEwwCdxhxm//JXWl/q9tnUvUwX84ioBntjf3zM+BYOESDzSFLybrE79M4YFFB4xT+BqFh+gROBUFyJq/tXk78nuSMouBgCjqKGVEe3h7874oZ2k2JdJlqSdlTC4zYVe1pj47JYfPapzkyfZ4NcSVnJ1iMQwHPArcf17XNZzGsYw1vGzwN6M9Wr+zVf5mi1fXlh8+xDGEpvkF
You just don't have to redirect the client, simply return the oter action's result:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SpecialOrderSelection(JobOrder job, ItemViewModel model)
{
return SpecialOrderSummary(model);
}
Related
I have problem i dont now how to fix it.
I have ViewModel
public class CartOrderViewModel
{
public Cart Carts;
public Order Orders;
public string name;
}
in CartController method
public async Task<IActionResult> Index()
{
CartOrderViewModel vm = new CartOrderViewModel
{
Carts = _cart,
Orders = new Order() { User = applicationUser },
};
return View(vm);
}
View Index from CartController
#using (Html.BeginForm("Test", "Cart", FormMethod.Post))
{
#Html.TextBoxFor(m => m.name)
<input type="submit" value="Submit" />
}
and in my method Test in CartController i dont see ViewModel CartOrderViewModel
[HttpPost]
public IActionResult Test(CartOrderViewModel test)
{
string komentarz = test.name;
return View();
}
Model: test in null.
Please help me. Thx a lot
How to send form from Index View from CartController my ViewModel CartOrderViewModel
example Model.Order.name ??
Why my name from CartOrderViewModel dont sent to method Test from index View ?
printscreen
enter image description here
Why my name from CartOrderViewModel dont sent to method Test from index View ?
ASP.NET binds to properties, not fields. Change all of the public fields in class CartOrderViewModel to be mutable properties with { get; set; }.
Like so:
public class CartOrderViewModel
{
public Cart? Carts { get; set; }
public Order? Orders { get; set; }
public String? Name { get; set; }
}
Don't forget to add validation attributes, such as [Required], as per your project's needs.
I have a model passed from controller to view in my asp.net mvc5 website. Then I show the dropdownlist using the model and I want to pass an id back when submitting the form. Here is my model :
public class SiteDirectionModel
{
public int id { get; set; }
public string name { get; set; }
}
Then in the model, I use a List<SiteDirectionModel> to which I add new instances of each item I need. I fill up both these lists and then pass my model to the view.
#model List<SiteDirectionModel>
#using (Html.BeginForm("GetSiteRF", "Create", FormMethod.Post))
{
#Html.DropDownListFor(x => x.name,new SelectList(Model.name,"Sites"));
<input type="button" value="Selectionner" class="btn btn-primary"/>
}
Then how to retrieve the ids for each name ? And how to pass it as a parameter to my controller? Such that I would have :
public ActionResult GetSiteRF(int id)
{
int newId = id;
//Call method to searchId ...
return View("CreateADUser");
}
I have given how to bind and get value from dropdown. Please use your own BL in this.
Your model should be like this.
public class Something
{
public int Id { get; set; }
public string Name { get; set; }
}
public class SiteDirectionModel
{
public SelectList MyDropDown { get; set; }
public int SelectedValue { get; set; }
}
You BL should be like this.
public List<Something> GetListofSomething()
{
//your logic.
}
Your Get method should be like this.
public ActionResult MyGetMethod()
{
SiteDirectionModel model = new SiteDirectionModel();
model.MyDropDown = new SelectList(GetListofSomething(), "key_field_name", "value_field_name", "default_value");
}
Then finally HTML
#Html.DropDownListFor(x => x.SelectedValue,Model.MyDropDown)
Hello I have following problem:
I tried to post a Model through a Form to an other controller-action.
But the received Model is only filled with null elements.
ToolController.cs
public class ToolController : Controller
{
public ActionResult Index()
{
var Model = new EditToolModel{ /* Some data */ };
return View(Model);
}
[HttpPost]
public ActionResult EditToolOverview(EditToolModel myModel)
{
return RedirectToAction("Index", "Tool", new { show = "overview" });
}
}
EditToolModel.cs
public class EditToolModel
{
public Tools tool;
public IEnumerable<Tools> tools { get; set; }
public ToolsExtention tool_extention;
public string latest_version { get; set; }
public string latest_version_type { get; set; }
public string latest_devStep { get; set; }
public IEnumerable<ToolVersionsView> versions { get; set; }
public IEnumerable<DevelopmentStep> developmentSteps { get; set; }
}
Index.cshtml
#model EditToolModel
#{
ViewBag.Title = "Index";
Layout = "~/Layout/_Layout.cshtml";
}
#Html.Partial("ToolOverview", this.Model)
ToolOverview.cshtml
#model EditToolModel
#using (Html.BeginForm("EditToolOverview", "Tool", FormMethod.Post))
{
<div class="contend">
#Html.TextBoxFor(Model => Model.tool_extention.a)
#Html.TextBoxFor(Model => Model.tool_extention.b)
<input type="submit" name="tool_submit" value="Submit"/>
</div>
}
You need to have a getter/setter on the tool_extention property in order for the DefaultModelBinder to work
public ToolsExtention tool_extention { get; set; }
Ditto for the tool property (but your only rendering controls for the tool_extention property in your view)
ToolsExtention Try changing the EditToolOverview property from EditToolModel to ToolsExtention in the form post method.
[HttpPost]
public ActionResult EditToolOverview(ToolsExtention myModel)
{
//_devProv.changeToolExtention(myModel);
return RedirectToAction("Index", "Tool", new { show = "overview" });
}
I am relatively new to ASP.NET MVC and I find myself a bit on a stick wicket or rather, in a soup kinda situation. This is a length description so please bear with me. And I'm sorry if this seems a bit long and boring :). So, here's my problem :
This is my model.
public class SocialAccount
{
public int SocialAccountID { get; set; }
public int UserID { get; set; }
public int SocialSiteID { get; set; }
public string SocialAccountUsername { get; set; }
public string SocialAccountUserID { get; set; }
public string OAuthToken { get; set; }
public string Captcha { get; set; }
public string UserCaptchaValue { get; set; }
}
public class SocialSitePost
{
public int PostID { get; set; }
public string PostContent { get; set; }
public string PostAttachments { get; set; }
public List<SocialSite> SelectedSocialSites { get; set; }
public List<SocialAccount> SocialAccount { get; set; }
}
public class SocialSite : Audit
{
public int SocialSiteID { get; set; }
public string SocialSiteName { get; set; }
}
When a user is successfully authenticated, I store some user details in session and redirect to the home page. This is the code for that:
//action method in some Controller
public Login()
{
//Authenticate user
//Get all social account related information
SomeRepository someRepository = new SomeRepository();
List<SocialAccount> socialAccountDetails = someRepository.SomeMethod(user.UserID);
//Add social account related information to session
HttpHelper.StoreInSession("UserDetails", socialAccountDetails);
//redirect to HomePage
return RedirectToAction("HomePage", "Account");
}
In the HomePage action method, I retrieve the user object from session and check the registered social accounts. I also create a list object of SocialSite to maintain a list of all registered social sites. I then pack it in ViewData and send it to the view. This is the code for that:
//action method in some other controller
public ActionResult HomePage()
{
List<SocialSite> allSocialSites = null;
List<SocialAccount> userSocialAccountDetails = HttpHelper.RetrieveFromSession("UserSocialSiteDetails") as List<SocialAccount>;
if (userSocialAccountDetails != null && userSocialAccountDetails.Count != 0)
{
allSocialSites = new List<SocialSite>();
bool hasFacebookAccount = userSocialAccountDetails.Exists(x => x.SocialSiteID == Convert.ToInt32(CommonConstants.SocialSite.Facebook));
if (hasFacebookAccount)
{
allSocialSites.Add(new SocialSite() { SocialSiteID = 1, SocialSiteName = "Facebook" });
}
bool hasTwitterAccount = userSocialAccountDetails.Exists(x => x.SocialSiteID == Convert.ToInt32(CommonConstants.SocialSite.Twitter));
if (hasTwitterAccount)
{
allSocialSites.Add(new SocialSite() { SocialSiteID = 2, SocialSiteName = "Twitter" });
}
}
ViewData["SocialSites"] = allSocialSites;
return View();
}
I don't have a strongly-typed view. What I need to do is post the user response. So I create a form for POSTing. Now within this form, I want to display a checkbox for all the registered social accounts (ViewData would give me this info). So, lets say, if user A registered only a Facebook account, then only 1 checkbox representing Facebook should be visible. If user B registered a Facebook, Twitter and Instagram account, then 3 checkboxes should be visible one representing each of these social accounts. I guess you get the idea. This is my code for that:
#model SocialSitePost
#{
using (Html.BeginForm("ProcesssRequest", "Account", FormMethod.Post))
{
<div class="divProcessRequest">
<br />
<div>
#Html.TextAreaFor(model => model.PostContent)
</div>
<div>
#foreach (var socialSite in ViewData["SocialSites"] as List<SocialSite>)
{
#Html.CheckBox("SocialSiteID", new { value = socialSite.SocialSiteID, #checked = true });
#Html.Label(socialSite.SocialSiteName)
} //Tried this..And am able to display the checkbox
#*#for (int i = 0; i < Model.SelectedSocialSites.Count; i++)
{
#Html.CheckBoxFor("SocialSiteID", new { value = Model.SelectedSocialSites[i].SocialSiteID, #checked = true });
}*# //Tried this too..I know this shouldn't work and rightly so, it doesn't work :)
</div>
<br />
<div>
<input type="submit" id="btnPost" value="Post" />
</div>
</div>
}
}
Enough said!!! Now my real problem:
When the user selects any checkbox, I want to populate the SelectedSocialSites property of the SocialSitePost object. This is the model whose object the form is posting back. I need to be able to access the SelectedSocialSites property in the POST method. This is how my POST method is :
[HttpPost]
public ActionResult ProcessRequest(SocialSitePost post)
{
if (ModelState.IsValid)
{
List<SocialSite> allSocialSites = ViewData["SocialSites"] as List<SocialSite>; //Can't get anything here
int socialSiteNo = post.SelectedSocialSites.SocialSiteID; //This is what I want to be able to do
return View("HomePage");
}
}
Since, I am relatively new to ASP.NET MVC, I'm not really sure if this is the right way of doing this. I did try out a few things like EditorFor, trying to send the SocialSitePost object the first time the view is rendered (I don't want to do this as it doesn't make any logical sense).
Can someone tell me how I can get the SelectedSocialSites property of the SocialSitePost class populated in the POST method based on the checkbox selections made by the user?
Also, can someone tell me if I am doing something wrong here as I haven't found any questions here so far on SO which seem similar to this kind of situation?
The main problem here is that the model is not completely suitable for what needs to be displayed. That is, the format of the model with respect to the view and its representation at the backend is different. Hence, a ViewModel needs to be used here. This is what solved my issue.
These were the ViewModels I ended up designing:
public class SocialSiteViewModel : SocialSite
{
public bool IsSelected { get; set; }
public string SocialSitePostID { get; set; }
}
public class SocialSitePostViewModel : SocialSitePost
{
public List<SocialSiteViewModel> SocialSiteViewModel { get; set; }
}
And then I could easily use them on the view as such:
using (Html.BeginForm("ActionMethodName", "ControllerName", FormMethod.Post))
{
#Html.CheckBoxFor(x => x.SocialSiteViewModel[i].IsSelected)
#Html.HiddenFor(x => x.SocialSiteViewModel[i].SocialSiteID)
#Html.HiddenFor(x => x.SocialSiteViewModel[i].SocialSiteName)
}
I'm rendering a PartialView via an Action on my controller.
This is sending a model to the partial which then populates a sub-list for each parent that the partial goes into.
Some of the parent objects don't have children.
I need to capture an Id from the model in the partial to link the sub-list into an Accordion control.
How do I prevent a null reference exception when the child model is empty?
Is there any way to send the ID direct from the Action?
Current attempt...
#using BootstrapSupport
#model IEnumerable<WhatWorks.ViewModels.FamilyListViewModel>
#{ if (string.IsNullOrEmpty(Model.FirstOrDefault().familyId.ToString()))
{
do something...
}
else
{
int modelIndex = Model.FirstOrDefault().familyId;
Controller Action
public ActionResult Index(int Id)
{
var model = GetDisplay(Id).OrderBy(i => i.dob).AsEnumerable();
return PartialView("_family", model);
}
Main View
var family = model.GetIdValue();
<div class="accordion" id="#Html.Raw("accordion")#family.Values.FirstOrDefault()#Html.Raw("_b")">
#Html.Action("Index", "Family", new { Id = family["Id"] })
</div>
ViewModel
public partial class FamilyListViewModel
{
public int Id { get; set; }
public int familyId { get; set; }
public string name { get; set; }
etc...
}
Then do this :
#{ if (Model.Count() >0 )
{
do something...
}