This is probably a very simple problem, but I am extremely new to C# / MVC and I have been handed a broken project to fix. So it's time to sink or swim!
I have an array of strings that is being passed from a function to the front end.
The array looks something like
reports = Directory.GetFiles(#"~\Reports\");
On the front end, I would like it to display each report, but I am not sure how to do that.
This project is using a MVC, and I believe the view is called "Razor View"? I know that it's using an HTML helper.
In essence, I need something like
#HTML.DisplayTextFor(Model.report [And then print every report in the array]);
I hope that makes sense.
If you want to display the file name array you can simply use a foreach:
#foreach(var report in Model.Reports){ #report }
Note that you should add the Reports property to your view model:
public class SampleViewModel
{
public string [] Reports { get; set; }
}
You could use ViewData or TempData but I find that using the view model is the better way.
You can then populate it:
[HttpGet]
public ActionResult Index()
{
var model = new SampleViewModel(){ Reports = Directory.GetFiles(#"~\Reports\")};
return View(model);
}
And use it in the view as you see fit.
Here is a simple online example: https://dotnetfiddle.net/5WmX5M
If you'd like to add a null check at the view level you can:
#if(Model.Reports != null)
{
foreach(var report in Model.Reports){ #report <br> }
}
else
{
<span> No files found </span>
}
https://dotnetfiddle.net/melMLW
This is never a bad idea, although in this case GetFiles will return an empty list if no files can be found, and I assume a possible IOException is being handled.
Related
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();
}
I have a razor view showing details of a Hotel.
model for the view:
#model MySite.MyViewModels.Hotel
Have to show many details segments of the hotel. So, I have to check null for the Model on each segment. Is it possible if I can check once for all and stop the compilation of c# code if it is null.
You can say on top of the view If I can write something like:
#If(Model==null || Model.RoomsAvailable.Count<1)
{
//Don't read c# code on rest of the view now
}
Hope it make sense.
In your controller:
pubilc ActionResult YourAction()
{
if (null == YourModel)
{
return View(SomeEmptyView); // or return null
}
return View(Some legitimate view);
}
By that, you don't need to add logic to your view and you get what you wanted.
I am working through sample MVC Nerdinner tutorial and using it on the AdventureWorks database. I have created an Edit action in the CategoryController to edit Product Category in AdventureWorks. The only updateable field in this table is the Name (the other fields - ID, RowGUID and UpdateDate are autogenerated). So my edit form View has only 1 field for the Name (of Product Category). My "Save" action for the edit is below: -
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection){
ProductCategory p = awRepository.GetProductCategory(id);
try
{
//UpdateModel(p);
p.Name = Request.Form["Name"];
awRepository.Save();
return RedirectToAction("Details", new { id = p.ProductCategoryID });
}
catch
{
foreach (var err in p.GetRuleViolations())
{
ModelState.AddModelError(err.PropertyName, err.ErrorMessage);
}
return View(p);
}
}
If I use the code as above, everything works as long as the Name I enter is valid (thus there is no exception). If I introduce an error (which is raised by GetRuleViolations if the Name is blank or for testing purposes is a particular "Test" string) I get a NullReferenceException (Object reference not set to an instance of an object) on this line in the View (Category/Edit.aspx) when the Edit View is redrawn (to show the user the error and allow him to correct)
<%= Html.TextBox("Name") %>
If I update my ProductCategory using UpdateModel(p) instead of using the Request.Form variable, everything works fine; Valid data is saved and invalid data redraws the view showing the error message.
My question is: what is the difference between UpdateModel and manual updating my variable by reading the values from Request.Form collection? The Nerdinner tutorial seems to suggest that both are equivalent. So I am surprised that one works smoothly and the other raises an exception.
Sounds like this:
http://forums.asp.net/p/1396019/3006051.aspx
So, for every error you add with
ModelState.AddModelError() and call
the View again, MVC Framework will try
to find an AttemptedValue for every
error it finds. Because you didn't add
them, MVC will throw an exception.
Normally you don't need to add these
values: AttemptedValues are
automaticaly populated when you use
DefaultBinding (by calling
UpdateModel() or by passing the object
to bind as an Action Method paramter:
public ActionResult
Create(FormCollection Form,
YourObjectType yourObject).
Looks like the following is done automatically by UpdateModel, but not done manually by yourself?
if (Form["Name"].Trim().Length == 0)
{
ModelState.AddModelError("Name", "Name is required");
//You missed off SetModelValue?
ModelState.SetModelValue("Name", Form.ToValueProvider()["Name"]);
}
I have a simple form on a view page, implemented as a user control, that looks something like this:
<%=Html.BeginForm("List", "Building", FormMethod.Post) %>
//several fields go here
<%Html.EndForm(); %>
There are two problems I would like resolved, the first is that I would like the controller method that receives this to take a type parameter of the user control. The goal is to avoid putting all of the fields of the form into the parameter list for the method. The controller method currently looks like this:
[AcceptVerbs("Post")]
public ActionResult List(string capacityAmount)
{
ProfilerDataDataContext context = new ProfilerDataDataContext();
IEnumerable<Building> result = context.Buildings.OrderBy(p => p.SchoolName);
ViewData["Boroughs"] = new SelectList(Boroughs.BoroughsDropDown());
return View(result);
}
The rest of the fields in the form will be used to conduct a search against the buildings type.
The form posts fine, I can search on the capacity the way you would expect, but I can smell ugliness ahead as I add parameters to the search.
Second, smaller problem is that when the page renders the BeginForm tag renders the string "System.Web.Mvc.Form" to the page. How do I make that go away?
1) Use FormCollection as the argument:
public ActionResult List(FormCollection searchQuery)
Now you can iterate the FormCollection and get key/value search terms from your search form.
2) Remove the "=" from BeginForm:
<% Html.BeginForm("List", "Building", FormMethod.Post) %>
That said, you should really be using, um... using:
<% using (Html.BeginForm("List", "Building", FormMethod.Post)) { %>
<% } %>
If I'm understanding your question properly, you use the html helper and create inputs named:
<%=Html.TextBox("building.FieldNumber1")%>
<%=Html.TextBox("building.FieldNumber2")%>
You should be able to access the data using:
public ActionResult List(Building building)
{
...
var1 = building.FieldNumber1;
var2 = building.FieldNumber2;
...
}
and if your action is to do two different things depending on if form is submitted:
public ActionResult List()
{
//some code here
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult List(Building building)
{
...
var1 = building.FieldNumber1;
var2 = building.FieldNumber2;
...
}
if anybody is skeptical about the whole 'using' pattern with Html.BeginForm - realize that the IDE is smart enough to match the opening '{' with the ending '}' which makes it very easy to see where your form begins and ends.
Also <% Html.EndForm(); %> requires a semicolon which I'm not sure i like :)