I am developing MVC application.
I am trying to pass the data from one method to another method in same controller.
But data doesn't pass properly...
Please check below code... I am trying to pass the Product list from Create to Save data method.
namespace StockWatchScreen.Controllers
{
public class OrderController : Controller
{
public class OrderProduct
{
public string SectionCode { get; set; }
public double Size { get; set; }
public double Thickness { get; set; }
public double Length { get; set; }
public double Quantity { get; set; }
}
public ActionResult Create()
{
List<OrderProduct> oProductList = new List<OrderProduct>();
OrderProduct oProduct = new OrderProduct();
oProduct.SectionCode = "123";
oProduct.Length = "123";
oProduct.Size = "123";
oProduct.Thickness = "123";
oProduct.Quantity = "123";
oProductList.Add(oProduct);
}
return RedirectToAction("SaveData", oProductList);
}
public ActionResult SaveData(List<OrderProduct> oProductList)
{
ViewBag.ProductList = oProductList;
ViewBag.OrderNo = "12321#";
return View();
}
}
}
}
In SaveData method, oProductList list shows always null.
What is reason ?
You need to return :return SaveData( oProductList); .You don't need to return RedirectToAction , and try to avoid using TempData["oProduct"] using TempData in mvc is not good practice.
Using AjaxBeginForm you on succes you can get result return SaveData( oProductList);and put it where you want .also you can use UpdateTargetId.
You can't send model like this in RedirectToAction, you should use tempdata for this communicating between actions like this
public ActionResult Create()
{
List<OrderProduct> oProductList = new List<OrderProduct>();
OrderProduct oProduct = new OrderProduct();
oProduct.SectionCode = "123";
oProduct.Length = "123";
oProduct.Size = "123";
oProduct.Thickness = "123";
oProduct.Quantity = "123";
oProductList.Add(oProduct);
}
TempData["oProduct"] = oProductList;
return RedirectToAction("SaveData");
}
And in the recieving controller
public ActionResult SaveData(List<OrderProduct> oProductList)
{
ViewBag.ProductList = TempData["oProduct"] as List<OrderProduct> ;
ViewBag.OrderNo = "12321#";
return View();
}
This is because RedirectToAction is doing a 301 redirection, and it is actually the client initiating a Get request to the /SaveData action.
Related
I have a Model that gets sent to a view. This model has List elements that are used to populate listboxes. In this view, I post to a controller action passing in my model as a parameter. On postback, I can see primitive types, but, can't seem to access the list. Here's my code:
Model:
public class ReportInfoViewModel
{
public int report_id { get; set; } = 0;
public string report_name { get; set; } = "";
public string report_path { get; set; } = "";
public string plaza_param { get; set; } = "y";
public List<FacilityViewModel> facilitieslist { get; set; } = new List<FacilityViewModel>();
}
public class FacilityViewModel
{
public string facility_id { get; set; }
public string facility_name { get; set; }
}
View:
#model CSC.ViewModels.ReportInfoViewModel
#using (Html.BeginForm("ViewReport", "Reports", Model, FormMethod.Post, new { target = "_blank" }))
{
if (#Model.plaza_param.ToString().ToLower().Equals("y"))
{
#Html.DevExpress().ListBox(
l =>
{
l.Name = "lstPlazaParam";
l.Width = Unit.Pixel(300);
l.Height = Unit.Pixel(120);
l.Properties.SelectionMode = ListEditSelectionMode.CheckColumn;
l.Properties.EnableSelectAll = true;
l.Properties.TextField = "facility_name";
l.Properties.ValueField = "facility_id";
l.SelectedIndex = 0;
l.Properties.ValueType = typeof(string);
l.Properties.ValidationSettings.RequiredField.IsRequired = true;
l.Properties.ValidationSettings.RequiredField.ErrorText = "Please select a Plaza";
l.Properties.ValidationSettings.ErrorText = l.Properties.ValidationSettings.RequiredField.ErrorText;
l.Properties.ValidationSettings.ErrorTextPosition = ErrorTextPosition.Bottom;
l.Properties.ValidationSettings.Display = Display.Dynamic;
l.Properties.ValidationSettings.ErrorDisplayMode = ErrorDisplayMode.ImageWithText;
}).BindList(Model.facilitieslist).GetHtml();
ViewContext.Writer.WriteLine("<br />");
}
Controller:
[HttpPost]
[Authorize]
public ActionResult ViewReport(ReportInfoViewModel _model)
{
string _parameterList = "";
ReportViewerViewModel _rptObj = new ReportViewerViewModel();
if (_model.plaza_param.ToLower().Equals("y"))
{
string[] _selected = DevExpress.Web.Mvc.ListBoxExtension.GetSelectedValues<string>("lstPlazaParam");
string subParam = "plazaparam=";
subParam += String.Join(",", _selected);
_parameterList = string.Concat(_parameterList, "#", subParam);
_parameterList = string.Concat(_parameterList, "#usrplazaparam=", getSelectedPlazaDisplayValues(_model.facilitieslist, _selected));**//here, _model.facilitieslist is null**
}
return View("AfterView", _rptObj);
}
What I am trying to do is on post back, send the model back to the controller. All primitive types are sent back, except the list types. How do I send back a list model on post? Any help is appreciated.
I was able to create a hidden field in my view serializing the list and storing it in the hidden field.
#using (Html.BeginForm("ViewReport", "Reports", Model, FormMethod.Post, new { target = "_blank" }))
{
string facilitiesListJson = Newtonsoft.Json.JsonConvert.SerializeObject(#Model.facilitieslist);
#Html.Hidden("FacilitiesList", facilitiesListJson);
//other form objects
}
In my controller action, I deserialized the hidden field(Request.Form) and access the list.
string _jsonString = Request.Form["FacilitiesList"];
List<FacilityViewModel> _objList = JsonConvert.DeserializeObject<List<FacilityViewModel>>(_jsonString);
Here's my view code:
#model pedidosOnlineMVC.Models.ViewModel.AdmView
#using pedidosOnlineMVC.Models
#{
Layout = "~/Views/Administrador/_LayoutAdm.cshtml";
List<Usuario> lu = pedidosOnlineMVC.Controllers.UsuarioController.favoreds(Model.adm.estabelecimento.Estabelecimento_Id);
}
#using (var f = Html.Bootstrap().Begin(new Form()))
{
using (var p = Html.Bootstrap().Begin(new Panel()))
{
using (var t = Html.Bootstrap().Begin(new Table()))
{
using (var h = t.BeginHeader())
{
using(var hr = h.BeginHeaderRow())
{
#hr.Cell("Usuário")
#hr.Cell("Status")
}
}
using(var b = t.BeginBody())
{
for(int i=0;i<lu.Count;i++)
{
using(var c = b.BeginRow())
{
#f.FormGroup().CustomControls(Html.HiddenFor(model => model.Usuario_Id[i], lu[i].Usuario_Id))
#c.Cell(lu[i].nome)
#c.Cell(f.FormGroup().CustomControls(Html.Bootstrap().CheckBoxFor(model=>model.checkAuts[i])))
}
}
}
}
using (var pf = p.BeginFooter())
{
#f.FormGroup().CustomControls(#Html.HiddenFor(model => model.adm.Administrador_Id, Model.adm.Administrador_Id))
#f.FormGroup().CustomControls(Html.Bootstrap().SubmitButton().Text("Autorizar"))
}
}
}
And I had a similar problem here: cshtml page not passing date value on post, but what I did then doesn't work here.
I tried looking in the network window in the developer tools and I can see the ID values (Administrador_ID and Usuario_ID) being sent on post, but they never reach my controller.
Here's the code for the controller:
[HttpPost]
public ActionResult autCli(AdmView adm)
{
return null;
}
It has no code in it because I still didn't get it to work, but the parameters should still work when debugging, but I get NULL in every attribute instead.
If anyone can help, I'd appreciate it.
AdmView model, as requested:
public class AdmView
{
public Administrador adm { get; set; }
public Produto prod { get; set; }
public virtual List<bool> checkAuts { get; set; }
public virtual List<int> Usuario_Id { get; set; }
}
Try to use the FormCollection to pass data from view to controller.
Just like this:
[HttpPost]
public ActionResult autCli(FormCollection collection)
{
strint Usuario_Id = collection["Usuario_Id"]; //You can get data with this way...
return View();
}
Check this question for more info.
Add [HttpPost] before your ActionResult method.
I need to pass a View Model from one controller to another controller. I used the below statement.
return RedirectToAction("FillNewSession", "Account", new { LoginResult = loginResult });
LoginResult is an object of the model "UserLoginProperties". FillNewSession controller is below.
public ActionResult FillNewSession(UserLoginProperties LoginResult)
{
Session["UserID"] = LoginResult.UserID.ToString();
Session["LoginID"] = LoginResult.LoginID;
Session["UserFullName"] = LoginResult.UserFullName;
Session["UserTypeID"] = LoginResult.UserTypeID;
Session["UserRefNo"] = LoginResult.UserRefNo;
Session["UserNRIC"] = LoginResult.UserNRIC;
return Redirect("~/index.aspx");
}
Problem is when "FillNewSession" controller is executed the passed parameter "LoginResult" is null.
Please Help.
If you want to pass an object through a redirect call you need to send all the properties of the object one by one, as illustrated below. You can't just pass the object as it is.
public class UserLoginProperties
{
public string UserID { get; set; }
public string LoginID { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
var prop = new UserLoginProperties(){ LoginID = "123", UserID = "abc"};
return RedirectToAction("OtherAction", new { UserID=prop.UserID, LoginID=prop.LoginID });
}
public ActionResult OtherAction(UserLoginProperties prop)
{
// do whatever you want with it here
}
}
I am trying to move from webForms to Asp.net-MVC and have some problems. I am trying to figure why this is not working, I am getting this error: "Object reference not set to an instance of an object"
I have the class 'Pages':
namespace _2send.Model
{
public class Pages
{
public string PageContent { get; set; }
public string PageName { get; set; }
public int LanguageId { get; set; }
}
}
I am inserting the value to 'Pages.PageContent' property with this class:
namespace _2send.Model.Services
{
public class PagesService : IPagesService
{
public void GetFooterlinksPage()
{
DB_utilities db_util = new DB_utilities();
SqlDataReader dr;
Pages pages = new Pages();
using (dr = db_util.procSelect("[Pages_GetPageData]"))
{
if (dr.HasRows)
{
dr.Read();
pages.PageContent = (string)dr["PageContent"];
dr.Close();
}
}
}
The Controller method looks like this:
private IPagesService _pagesService;
public FooterLinksPageController(IPagesService pagesService)
{
_pagesService = pagesService;
}
public ActionResult GetFooterLinksPage()
{
_pagesService.GetFooterlinksPage();
return View();
}
I am trying to write the property in the view like this:
#model _2send.Model.Pages
<div>
#Model.PageContent;
</div>
When debugging, the method is fired and the dataReader is inserting the value to the 'PageContent' property, but I am still getting this error from the view.
Thanks!
return View();
You didn't pass a model.
You need to pass the model as a parameter to the View() method.
You need to rewrite service method to return Pages:
public Pages GetFooterlinksPage()
{
DB_utilities db_util = new DB_utilities();
Pages pages = new Pages();
using (var dr = db_util.procSelect("[Pages_GetPageData]"))
{
if (dr.HasRows)
{
dr.Read();
pages.PageContent = (string)dr["PageContent"];
return pages;
// Because you use using, you don't need to close datareader
}
}
}
And then rewrite your action method:
public ActionResult GetFooterLinksPage()
{
var viewmodel = _pagesService.GetFooterlinksPage();
return View(viewmodel);
}
You can return a model:
var viewmodel = new _2send.Model.Pages().
//here you configure your properties
return View(viewmodel);
I'm using jqGrid to display some data on a page. Within the controller action, we're using an anonymous object to represent the data that the jqGrid needs. My question is, is there a way we can create a strongly typed object to represent the jqGrid data that we are sending with Json()?
Main reason for this is so that we can do unit testing with the objects that are being sent to it.
Thanks!
EDIT:
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult GridData(FormCollection form, string alias, string location, string state)
{
int pageSize = Convert.ToInt32(form["rows"]);
int pageIndex = Convert.ToInt32(form["page"]) - 1;
var deviceList = this._device.GetList(CreateFilter(location,alias,state),this._securityCache.GetSecurityContext(),pageSize,pageIndex);
int totalResults = deviceList.TotalRecords;
int totalPages = (int)Math.Ceiling((float)totalResults / (float)pageSize);
var jsonData = new {
total = totalPages,
page = pageIndex + 1,
records = totalResults,
rows = (from device in deviceList.Data
select new {i = device.Alias,cell = new string[]{device.Alias,device.Location,device.RatePlan,device.State,device.DateCreated.ToString()}}).ToArray()
};
return Json(jsonData);
This above here works, but we can't unit test the data that is being passed into the Json() method.
var newJsonData = new JsonJQGridReturnData();
newJsonData.total = totalPages;
newJsonData.page = pageIndex + 1;
newJsonData.records = totalResults;
List<JsonJQGridRow> list = new List<JsonJQGridRow>();
foreach (var device in deviceList.Data)
{
list.Add(new JsonJQGridRow(device.Alias, new string[] { device.Alias, device.Location, device.RatePlan, device.State, device.DateCreated.ToString() }));
}
newJsonData.rows = list.ToArray();
_cookieHelper.SaveCookie("DeviceListIndex", this._securityCache.GetSecurityContext().UserID.ToString(), COOKIE_PAGE_SIZE_KEY, pageSize.ToString());
return Json(newJsonData);
}
Here is my poor attempt at trying to wrap these into strongly typed objects. Unfortunately, running this gives me a "u is undefined" in the jqGrid file. I suspect that this is because the json being passed in is not correctly formatted. Here are the classes....
[DataContract]
public class JsonJQGridReturnData
{
[DataMember]
public int total { get; set; }
[DataMember]
public int page { get; set; }
[DataMember]
public int records { get; set; }
[DataMember]
public JsonJQGridRow[] rows { get; set; }
}
[DataContract]
public class JsonJQGridRow
{
public JsonJQGridRow(string i, string[] columns)
{
this.i = i;
this.cells = columns;
}
[DataMember]
public string i { get; set; }
[DataMember]
public string[] cells { get; set; }
}
If I understand your question you can use Generics to do this:
Model:
// represents one row in the JQGrid
class Customer
{
public string firstname { get; set; }
public string lastname { get; set; }
}
JQGrid class:
class JQGridData<TModel>
{
// add in whatever other properties you want for JQGrid
public int responseTime {get; set; };
public List<TModel> rows = new List<TModel>();
}
Controller Action :
public JsonResult GridData(int page)
{
var gridData = new JQGridData<Customer>();
// Populate your data here, this is just an example:
gridData.rows.Add(new Customer()
{
firstname = "fred", lastname = "pharkas"
});
// return the result
return Json(gridData, JsonRequestBehavior.AllowGet);
}
Result:
{
responseTime: 0
rows: [
{
firstname: "fred"
lastname: "pharkas"
}
]
}
Is that what you were asking?
David,
Here's the kinda thing i use in an app i'm working on at the moment for this type of thing. I know it doesn't provide a strongly typed object as such, but the 'list' could be a part of the model that is then sent ToArray() at the end of the piece.
public JsonResult GridData(int id)
{
// get our messages based on id
var bookingmessagesList = _repository.Find(x => x.ID == id);
var list = new ArrayList();
foreach (var bookingmessage in bookingmessagesList) //populate data containers with read data
{
list.Add(new
{
bookingmessage.ClassRowVersionDate,
bookingmessage.ID,
bookingmessage.BookingID,
bookingmessage.AssignedFrom,
bookingmessage.AssignedTo,
bookingmessage.AssignedDate,
bookingmessage.CompletedDate,
bookingmessage.MessageType,
bookingmessage.Notes
});
}
int totalOjectCount = list.Count;
return Json(new { dataitems = list.ToArray(), totalItems = totalOjectCount });
}
hope it gives you some ideas.. Will be interested to see the suggestions made.
Here's a quick take on a strongly-typed JQGridResult.
public class JQGridResult<T> : JsonResult where T : class
{
public T Model
{
get { return (T)this.Data; }
set { this.Data = value; }
}
}
Used as...
return new JQGridResult<JsonModel> {
Model = new GridModel { ... initialize model here ... }
});
where GridModel is basically a container class holding the strongly typed properties for the grid.
I feel really silly. I had a misspelling in the GridRow that was causing jqGrid to blow up. After I fixed that, I was able to get the jqGrid to work with my strongly typed object...
Now in my unit tests, I can just do...
var result = controllerToTest.GridData(form, null, null, null) as JsonResult;
var data = result.Data as JsonJQGridReturnData;
and now I can access the fields :D