C# MVC Download dynamic File Name - c#

How can I download a pdf file that's not static.
I tried this:
public ActionResult GetPdf(string filename)
{
var invoice = db.Invoices.ToList().Find(x=>x.InvoicePath==filename);
return File("~/Invoice/" +invoice.ToString(), "application/pdf",Server.UrlEncode(invoice.ToString()));
}
The Index View
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.CreatedInvoice)
</th>
<th>
#Html.DisplayNameFor(model => model.InvoicePath)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.CreatedInvoice)
</td>
<td>
#Html.DisplayFor(modelItem => item.InvoicePath)
</td>
<td>
#Html.ActionLink("Download", "GetPdf", new { id = item.InvoicePath })
</td>
</tr>
}
</table>
This is my upload file method
public ActionResult fileupload(HttpPostedFileBase file)
{
if (file != null)
{
string ImageN = System.IO.Path.GetFileName(file.FileName);//get the file path
string physicalPath = Server.MapPath("~/Invoice/" + ImageN);//store the file path in a folder called img
file.SaveAs(physicalPath);
Invoice newP = new Invoice();
newP.InvoicePath = ImageN;
newP.CreatedInvoice = DateTime.Now;
db.Invoices.Add(newP);//store the image path in a database
db.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
Any suggestions will be Greatly appreciated

This is what your code should be:
public ActionResult GetPdf(string filename)
{
var invoice = db.Invoices.FirstOrDefault(x=> x.InvoicePath == filename);
return File("~/Invoice/" + invoice.InvoicePath, "application/pdf", Server.UrlEncode(invoice.InvoicePath));
}
I'm not sure why you're Querying the Database though as you're getting the fileName in paramater and that is all you need to serve the file anyways.
You're saving the file name in InvoicePath property when file is uploaded, it is this property which you should be using to get the name of file to be downloaded.

I just Changed the download Method To This
public ActionResult GetPdf(int id)
{
var invoice = db.Invoices.Find(id);
return File("~/Invoice/" + invoice.InvoicePath, "application/pdf", Server.UrlEncode(invoice.InvoicePath));
}
and Changed The Action Link to
#Html.ActionLink("Download", "GetPdf", new { id = item.InvoiceId })
dont really know why the above method did not work

Related

ASP.NET Core 5 MVC Render string from action in view

I try to display a string from Action in a View. This sounds like a very simple and easy task, but I don't get it how to do this.
My async Action returns Content Result:
public async Task<IActionResult> DisplayName(string key)
{
// Retrieves the requested culture
var rqf = Request.HttpContext.Features.Get<IRequestCultureFeature>();
// Culture contains the information of the requested culture
var culture = rqf.RequestCulture.Culture;
return Content(await Task.FromResult(_displayProvider.GetDisplayName(key, culture.Name)));
}
My View is very simple html:
#model List<MyModel>
<table class="table table-bordered table-striped datatable">
<thead class="table-head-dark">
<tr>
<th>
#Html.DisplayNameFor(model => model.First().Id)
</th>
<th>
Actions
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
<partial name="_EditDetailButton" model="#item.Id" />
<partial name="_DeleteButton" model="#item" />
</td>
</tr>
}
</tbody>
</table>
Instead of #Html.DisplayNameFor(model => model.First().Id) I want to Display a user-defined value. The user-defined value is returned from the Action.
I tried #Url.Action("DisplayName", "DisplayName", new { key = "MyModel.Id" }) but this is rendering an Url.
I tried Html.RenderAction("DisplayName", "DisplayName", new { key = "LastName" }) but RenderAction does not exist in ASP.NET Core 5.
I could call a static Class e. g. DisplayNameProvider.GetDisplayName("MyModel.Id", ???) but i dont know how to get the choosen culture to pass it to the method.
How do I get this working? I am also not familiar with components in ASP.NET Core.
Or is there a completely different solution for displaying strings, which the user has defined and save to the database? The DisplayNameProvider is retrieving the strings from database and handles caching.
UPDATE:
The Goal is to store and change displaynames for properties in the database. The user can change the displaynames. In my example the user wants a different displayname for the column header. I cannot use resource files as these are static and cannot be changed during runtime.
This is my DisplayNameProvider.GetDisplayName Method:
public string GetDisplayName(string ressourceKey, string language)
{
var ressources = GetCached(language);
var item = ressources.FirstOrDefault(r => r.ResourceKey == ressourceKey);
return item.Text;
}
Thanks in advance
I ended up using a string localizer, which returns the desired value for my properties.
Now i can use displaynamefor and it shows the value of the language. E.g.:
#Html.DisplayNameFor(model => model.MyProperty)

String with email format turns into Hyperlink

Hi this probably is an easy question but i cant find information about how to solve it i have a table with a field named Email and the values are of type string but the problem is that mvc or the browser automatically changes that string email into Hyperlink as shown in the following picture
when i inspect the element it is an hyperlink:
lacubana#la.com
what can i do to only display the emails as string? i don't want that information to be in hyperlink format. thanks very much
Edited: here is my code of the view
<table class="table table-bordered table-striped">
<tr>
<th>Email</th>
<th>Contraseña</th>
<th>NickName</th>
<th>TipoUsuario</th>
<th>Acciones</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Email)</td>
<td>#Html.DisplayFor(modelItem => item.Contraseña)</td>
<td>#Html.DisplayFor(modelItem => item.NickName)</td>
#if (item.TipoUsuario == 1)
{
<td>Administrador</td>
}
else
{
<td>Vendedor</td>
}
<td>
#Html.ActionLink("Editar", "EditarUsuario", new { id = item.IdUser }) |
#Html.ActionLink("Eliminar", "EliminarUsuario", new { id = item.IdUser })
</td>
</tr>
}
</table>
and here is the code of my controller:
IList<Usuario> UsuarioList = new List<Usuario>();
var query = from usu in database.ReportingUsersT
where usu.Activo == 1
select usu;
var listdata = query.ToList();
foreach (var Usuariodata in listdata)
{
UsuarioList.Add(new Usuario()
{
IdUser = Usuariodata.IdUser,
Email = Usuariodata.Email,
Contraseña = Usuariodata.Contraseña,
NickName = Usuariodata.NickName,
TipoUsuario = Usuariodata.TipoUsuario
});
}
return View(UsuarioList);
#Html.DisplayFor(...) is determining that the text is an email and is wrapping it in a link. You can simply use
<td>#item.Email</td>
to display it as text

Update Values in Database - MVC

im using the sortable jquery plugin, because i want that the user can choice the order of the images are showing in my view.
For this i have a Get Controller which sends the data to my PartialView.
How can i make the now the Post Controller to update my table in my database?
Note: In this moment the controller don´t receive any data. i haven´t figured out what is wrong
Someone can help me with this?
Thanks in advance:
Here is my code:
In My PartialView:
#(Html.BeginForm("UpdateOrder", "Admin", FormMethod.Post)){
<div id="Order">
<ul id="sortable">
#foreach (var p in ViewBag.Images)
{
<li id="#Html.AttributeEncode(p.FileName)">
<img src="~/Files/#p.FileName"/>
</li>
}
</ul>
</div>
}
Controller:
if (ModelState.IsValid)
{
using (SqlConnection cn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
SqlCommand cmd;
System.Text.StringBuilder sql = new System.Text.StringBuilder();
sql.Append("Update Image Set MyFileName=??? Order By ASC");
cn.Open();
cmd = new SqlCommand(sql.ToString(), cn);
cmd.Parameters.Add(??????????).Value = ;
cmd.ExecuteNonQuery();
cn.Close();
}
}
return View();
Are you looking for something like this?
SqlCommand comm = new SqlCommand("UPDATE Customers SET Name=#name WHERE ID=#id", con;
comm.Parameters.AddWithValue("#name", "John");
comm.Parameters.AddWithValue("#id", id);
For passing data from view to controller take a look at the following links: ASP.NET MVC 3 Razor: Passing Data from View to Controller
ASP.Net MVC Passing multiple parameters to a view
I have created a backend for a website, where i e.g. can add, edit, delete events. So the snippet in the view for the events looks like this:
<div id="tabs-2" class="ui-widget-content">
<h2>
Events</h2>
<p>
#Html.ActionLink("Create new Event", "EventCreate")
</p>
<table id="tableEvent">
<tr>
<th>
Event
</th>
<th>
Date
</th>
<th>
Day of the Week
</th>
<th>
</th>
</tr>
#foreach (var e in ViewBag.Events)
{
<tr id="#e.EventID">
<td>
<h4>#e.EventName</h4>
</td>
<td>
<h4>#string.Format("{0:d}", e.Datum)</h4>
</td>
<td>
<h4>#e.Tag</h4>
</td>
<td>
#Html.ActionLink("Löschen", "EventDelete", new { id = e.EventID })
</td>
</tr>
}
</table>
</div>
I pass the id to the controller in the ActionLink and call the EventDelete:
[Authorize]
public ActionResult EventDelete(int id)
{
repevent.Delete(id);
return RedirectToAction("Main");
}
Now i have the id of the event and can do whatever i want. (In my case, i delete the event with the associated id.
public void Delete(int id)
{
using (KiGaDBEntities db = new KiGaDBEntities())
{
Event event = db.Event.SingleOrDefault(e => e.EventID == id);
if (event != null)
{
db.Event.Remove(event);
db.SaveChanges();
}
}
}
I hope that helps you!

Updating Multiple Records in one view; "Not all code paths return a value" error

I'm really new to programming and stuck on a problem.
I'm trying to edit and update multiple rows of a database in one view, using mvc and asp.net.
I think I'm somewhere along the right tracks but keep getting an error saying "not all code paths return a value".
My Conroller looks like this:
[HttpGet]
public ViewResult AnotherListEdit()
{
var chosenClass = from c in db.ClassInstanceDetails.Include("ClassInstance").Include("Student")
where c.ClassInstance.ID == 1
select c;
return View(chosenClass.ToList());
}
[HttpPost]
public ActionResult AnotherListEdit(IList<ClassInstanceDetail> list)
{
if (ModelState.IsValid)
{
foreach (ClassInstanceDetail editedClassInstanceDetail in list)
{
var tempBook = (from classInstDet in db.ClassInstanceDetails
where (teacher.ClassInstanceID == editedClassInstanceDetail.ClassInstanceID)
&& (classInstDet.StudentID == editedClassInstanceDetail.StudentID)
select teacher).First();
db.ApplyCurrentValues(tempBook.EntityKey.EntitySetName, editedClassInstanceDetail);
}
db.SaveChanges();
return View(db.Teachers.ToList());
}
}
My View looks like this:
#model IList<FYPSchoolApp.DAL.ClassInstanceDetail>
#{
ViewBag.Title = "AnotherListEdit";
}
#using (Html.BeginForm())
{
<table>
<tr>
<th>
Name
</th>
<th>
Second Name
</th>
<th>
attendance
</th>
<th>
Comment
</th>
</tr>
#for (var i = 0; i < Model.Count(); i++) {
<tr>
<td>
#Html.DisplayFor(m => Model[i].StudentID)
</td>
<td>
#Html.DisplayFor(m => Model[i].Attendance)
#Html.EditorFor(m => Model[i].Attendance)
</td>
<td>
#Html.DisplayFor(m => Model[i].CommentNote)
#Html.EditorFor(m => Model[i].CommentNote)
</td>
</tr>
}
</table>
<input type="submit" value="save" />
}
The "not all code paths return a value error" is being highlighted with AnotherListEdit function, the second one thats after HttpPost. If I run the project without that whole function, the display works, and the correct information is passed to the display.
Any help would be very much appreciated!!
What should happen in the AnotherListEdit method if the modelstate is invalid? That is what is missing ... The action does not return a "ActionResult" if the modelstate is invalid
[HttpPost]
public ActionResult AnotherListEdit(IList<ClassInstanceDetail> list)
{
if (ModelState.IsValid)
{
foreach (ClassInstanceDetail editedClassInstanceDetail in list)
{
var tempBook = (from teacher in db.ClassInstanceDetails
where (teacher.ClassInstanceID == editedClassInstanceDetail.ClassInstanceID)
&& (teacher.StudentID == editedClassInstanceDetail.StudentID)
select teacher).First();
db.ApplyCurrentValues(tempBook.EntityKey.EntitySetName, editedClassInstanceDetail);
}
db.SaveChanges();
return View(db.Teachers.ToList());
}
//HERE!!What view should return? any error messages?
return View("View with no valid modelstate?");
//Maybe?
//return RedirectToAction("AnotherListEdit");
}
if (ModelState.IsValid)
{ //you return something here }
but if the modelstate is not valid, nothing is returned. The error must come from there

linq to entity query returns list as continuous string

I have a query that looks like this:
var ChangesOthersResult = surveyResponseRepository.Query.Select(r => r.ChangesOthers);
That returns all of the entries in "ChangesOthers" column from my table.
When I return the data inside my view:
#Html.DisplayFor(modelItem => modelItem.ChangesOthersResult)
It is returning all of the data as a single continous string of text. How can I add a line break in between the columns of data that it is returning?
var data = new ResultsViewModel()
{
PatientFollowUpResult = PatientFollowUpResult,
PatientFollowUpResultPct = PatientFollowUpResultPct,
TotalResponsesResult = TotalResponsesResult,
ChangesOthersResult = ChangesOthersResult,
};
View Model Type
#model CMESurvey.ViewModels.ResultsViewModel
Perhaps something like:
#foreach (var x in Model.ChangesOthersResult)
{
#x<br>
}
<table>
<tr>
<th>
HeaderName1
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => modeItem.FieldName)
</td>
</tr>
}
</table>
Razor doesn't know that you want line breaks in between each item when you use
#Html.DisplayFor(modelItem => modelItem.ChangesOthersResult)
You can literally add the line break in the select by adding the string "<br/>" to each item before selecting it:
var ChangesOthersResult = surveyResponseRepository
.Query
.Select(r => r.ChangesOthers + "<br />");

Categories