Unable to create IEnumerable on a class - stored-procedures

I am trying to use below code in MVC and here is what I have done till now:
public class MoviesModel
{
public int Id { get; set; }
public string MovieName { get; set; }
public string Actor { get; set; }
public int Year { get; set; }
}
Controller
public MoviesModel Index()
{
MoviesModel myModel;
string connectionString =
"";
SqlConnection con = new SqlConnection(connectionString);
SqlCommand com = con.CreateCommand();
com.CommandText = "SELECT [ID] ,[MovieName] ,[Actor] ,[Year] FROM [dbo].[Movies]";
con.Open();
using (SqlDataReader reader = com.ExecuteReader())
{
while (reader.Read())
{
myModel = new MoviesModel
{
myModel.Id = Convert.ToInt32(reader[0]),
myModel.MovieName = reader[1].ToString(),
myModel.Actor = reader[2].ToString(),
myModel.Year = Convert.ToInt32(reader[3])
};
}
}
con.Close();
return myModel;
}
But I am getting below error
cannot initialize class with a collection because it does not implement System.Collection.IEnumerable

The compilation error you're getting comes with a file name and a line number, and I guarantee those things are not pointing at any of the code you've quoted.
I take that back, actually. I think this might be the source of your compilation error (telling us what line the compiler was complaining about would have helped).
myModel = new MoviesModel
{
myModel.Id = Convert.ToInt32(reader[0]),
myModel.MovieName = reader[1].ToString(),
myModel.Actor = reader[2].ToString(),
myModel.Year = Convert.ToInt32(reader[3])
};
That's not the right syntax. Inside the curly brackets is the code that will be run in order to initialize myModel - you can't refer to myModel inside the brackets, because it doesn't exist until after the code in the brackets has finished executing. Fortunately, you don't need to, because this is the syntax for setting those properties:
myModel = new MoviesModel
{
Id = Convert.ToInt32(reader[0]),
MovieName = reader[1].ToString(),
Actor = reader[2].ToString(),
Year = Convert.ToInt32(reader[3])
};
More broadly, I'll go out on a limb and guess that what you really want to do is return a collection of MoviesModel objects instead of a single MoviesModel object that happens to be the last movie in the result set. The code to do that would look something like this:
public ActionResult Index()
{
var models = new List<MoviesModel>();
string connectionString = "";
using (var con = new SqlConnection(connectionString))
using (var com = con.CreateCommand())
{
com.CommandText = "SELECT [ID] ,[MovieName] ,[Actor] ,[Year] FROM [dbo].[Movies]";
con.Open();
using (var reader = com.ExecuteReader())
{
while (reader.Read())
{
var myModel = new MoviesModel
{
Id = reader.GetInt32(0),
MovieName = reader.GetString(1),
Actor = reader.GetString(2),
Year = reader.GetInt32(3)
};
models.Add(myModel);
}
}
}
return View(models);
}
As an aside, Convert.ToInt32 is a pretty inefficient way to get something that's already an integer in the database, and in the reader. The GetInt32 method will perform better.

Related

MVC form post model list

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);

How to display details from database to the single user in mvc

I am trying to get the details from database to display in the View. Here I need to display the records for particular user who logged currently. But unfortunately all the data which ever in DB table coming into the view. But I dont want to display all the data.
In DB I have two tables for tblEmployee and TaskDetails.
This is my Model:
public class TaskDetails
{
public string ProjectID { get; set; }
public string ProjectName { get; set; }
public DateTime StartDate { get; set; }
public DateTime EstimatedDate { get; set; }
public string TaskDescription { get; set; }
}
This is My controller,
To fetch the data here I am using ADO.Net,
public ActionResult TaskDetails(string td)
{
string connectionstring = "data source = NLTI37; initial catalog = Data; integrated security = True; MultipleActiveResultSets = True; App = EntityFramework";
string sql = "select * from TaskDetail";
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand(sql, conn);
var Details = new List<TaskDetails>();
{
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
var ProjectDetail = new TaskDetails();
ProjectDetail.ProjectID = rdr["ProjectID"].ToString();
ProjectDetail.ProjectName = rdr["ProjectName"].ToString();
ProjectDetail.StartDate = DateTime.Parse(rdr["StartDate"].ToString());
ProjectDetail.EstimatedDate = DateTime.Parse(rdr["EstimatedDate"].ToString());
ProjectDetail.TaskDescription = rdr["TaskDescription"].ToString();
Details.Add(ProjectDetail);
}
}
return View(Details);
}
Here I am using ADO.Net to fetching the details. And these details I need to display on the View for user who currently logged in.
This is my View:
<tbody>
#foreach (var ProjectDetail in Model)
{
<tr>
<td>#ProjectDetail.ProjectID</td>
<td>#ProjectDetail.ProjectName</td>
<td>#ProjectDetail.StartDate</td>
<td>#ProjectDetail.EstimatedDate</td>
<td>#ProjectDetail.TaskDescription</td>
</tr>
}
</tbody>
Here I need to display the records of the user who logged in currently. But unfortunately all the user details I am getting here. As per my understanding SQL statement is wrong. Correct Me if wrong. How to get the details for that particular user details. Can any one help on this.
I think you should have to use where clause. Try this.
I assumed that td is your ProjectID
string sql = "select * from TaskDetail where ProjectID=#ProjectID";
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#ProjectID", td);

LINQ to Entities does not recognize the method. Guid causing trouble?

In my model class OwnedModule i have OwnerID as Guid.
There is another model class called BusinessUnit which contains the same Guid value from OwnedModule and its OwnerName.
I want to show the details of OwnedModule, which contains all the details about the hardware but has the owner as Guid value and not the name, and for this i have created a view model
public class OwnedModuleViewModel
{
public long Id { get; set; }
public string ModuleId { get; set; }
public string TypeName { get; set; }
public string KindName { get; set; }
public string Owner { get; set; }
public DateTime OwnershipStart { get; set; }
}
public class IndexOwnedModule
{
public List<OwnedModuleViewModel> OwnedModules { get; set; }
}
to show all this detail in my repository i have following function
public IndexOwnedModule GetAllOwnedModules()
{
var modulesList = new IndexOwnedModule();
var modules = (_dbSis.OwnedModules.OrderBy(module => module.Id).Select(module => new OwnedModuleViewModel
{
Id = module.Id,
ModuleId = module.ModuleId,
TypeName = module.ModuleType.TypeName,
Owner = GetModuleOwner(module.ModuleOwnerId),//error here
OwnershipStart = module.Start
}));
modulesList.OwnedModules = modules.ToList();
return modulesList;
}
public string GetModuleOwner(Guid id)
{
var ownedModule =_dbSis.Set<BusinessUnit>().FirstOrDefault(t => t.Id == id);
if (ownedModule != null) return ownedModule.Name;
return null;
}
It would not be convinient to show the guid value as owner in the view to user so I wanted to fetch the name for which I had GetModuleOwnerName.
But it seems like the way i've set the name of the owner to my viewmodel view is wrong, and when i run the application i get the following error.
LINQ to Entities does not recognize the method 'System.String GetModuleOwner(System.Guid)' method, and this method cannot be translated into a store expression.
When i comment the line where I've set the value of owner(Owner = GetModuleOwner(module.ModuleOwnerId)), everything works fine.
When Entity Framework build your query, it relies on the inspection of the passed Expression Tree. When it encounter a method call, it will try to map it to an equivalent SQL method using (see this for the canonical methods). Because Entity Framework has no knowledge of OwnedModuleViewModel.GetModuleOwner, it cannot generate an appropriate SQL query. In this case, the simple way would be to embed what your method does in the query instead of calling a method:
_dbSis.OwnedModules
.OrderBy(module => module.Id)
.Select(module => new OwnedModuleViewModel
{
Id = module.Id,
ModuleId = module.ModuleId,
TypeName = module.ModuleType.TypeName,
Owner = _dbSis.Set<BusinessUnit>()
.Where(t => t.Id == module.ModuleOwnerId)
.Select(t => t.Name).FirstOrDefault(),
OwnershipStart = module.Start
});
Of course, that is assuming _dbSis.Set<BusinessUnit>() is a DbSet<T> part of the same DbContext, otherwise the same problem arise.
In Linq-To-Entities, a Linq statement against a context gets translated to a SQL statement. It's obviously impossible to translate the GetModuleOwner() method to SQL. You need to get the ModuleOwnerId first, and then in another step after, call GetModuleOwner() on each ModuleOwnerId.
Or you could restructure your query to use a join:
var modules = from m in _dbSis.OwnedModules
join b in _dbSis.BusinessUnit on m.ModuleOwnerId equals b.Id
order by m.Id
select new OwnedModuleViewModel {
Id = m.Id,
ModuleId = m.ModuleId,
TypeName = m.ModuleType.TypeName,
Owner = b.Name,
OwnershipStart = m.Start};
modulesList.OwnedModules = modules.ToList();
NOTE: I didn't test this so it might have some minor syntax errors.
This could be another option
var ownedModules = _dbSis.OwnedModules.OrderBy(module => module.Id).Select(module => new
{
Id = module.Id,
ModuleId = module.ModuleId,
TypeName = module.ModuleType.TypeName,
ModuleOwnerId = module.ModuleOwnerId,
OwnershipStart = module.Start
}).ToList().Select(m => new OwnedModuleViewModel
{
Id = m.Id,
ModuleId = m.ModuleId,
TypeName = m.TypeName,
Owner = GetModuleOwner(m.ModuleOwnerId),
OwnershipStart = m.OwnershipStart
});
ownedModulesList.OwnedModules = ownedModules.ToList();
return ownedModulesList;

how to bind column value from database to html dropdownlist in mvc4 using ado.net

I want to bind column value of database to dropdownlist using storedprocedure in mvc4
i dont know how to handle this .plz help me
my model code is like this
public class dropdown
{
string conn = System.Configuration.ConfigurationManager.ConnectionStrings["cnstr"].ConnectionString;
[Required(ErrorMessage = "DomainName is Required")]
[Display(Name = "DomainName")]
public string DomainName { get; set; }
public IEnumerable<dropdown> obj { get; set; }
public List<dropdown> LoadDomain(dropdown model)
{
List<dropdown> obj = new List<dropdown>();
using (SqlConnection con = new SqlConnection(conn))
{
try
{
con.Open();
SqlCommand cmd = new SqlCommand("selectDomainName", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
var data = new dropdown();
data.DomainName = ds.Tables[0].Rows[i]["DomainName"].ToString();
obj.Add(data);
}
}
catch
{
}
}
return obj;
in obj i am getting all the column values
my controller code
public ActionResult binddropdown(dropdown model1)
{
var x = model1.LoadDomain(model1);
ViewData. = x;
return View(model1);
}
i dont know wheather i am going in direction or not. i am a beginner so plz suggest me .
you can set your data in viewbag and then on front side you can loop through data and assign value to your dropdownbox. here what you can do is,
public ActionResult binddropdown(dropdown model1)
{
var x = model1.LoadDomain(model1);
viewbag.MyData = x;
return View();
}
and on front end side you can fetch data from viewbag (conver to appropriate type using typecast if required) and can assign to html tag like like this,
#{
var a = (yourobjtypecast) viewbag.MyData ;
<select name="drpId" id="drpId">
<option value="yourvalue"> Select </option>
#foreach (var te in a)
{
<option value='#te.ID.ToString()'>#te.Nam </option>
}
</select>
}
I hope this work.

ASP.net MVC - Strongly typed object to represent a Json Object that I pass to the view

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

Resources