Need to get value from DropDownListFor asp.net mvc - c#

I have combobox in view and I need to get select value in combobox.
Code View:
#Html.DropDownListFor(model => model.servicesModel, (SelectList)ViewBag.serviceNames, new { #id = "listNames" })
Code action that added values in combobox(I know, I missed the symbol in database when created table):
var servicesDetails = dbModel.SERVICES.ToList();
ViewBag.serviceNames = new SelectList(servicesDetails, "iIdSevices", "vName");
I have form, press button and after that thanks to #using (Html.BeginForm("SendApplication", "Home", FormMethod.Post)) I send data to My actionResult.
My ActionResult:
[HttpPost]
public ActionResult SendApplication(App_AppTemp_Serv_PersInfModel appFile, int iIdServices)
{
int iIdService = 0;
var serviceDetails = dbModel.SERVICES.Where(x => x.iIdSevices == iIdServices).FirstOrDefault();
iIdService = serviceDetails.iIdSevices;
if (bFile == true)
{
appFile.appModel.vFile = "Приклепленные файлы имеются";
}
else
{
appFile.appModel.vFile = "Приклепленных файлов нет";
}
appFile.appModel.vDate = Convert.ToString(DateTime.Now);
try
{
dbModel.APPLICATIONS.Add(appFile.appModel);
dbModel.SaveChanges();
ModelState.Clear();
}
catch (Exception exc)
{
ViewBag.sErrorMessage = exc.Message;
}
return View("~/Views/Home/ProblemForm.cshtml", appFile);
}
But I can't to get the data from combobox, I don't know how?! Maybe use class and get class value, anyone have a idea for this?

Hi you can get the data from dropdownlist using the name of that control. It seems that in your example model.servicesModel will be the name of dropdownlist. so in your controller get data using that property .
for ex: Assuming App_AppTemp_Serv_PersInfModel is your model, if no, change it accordingly
[HttpPost]
public ActionResult SendApplication(App_AppTemp_Serv_PersInfModel appFile, int iIdServices)
{
//dropdownlist selected value
string selectedvalue = appFile.servicesModel
//other code
}
Hope it was helpful
Thanks
Karthik

Related

How to return the main view in another action within same controller?

So I'm struggling to tackle the following problem:
I have a main view called ApiBroker, in this view there are several methods to do something with the input from this view.
For example:
[HttpPost]
public ActionResult AddApi(ApiRedirect model)
{
var data = model;
try
{
List<ApiRedirect> list = dbProducts.ApiRedirects.ToList();
int companyID = dbProducts.Companies.Where(x => x.CompanyName == model.Company.CompanyName).FirstOrDefault().CompanyID;
int mappingID = dbProducts.MappingNames.Where(x => x.Name == model.MappingName.Name).FirstOrDefault().MappingID;
ApiRedirect api = new ApiRedirect();
api.ApiName = model.ApiName;
api.CompanyID = companyID;
api.ApiURL2 = model.ApiURL2;
api.MappingID = mappingID;
api.ResponseType = model.ResponseType;
dbProducts.ApiRedirects.Add(api);
dbProducts.SaveChanges();
return View();
}
catch (Exception ex){
throw ex;
}
}
This view should return the main View(Index) but instead of doing that its trying to return the View "AddApi" which does not exist. Error:
With the code above, the data gets inserted into my database but its returning me a 500 error.
What I've tried:
I've tried returning my View hard coded like this: return View("~/Views/ApiBroker/Index.cshtml"); but this gives me an error in my WebGrid.
I've also tried using "Return View("Index")", however this is me the following error in my WebGrid:
I've also tried "return View("Index",YourModel);", this is giving me the following error:
Hope someone can help!
You can return a particular View if they belong to the same Controller like this:
return View("Index");
If the View belongs to a different Controller, then you would simply have to specify the name of the View and its folder name and call it like this:
return View("../ControllerName/Index");
return RedirectToAction("YourAction");
or
return RedirectToRoute("YourRouteName");

How to setup gridview in mvc

I would like to setup gridview under MyTickets tab.
How can I set this view to have only tickets from username eg 'testuser' ?
In controller I have below code. Table Zgloszenia is my table where I storing all information about tickets (date,username, id etc)
public ActionResult MyTickets(Zgloszenia model)
{
if (Session["UserID"] != null)
{
test dg = new test();
var item = dg.Zgloszenia.Where(x => x.UsrUsera == model.UsrUsera).SingleOrDefault();
return View(item);
}
else
{
return RedirectToAction("Login");
}
}
In view I have this code:
#model IEnumerable<Webform.Models.Zgloszenia>
#{
ViewBag.Title = "MyTickets";
WebGrid grid = new WebGrid(Model);
}
<h2>MyTickets</h2>
#if (Session["UserID"] != null)
{
<div>
Welcome: #Session["Username"]<br />
</div>
}
#grid.GetHtml(columns: new[] {
grid.Column("Opis"),
grid.Column("Priorytet"),
grid.Column("Srodowisko"),
grid.Column("NumerTaska"),
grid.Column("test"),
grid.Column("Date")
})
When I log in to my app and click Tab "MyTicket" I'm receiving below error:
A data source must be bound before this operation can be performed.
How I can fix this issue and set up view properly ?
In your action you are selecting a single item, not a collection to enumerate. On the contrary, the WebGrid expects a collection as a data source, so the way you declared things on the view is fine.
To check if that is indeed the issue, simply remove SingleOrDefault call in your action. If your Where call returns at least one record, you should be able to see it on the page:
test dg = new test();
var items = dg.Zgloszenia.Where(x => x.UsrUsera == model.UsrUsera).ToList();
return View(items);
Are you working with Visual studio? If yes, you have to make a dataset. (local or online) You do not have a database at the moment so he saves it nowhere.

ASP .NET MVC overriding when edit while multiple records are opened at once in different tabs-

My custom MVC web application has an overriding problem. I have custom edit page and im edditing university teachers, so they all have a profile picture. This is my edit controller which loads the view.
public ActionResult Edit(int? id)
{
if (cf.CheckDBConnection() != true)
{
return View("~/Views/Error/NoDBConnection.cshtml");
}
if (checksession.CheckSessionState() != 1)
{
return View("~/Views/Error/NotAdmin.cshtml");
}
if (id == null)
{
return View("~/Views/Error/BadRequest.cshtml");
}
var disciplina = db.tblDisciplines.ToList();
ViewBag.disciplina = disciplina;
var specialies = db.tblSpecialities.ToList();
ViewBag.specialty = specialies;
var Ischecked = db.tblTeachersDisciplines.Where(p => p.TeacherID == id).Select(p => p.DisciplineID).ToArray();
ViewBag.Checked = Ischecked;
tblTeacher tblTeacher = db.tblTeachers.Find(id);
var IscheckedSpec = db.tblTeachersSpecialities.Where(p => p.TeacherID == tblTeacher.ID).Select(p => p.SpecialityID).ToArray();
ViewBag.CheckedSpec = IscheckedSpec;
TempData["Photo"] = tblTeacher.ProfilePicture;
if (tblTeacher == null)
{
return View("~/Views/Error/NotFound.cshtml");
}
var department = tblTeacher.TDepartment;
ViewBag.department = department;
return View(tblTeacher);
}
This is the controller that runs after clicking "save"
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ID,FirstName,SecondName,Title,PersonalCabinet,Laboratory,TelNum,Email,VisitingHours,PersonalInterests,TDepartment,ProfilePicture")] tblTeacher tblTeacher, HttpPostedFileBase file, int[] discipline, int[] specialty, string department)
{
var disciplina = db.tblDisciplines.ToList();
ViewBag.disciplina = disciplina;
var specialies = db.tblSpecialities.ToList();
ViewBag.specialty = specialies;
var Ischecked = db.tblTeachersDisciplines.Where(p => p.TeacherID == tblTeacher.ID).Select(p => p.DisciplineID).ToArray();
ViewBag.Checked = Ischecked;
var IscheckedSpec = db.tblTeachersSpecialities.Where(p => p.TeacherID == tblTeacher.ID).Select(p => p.SpecialityID).ToArray();
ViewBag.CheckedSpec = IscheckedSpec;
tblTeacher.TDepartment = department;
if (department == null || department == "")
{
ModelState.AddModelError("", "Изберете факултет");
return View(tblTeacher);
}
if (!ModelState.IsValid)
{
return View(tblTeacher);
}
if (discipline == null)
{
ModelState.AddModelError(string.Empty, "Моля, изберете дисциплини");
return View(tblTeacher);
}
if (specialty == null)
{
ModelState.AddModelError(string.Empty, "Моля, изберете специалност");
return View(tblTeacher);
}
try
{
var _photo = TempData["Photo"];
if (file != null)
{
if (file.ContentLength > 0 && file.ContentLength < 1000000 && file.ContentType == "image/jpeg")
{
byte[] imageBytes = null;
BinaryReader reader = new BinaryReader(file.InputStream);
imageBytes = reader.ReadBytes((int)file.ContentLength);
_photo = imageBytes;
}
else
{
ModelState.AddModelError(string.Empty, "Профилната снимка е задължителна и трябва да отговаря на описаните условия!");
return View(tblTeacher);
}
}
tblTeacher.ProfilePicture = (byte[])_photo;
db.Entry(tblTeacher).State = EntityState.Modified;
db.tblTeachersDisciplines.Where(p => p.TeacherID == tblTeacher.ID).ToList().ForEach(p => db.tblTeachersDisciplines.Remove(p));
db.tblTeachersSpecialities.Where(p => p.TeacherID == tblTeacher.ID).ToList().ForEach(p => db.tblTeachersSpecialities.Remove(p));
db.SaveChanges();
for (int i = 0; i < discipline.Length; i++)
{
using (RSEntities entities = new RSEntities())
{
tblTeachersDiscipline TD = new tblTeachersDiscipline
{
TeacherID = tblTeacher.ID,
DisciplineID = discipline[i]
};
entities.tblTeachersDisciplines.Add(TD);
entities.SaveChanges();
}
}
for (int i = 0; i < specialty.Length; i++)
{
using (RSEntities entities = new RSEntities())
{
tblTeachersSpeciality TS = new tblTeachersSpeciality
{
TeacherID = tblTeacher.ID,
SpecialityID = specialty[i],
};
entities.tblTeachersSpecialities.Add(TS);
entities.SaveChanges();
}
}
return RedirectToAction("Index");
}
catch (Exception ex)
{
DateTime currentTime = DateTime.Now;
string _error = ex.ToString();
_error = currentTime + " Exception: " + _error;
SendMailOnErrorService mail = new SendMailOnErrorService();
mail.Sendemail(_error);
return View("~/Views/Error/DataBaseError.cshtml");
}
}
The problem seems to occur in this current scenario:
When i open many "Edit" tabs and i save all of them, they all change their profile picture with the one from the last tab opened.
I reckon the problem comes fromTempData["Photo"] = tblTeacher.ProfilePicture;
as it probably takes the picture from the last tab opened and then when I save a tab it applies it to the current teacher profile.
I use TempData["Photo"] = tblTeacher.ProfilePicture; because if I dont, when I edit-save a profile it erases the profilepicture from the database as it comes as null from the view and the controller on its behalf inserts null in the column from the DB.
One of the solutions may be not using TempData at all but what I want to know is why the problem occurs and how it can be solved while still using TempData
PS - I've done some testing and its 100% sure the problem is with TempData
The key string you are using for for TempData is "Photo". The value for returned from TempData for key "Photo" is whatever you last set it to in your HttpGet Edit method. If you have multiple Edit tabs open, the value for TempData["Photo"] will be whatever you last set it to for the last Edit tab open.
If you want to use TempData for each open Edit tab you would need a unique key for each Edit tab like so:
Edit tab 1: TempData["EditTab1_Photo"]
Edit tab 2: TempData["EditTab2_Photo"]
And so on.
And a unique TempData key for each Edit View request is not easy to do, you will have to generate a unique TempData key for each HTTP request and somehow know which key to use in the HttpPost Edit HTTP requests. Challenging and overly complex solution this is.
You do not have a ViewModel for your View and that is what you need, you should stop using TempData right away, see below for what TempData is used for.
The way to solve this problem is a standard ViewModel, an essential core tenant of how MVC data sharing is done between a View and a Controller. A Teacher ViewModel, which will have a byte Photo {get;set;} property among other properties that relate, mostly 1 to 1 in type and name as your tblTeacher entity,thus a unique instance of that Teacher ViewModel will be what is passed back and forth for each open Edit tab.
Currently you are sending the data Entity (tblTeacher) directly to the View which is not ever correct in a MVC design pattern. Your View should not depend on a persistence (database) Entity structure/representation, a structure which will change in the future and when that happens, it should not break your View, your View should depend on a ViewModel which translates your Entity into a structure specific to the View, the controller has the responsibility of translating/mapping the structure of the Entity and the ViewModel back and forth between HTTP requests.
A quote and article for you of what TempData is used for:
"TempData, on the other hand, is geared specifically for working with data on HTTP redirects, so remember to be cautious when using TempData."
http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp-net-mvc-3-applications/

what is the correct place to put code that reoccurs on every page in MVC

In my mvc solution I was originally using a viewModel to hold an IEnumerable of SelectListItems. These would be used to populate a dropdownfor element like below
#Html.DropDownListFor(model => model.Type, Model.PrimaryTypeList, new { data_acc_type = "account", data_old = Model.Type, #class = "js-primary-account-type" })
the problem being that whenever I had to return this view, the list would need re-populating with something pretty heavy like the following:
if(!ModelState.IsValid){
using (var typeRepo = new AccountTypeRepository())
{
var primTypes = typeRepo.GetAccountTypes();
var primtype = primTypes.SingleOrDefault(type => type.Text == model.Type);
model.PrimaryTypeList =
primTypes
.Select(type => new SelectListItem()
{
Value = type.Text,
Text = type.Text
}).ToList();
}
return View(model);
}
It seemed silly to me to have to rewrite - or even re-call (if put into a method) the same code every postback. - the same applies for the ViewBag as i have about 6 controllers that call this same view due to inheritance and the layout of my page.
At the moment i'm opting to put the call actually in my razor. but this feels wrong and more like old-school asp. like below
#{
ViewBag.Title = "Edit Account " + Model.Name;
List<SelectListItem> primaryTypes = null;
using (var typeRepo = new AccountTypeRepository())
{
primaryTypes =
typeRepo.GetAccountTypes()
.Select(t => new SelectListItem()
{
Value = t.Text,
Text = t.Text
}).ToList();
}
#Html.DropDownListFor(model => model.Type, primaryTypes, new { data_acc_type = "account", data_old = Model.Type, #class = "js-primary-account-type" })
Without using something completely bizarre. would there be a better way to go about this situation?
UPDATE: While semi-taking onboard the answer from #Dawood Awan below. my code is somewhat better, still in the view though and i'm 100% still open to other peoples ideas or answers.
Current code (Razor and Controller)
public static List<SelectListItem> GetPrimaryListItems(List<AccountType> types)
{
return types.Select(t => new SelectListItem() { Text = t.Text, Value = t.Text }).ToList();
}
public static List<SelectListItem> GetSecondaryListItems(AccountType type)
{
return type == null?new List<SelectListItem>(): type.AccountSubTypes.Select(t => new SelectListItem() { Text = t.Text, Value = t.Text }).ToList();
}
#{
ViewBag.Title = "Add New Account";
List<SelectListItem> secondaryTypes = null;
List<SelectListItem> primaryTypes = null;
using (var typeRepo = new AccountTypeRepository())
{
var primTypes = typeRepo.GetAccountTypes();
primaryTypes = AccountController.GetPrimaryListItems(primTypes);
secondaryTypes = AccountController.GetSecondaryListItems(primTypes.SingleOrDefault(t => t.Text == Model.Type));
}
}
In practice, you need to analyse where you app is running slow and speed up those parts first.
For starters, take any code like that out of the view and put it back in the controller. The overhead of using a ViewModel is negligible (speed-wise). Better to have all decision/data-fetching code in the controller and not pollute the view (Views should only know how to render a particular "shape" of data, not where it comes from).
Your "Something pretty heavy" comment is pretty arbitary. If that query was, for instance, running across the 1Gb connections on an Azure hosted website, you would not notice or care that much. Database caching would kick in too to give it a boost.
Having said that, this really is just a caching issue and deciding where to cache it. If the data is common to all users, a static property (e.g. in the controller, or stored globally) will provide fast in-memory reuse of that static list.
If the data changes frequently, you will need to provide for refreshing that in-memory cache.
If you used IOC/injection you can specific a single static instance shared across all requests.
Don't use per-session data to store static information. That will slow down the system and run you out of memory with loads of users (i.e. it will not scale well).
If the DropDown Values don't change it is better to save in Session[""], then you can access in you View, controller etc.
Create a class in a Helpers Folder:
public class CommonDropDown
{
public string key = "DropDown";
public List<SelectListItem> myDropDownItems
{
get { return HttpContext.Current.Session[key] == null ? GetDropDown() : (List<SelectListItem>)HttpContext.Current.Session[key]; }
set { HttpContext.Current.Session[key] = value; }
}
public List<SelectListItem> GetDropDown()
{
// Implement Dropdown Logic here
// And set like this:
this.myDropDownItems = DropdownValues;
}
}
Create a Partial View in Shared Folder ("_dropDown.cshtml"):
With something like this:
#{
// Add Reference to this Folder
var items = Helpers.CommonDropDown.myDropDownItems;
}
#Html.DropDownList("ITems", items, "Select")
And then at the top of each page:
#Html.Partial("_dropDown.cshtml")

pass model from one action to another action in same controller

I am trying to pass my model List< Models.Statement > statementList from one action to another but i am receiving null value in the 2nd controller. Please suggest what is wrong here. Even tried with:
return RedirectToAction("WriteInTemplate", new { statementList = statementList });
Please help.
public ActionResult SendPdfStatement(string InvoiceNumber)
{
try
{
InvoiceNumber = InvoiceNumber.Trim();
ObjectParameter[] parameters = new ObjectParameter[1];
parameters[0] = new ObjectParameter("InvoiceNumber", InvoiceNumber);
List<Models.Statement> statementList = new List<Models.Statement>();
statementList = _db.ExecuteFunction<Models.Statement>("uspInvoiceStatement", parameters).ToList<Models.Statement>();
//WriteInTemplate(statementList);
return RedirectToAction("WriteInTemplate", statementList );
}
catch (Exception e)
{
InvoiceSearchTool.Models.udtExceptionTable exception = new udtExceptionTable();
exception.MethodName = "SendPdfStatement";
exception.Exception = e.ToString();
exception.Date = DateTime.Now;
DYNAMICS_EXTEntities db = new DYNAMICS_EXTEntities();
db.AddToudtExceptionTables(exception);
db.SaveChanges();
return View("Error");
}
}
public ActionResult WriteInTemplate(List<Models.Statement> statementList)
{
try
{
string invoiceNumber = statementList.FirstOrDefault().Invoice.ToString().Trim();
...................snip..........
return RedirectToAction("CreateMessageWithAttachment", "email", invoiceNumber);
}
catch (Exception e)
{
InvoiceSearchTool.Models.udtExceptionTable exception = new udtExceptionTable();
exception.MethodName = "WriteInTemplate";
exception.Exception = e.ToString();
exception.Date = DateTime.Now;
DYNAMICS_EXTEntities db = new DYNAMICS_EXTEntities();
db.AddToudtExceptionTables(exception);
db.SaveChanges();
return View("Error");
}
}
Please take a look here to pass your Model
you are not passing "statementList" , instead you are passing new { statementList= statementList} just pass the model and you should be fine .
return RedirectToAction("WriteInTemplate", statementList);
Answer by sino
RedirectToAction() writes a redirect command to the browser, making it start a brand new request to WriteInTemplate(). Your model object is therefore lost.
Is WriteInTemplate() an independent action which will sometimes be responsible for an entire request from a user or a partial request from a view? If not, you should just call it as a regular method instead of using RedirectToAction().
This is because you had spefified wrong route parameters.
while thinking about this.. did you check that the data are not null?
you are using
return RedirectToAction("WriteInTemplate", statementList );
instead you should use
return RedirectToAction("WriteInTemplate","controllerName", new{"statementList"=stetementList});
see reference here
The way you call the RedirectToAction() method may not be your issue.
For me, the solutions presented above did not work because the RedirectToAction() method builds a RouteValueDictionary by using the .ToString() value of each property in the model. This will only work if all the properties in the model are simple properties and it fails if any properties are complex objects, lists, collections, etc.
because this method does not use recursion.
If for example, a model called MymodelOrganization contained a property List Employees, then that property would result in a query string value of
....&Employees=System.Collections.Generic.List'1[System.String]
and binding would fail, and you would end up (as was my case) with ... null
I had this problem, so I created a copy of my model containing only the elements of the form, stripping my Lists and passed that inside RedirectToAction().
Once on the other action method, I was able to re-assemble my Lists and added them to my Model before calling the last return. Good luck. Here is the idea in my code:
[HttpPost]
public ActionResult ItemSubmissionForm(CombinedModelContent membervalues)
{ ...
ItemSubmissionsDBFields aFieldsList = membervalues.FieldsList; //Stripping other objects
return RedirectToAction("ItemSubmissionConfirm", aFieldsList);
}
[HttpGet]
public ActionResult ItemSubmissionConfirm(ItemSubmissionsDBFields aFieldsList)
{ ...
List<SomeArea> SomeAreaitems = new List<SomeArea>();
SomeAreaitems.Add ...
CombinedModelContent copymembervalues = new CombinedModelContent();
copymembervalues.SomeCodeLists = SomeAreaitems;
copymembervalues.FieldsList = aFieldsList;
return View("SomeConfirmPage", copymembervalues);

Categories

Resources