Accurate way of passing data controller to view ASP.NET MVC - asp.net

In my application, to load some data to the view (combo boxes) I have been using TempData. I want to know if it is okay to use TempData for that purpose?
My current code is here; first I called data to a list in controller:
List<Request_Types> RequestTyleList = db.Request_Types.Where(r => r.Status == true).ToList();
List<SelectListItem> ReqTypeDropDown = RequestTyleList.Select(r => new SelectListItem { Text = r.Request_Type, Value = r.Id.ToString() }).ToList();
Then I am assigning this data to TempData:
TempData["RequestTyleList"] = ReqTypeDropDown;
In the view I called that temp data and assigning to the combo box
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
List<SelectListItem> ReqType = (List<SelectListItem>)TempData.Peek("RequestTyleList");
}
-----------------
<div class="form-group row">
#Html.LabelFor(model => model.ReqType, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-sm-8">
#Html.DropDownListFor(model => model.ReqType, ReqTypes, "Select Request Type", new { #class = "js-dropdown" })
#Html.ValidationMessageFor(model => model.ReqType, "", new { #class = "text-danger" })
</div>
</div>
If I want to access those same data in Edit, I again create a list and putting data to the list and transfer to TempData and again call the same data from the view. Still I have 5 to 8 items of data on the list, I want to know when there are 100 items of data in TempData, will my system get slow? Are there any potential performance issues?
While surfing this on the internet, I got that same will do in the Sessions, but I don't know will it be suitable for this? Or else is there any good way to do this without dropping any performance of the system, like in one controller if I call and stores data, I can access those data from any view.

#smc developments, please use below Model and html markup to show dropdown list for users
public class User
{
public int SelectedUserId{get;set;}
public IEnumerable<SelectListItem> Users { get; set; }
}
#Html.DropDownListFor(x => Model.SelectedUserId, new SelectList(Model.Users, "Value", "Text"), htmlAttributes: new { #class = "form-control", id = "User"})

Related

how to configure dropdownlist to return the Title and not id back to the database

I have an asp.net mvc using entity framework web app. A specific table in the app has a text column we want to force users to select entries from a dropdown to avoid spelling issues. There are only two selections, Buy Item and Raw Components. We don't want to go through the trouble of creating an actual table and then relate that table with the original. When creating a new record or editing an existing record I would like to have the selected Text and not the selected ID saved in the record. The reason for this is there are many records in the table already AND a report deck associated with the table that would all have to be updated if the ID was saved back to the record. In the examples I've included below, you see I've used the ViewBag method although the Model method (for me) has the same issues.
To start I created a class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ProdMan4.Models
{
public class ItemTypes
{
public int Id { get; set; }
public string Title { get; set; }
}
}
Added the following to the controller for this table...
private List<ItemTypes> GetITs()
{
var itemtypes = new List<ItemTypes>();
itemtypes.Add(new ItemTypes() {Id = 1, Title = "Buy Item" });
itemtypes.Add(new ItemTypes() {Id = 2, Title = "Raw Components" });
return itemtypes;
}
public ActionResult Create()
{
ViewBag.ItemTypesSelectList = new SelectList(GetITs(),"Id", "Title");
return View();
}
Then Added the dropdown on the Create View as follows...
<div class="form-group">
#Html.LabelFor(model => model.ItemType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Title", ViewBag.ItemTypesSelectList as SelectList, "Select Type", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ItemType, "", new { #class = "text-danger" })
</div>
</div>
I have two issues.
I can create a new item but it saves the ID to the SQL table
The edit view, while setup just like the create view for this column, throws the following error.
System.InvalidOperationException: 'The ViewData item that has the key 'Id' is of type 'System.Int32' but must be of type 'IEnumerable'.'
At this point I'm a bit lost. Any direction would be appreciated.
Use Html.DropDownListFor like this
#Html.DropDownListFor(m=>m.ItemType, ViewBag.ItemTypesSelectList as SelectList,"--- select type --- ",new { #class = "form-control" })

dropdownlistfor yields error ,{"Object reference not set to an instance of an object."} , when I click submit button

I am trying to create sub category for categories. User first select the categories from dropdownlist and then type the subcategory name and clicks submit. Even though dropdownlist elements are properly fill the dropdown list. When I click submit button It creates error. How can I solve this?
My View:
#model CETAPPSUGG.Models.CategorySubCategoryModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.HiddenFor(model => model.selectedId, new { id = "3" });
// #Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SubCatagories</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.SubCategory.SubCategoryName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SubCategory.SubCategoryName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SubCategory.SubCategoryName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
Upper cat: <div class="col-md-10">
#Html.DropDownListFor(Model => Model.Categories, Model.categoryList)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
My Controller:
public ActionResult Create()
{
var categories = db.Categories.ToList();
CategorySubCategoryModel deneme = new CategorySubCategoryModel();
var list = new List<SelectListItem>();
deneme.Categories = categories;
foreach (Categories c in categories)
{
list.Add(new SelectListItem() { Text = c.CategoryName, Value = c.Id.ToString() });
}
deneme.categoryList = list;
return View(deneme);
}
// POST: SubCatagories/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
// [ValidateAntiForgeryToken]
public ActionResult Create( CategorySubCategoryModel model)
{
string strDDLValue = model.selectedId;
SubCatagories newSubCategory = new SubCatagories();
Categories cat = new Categories();
cat = db.Categories.Find(Convert.ToInt32(strDDLValue));
// cat = db.Categories.Find(Convert.ToInt32(strDDLValue));
newSubCategory.SubCategoryName = model.SubCategory.SubCategoryName;
newSubCategory.UpperCategory = Convert.ToInt32(strDDLValue);
newSubCategory.Categories = cat;
db.SubCatagories.Add(newSubCategory);
db.SaveChanges();
return View();
}
My Model
namespace CETAPPSUGG.Models
{
public class CategorySubCategoryModel
{
SubCatagories SubCatagories { get; set; }
public IEnumerable<Categories> Categories { get; set; }
public IEnumerable<SubCatagories> SubCategories { get; set; }
public IEnumerable<SelectListItem> categoryList { get; set; }
public SubCatagories SubCategory { get; set; }
public string selectedId;
}
}
It creates error in view
You have a bunch of problems here.
Your primary problem is that you are not passing a model back to the View on post, thus the model is null. So, when you attempt to dereference items from the model in the View, a null reference is generated.
First, you are using selectedId but do not set this anywhere. It doesn't get set by magic. What you probably want is #Html.DropDownListFor(model => model.selectedId, Model.categoryList) (note the lowercase m in model in the first parameter, and uppercase M in the second)
Second, don't use a Model in your lambda in the DropDownListFor, use the lowercase model, because uppercase Model is reserved for the actual Model instance. If you want to reference the Model instance, then do something like DropDownListFor(_ => Model.Foo, Model.Foos). Note that I replaced the Model before the lambda with an underscore or some other value that is not Model. Frankly i'm surprised this even works, but there's probably a scoping rule here that overrides the outer Model. Avoid this because it can cause you confusion down the road.
Third, you are passing an IEnumerable to the DropDownListFor as the selected item variable, this won't work on a number of levels. This needs to be a single string value in most cases (sometimes a numerical one, but always a single more basic type that can have ToString() called on it and get a sensible string since DropDownListFor can't display complex objects).
Fourth, You also need to re-populate your DropDownListFor in the Post action, because the contents of a dropdownlist are not posted back, and thus will be null in the model. This, along with the SubCategory derefences in your view are ultimately what is generating the Null Reference exception.
You also need to pass the model back to your view in the Post, but as stated above, it needs to be re-initialized with the Categories as well as SubCategories.
There are probably more problems here, but fix these and you should be on your way.

MVC5 SPA IdentityUser add State and display it as Dropdown with static values

I am trying to add a state field to the user registration on the default MVC SPA template. I want to use a dropdown that doesn't link to a database field, or anyother crazy stuff other than having them statically/manually created as they are not going to change.
Is there any easy to implement solution or a way that I can implement this easily without altering the defaults too much?
You sound lazy ;-). This should do the job:
Add this property to the RegisterViewModel in the AccountViewModel.cs:
[Display(Name = "State")]
public string State { get; set; }
This will take take of posting the state value. Then add this to the Register.cshtml, below the confirm password field:
#{ var states = new List<SelectListItem>
{
new SelectListItem { Text = "Example 1", Value="Example1" },
new SelectListItem { Text = "Example 2", Value="Example2" }
};
}
<div class="form-group">
#Html.LabelFor(m => m.State, new {#class = "col-md-2 control-label"})
<div class="col-md-10">
#Html.DropDownListFor(m => m.State, states, "-- Select Status --", new { #class = "form-control"})
</div>
</div>
This results in:

Issue with DateTime Property

Here is my property in my model:
[Display(Name = "Date / Time:")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy HH:mm}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> DayTime { get; set; }
For my application it is necessary to include the time.
Here is my .cshtml
<div class="form-group">
#Html.LabelFor(model => model.DayTime, htmlAttributes: new { #class = "control-label col-md-2 required" })
<div class="col-md-10">
#Html.EditorFor(model => model.DayTime, new { htmlAttributes = new { #class = "form-control datepicker" } })
#Html.ValidationMessageFor(model => model.DayTime, "", new { #class = "text-danger" })
</div>
</div>
I am using jQuery Datepicker.
When the user initially goes to the Create page, I have it setup so that it will automatically have today's date and current time already in the EditorFor as so:
public ActionResult Create()
{
DailySummary daily = new DailySummary();
daily.DayTime = DateTime.Now;
return View(daily);
}
Now that all works fine, until I want to change the date and time... I am able to change the Date portion but I am unable to add the HH:mm part of the DateTime... like the EditorFor isn't allowing me to space from the Date portion to enter the time.
How do I fix this so that I can enter the time portion along with the date?
After searching around I found Bootstrap 3 Datepicker v4
I went into Nuget and downloaded the .CSS version of Bootstrap.v3.Datetimepicker.CSS.
After referencing the newly downloaded files in my _Layout View I followed the simple instructions in the link given above, and it works like a charm.

asp.net mvc 4.5.1 set field default based on another field

I have a form which includes 2 fields....Owner_ID and AQ_Manager. I want to make the AQ_Manager field default to a name, depending on what is entered into the Owner_ID field. For example, if user inputs "Company A" into the Owner_ID field, I want to default the AQ_Manager field to "John Smith". Is there a way for me to accomplish this?
Model Info:
[DisplayName("Owner ID")]
public string Owner_ID { get; set; }
[DisplayName("AQ Manager")]
public string AQ_Manager { get; set; }
View:
<div class="form-group">
#Html.LabelFor(model => model.Owner_ID, new { #class = "control-label col-md-2 required CreateEditFieldNamesSpan" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Owner_ID (SelectList)ViewBag.VBProjectOwnerList, "--Select Owner--")
#Html.ValidationMessageFor(model => model.Owner_ID)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.AQ_Manager, new { #class = "control-label col-md-2 CreateEditFieldNamesSpan" })
<div class="col-md-10">
#Html.EditorFor(model => model.AQ_Manager)
#Html.ValidationMessageFor(model => model.AQ_Manager)
</div>
</div>
From your comments, you have indicated that there are only 3 options for Owner_ID, so you could add a property to your view model to store the associated defaults (say) public List<string> DefaultManagers { get; set; } and in the GET method, initialize the collection and add the 3 values (in the same order as the 3 options)
model.DefaultManagers = new List<string>{ "John", "Bob", "Jim" };
return View(model);
and in the view, include the following script
var defaults = #Html.Raw(Json.Encode(Model.DefaultManagers))
which will create a javascript array containing the 3 values. Then handle the .change() event of your dropdownlist an update the textbox
$('#Owner_ID').change(function() {
var index = $(this).children('option:selected').index();
$('#AQ_Manager').val(defaults[index]);
});
An alternative, if the view was more complex and you need to update multiple inputs, would be to use ajax to call a controller method that returns the result(s) you need
var url = '#Url.Action("GetDefaults")';
$('#Owner_ID').change(function() {
$.getJSON(url, { id: { $(this).val() }, function(data) {
$('#AQ_Manager').val(data.DefaultManager);
$(anotherElement).val(data.SomeOtherPropery);
});
});
and the controller method would be
public JsonResult GetDefaults(string id)
{
// get the values you need based on the selected option, for example
var data = new { DefaultManager = "Jim", SomeOtherPropery = someOtherValue };
return Json(data, JsonRequestBehavior.AllowGet);
}
as per your question you are entering a value in 'Owner_Id' field. we can easily set up a default value in 'AQ_Manager' field by using java script or JQuery. The syntax changes it depends up on what type of your fields

Resources