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.
Related
In my controller I am using .Include and .ThenInclude to fill my object.
When I debug and view the properties of the servicePackage, I can see all of the data I expect to see is there:
ServicePackage servicePackage = await _context.ServicePackage
.Include(bs => bs.ServicePackageLines)
.ThenInclude(bsl => bsl.Product)
.Where(bs => bs.Id == id)
.FirstOrDefaultAsync();
// viewing the properties of this servicePackage
// shows that there is product data when I drill down.
return View(servicePackage);
But in the view I cant access the data:
#model Domain.Entities.ServicePackage
#foreach (var lineDetail in Model.ServicePackageLines)
{
#if(lineDetail.Product != null)
{
<td>#lineDetail.Product.SupplierModelNumber</td>
}
else
{
<td>#lineDetail.ProductId</td>
}
}
Always shows the line detail product Id, and not the model number.
I'm not sure what I'm doing wrong, but it would be great if someone could put me on the right path.
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");
I'm fairly new to mvc, and have started learning asp.net mvc 5 and django
I want to create an application where the user can create a new view at runtime. So lets say I create a feature in the web app for a user to add a new page where they can fill out a form, say the title maybe text, or fields they want to display on the view, and when the user saves it that info gets saved to the db and creates a new view.
My questions are:
can you create dynamic views at runtime?
how do you create the proper url to route to that new page?
if the 1st two are possible can you use a model or viewModel to then display the content from the db for that page?
Any advice on if this can be done would be appreciated. Thanks
I think you need to make a page that saves the user configuration in db as per user demand.
From my end, I suggest the following approach to do it.
Whatever you gets the data from database which are returns like as below snap.
Make one Action in controller and assign those data in one datatable/list in action.
public ActionResult LoadContent()
{
dynamic expando = new ExpandoObject();
var model = expando as IDictionary<string, object>;
/*Let say user insert the detail of employee registration form. Make the
database call and get the distinct detail of particular inserted form by Id
or whatever. As an example below datatable contains the data that you fetch
during database call.*/
DataTable objListResult =
HeaderViewActionHelper.GetFinalResultToRenderInGenericList(id);
if (objListResult != null && objListResult.Rows.Count > 0)
{
foreach (DataRow row in objListResult.Rows)
{
model.Add(row["DisplayName"].ToString(),
row["DisplayNameValue"].ToString());
/*If you want to handle the datatype of each field than you can bifurcation
the type here using If..else or switch..case. For that you need to return
another column in your result from database i.e. DataType coloumn. Add in
your model as, model.Add(row["DisplayName"].ToString(),
row["DisplayNameValue"].ToString(), row["DataType"].ToString());*/
}
}
/* return the model in view. */
return View(model);
}
In the view you can go through the loop over modal and render the detail.
#model dynamic
#using (Html.BeginForm("SubmitActionName", "ControllerName")
{
<div class="table-responsive">
<table>
#if (Model != null)
{
foreach (var row in Model)
{
}
}
</table>
</div>
}
For more detail, Please go through this link.
I have a PartialView (_Letra) that receives information from a Controller named Music ... this way
public ActionResult CarregarLetra(string id, string artista, string musica)
{
return PartialView("_Letra", ArtMus(artista, musica));
}
public ResultLetra ArtMus(string artista, string musica)
{
//Conteúdo do metodo[..]
var queryResult = client.Execute<ResultLetra>(request).Data;
return queryResult;
}
Until then, no problem. What happens is that now I need to pass other information to this same PartialView (_Letra). This information is in PartialView (_Cifra).
So I added the following lines in my Music controller
public ActionResult CarregarCifra(string id, string artista, string musica)
{
return PartialView("_Cifra", GetCifra(artista, musica));
}
public ResultChords GetCifra(string artista, string musica)
{
var cfrTest= new Cifra();
var cifra = new ResultChords();
cifra.chords = cfrTest.GetInfs(artista, musica);
return cifra;
}
Everything working so far, PartialView _Cifra receives the information
I searched and found that I could use in PartialView _Letra the Html.Partial to load my PartialView _Cifra, I did this way then
I added
<div class="item">
<div class="text-carousel carousel-content">
<div>
#Html.Partial("_Cifra", new letero.mus.Infra.Models.ResultChords());
</div>
</div>
</div>
Now it starts to complicate why, the return of this is null, I believe it is due to a new instance of ResultChords that I make in Html.Partial
I have already tried using a ViewBag also to transpose the information between Partials, but probably not correctly, due to the return being null as well.
I've already done a lot of research and I'm not getting the information I need for PartialView _Letra.
There is a better way not to use Html.Partial, or to use it properly, as I am not aware.
In _Letra use
#Html.Action("CarregarCifra", "Music", new { id=Model.Id, artista=Model.Artista, musica=Model.Musica });
if the variables are available on the model then you can pass them in; otherwise, make use of the Viewbag and set them in CarregarLetra
Are you always passing a new object to the second partial? You could just create it at the top of the new _Cifra partial.
_Cifra.cshtml
#{
var resultChords = new letero.mus.Infra.Models.ResultChords();
}
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")