how to display docx or pdf in browser using mvc5 - c#

I am working on project in which I want to display docx or pdf in browser, these documents are coming from database as binary data. Here is my code
Controller
private DiagnosticDetailModel GetFileList(int id)
{
var DetList = db.DiagnosticDetailModels.Where(p => p.Id == id).FirstOrDefault();
return DetList;
}
[HttpGet]
public ActionResult RetrieveFile(int id)
{
DiagnosticDetailModel diagnosticDetailModel = GetFileList(id);
byte[] img = diagnosticDetailModel.FileContent.ToArray();
string s = Encoding.UTF8.GetString(img);
Response.Buffer = true;
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(img);
Response.AppendHeader("Content-Disposition", "inline");
ViewData["myInnerHtml"] = s;
return View("test", ViewData["myInnerHtml"]);
}
test.cshtml
<div id="doc-viewer-id" style="width:500px; height:500px;">
#(new HtmlString(ViewData["myInnerHtml"].ToString()))
</div>
index.cshtml
<table>
<thead style="background-color:#5bc0de; color:white;font-size:14px;">
<tr>
<th>#</th>
<th>
Diagnostic Name
</th>
<th>
Registration Date
</th>
<th>View Report</th>
</tr>
</thead>
<tbody style="font-size:12px;">
#foreach (var item in Model)
{
<tr>
<td></td>
<td>
#Html.DisplayFor(modelItem => item.DiagnosticName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.ActionLink("View", "RetrieveFile", new { id = item.Id }, new { #class = "btn btn-primary btn-sm fa fa-eye", #style = "color:white;background-color:#5bc0de;",#target="_blank" })
</td>
</tr>
}
</tbody>
</table>
when I click on button to display document in browser I am getting data like this which is showing in below image
anyone know where I am doing wrong in code?

Related

Showing results on table data HTML

In my ASP.NET MVC web application, there is a table I have created and loads the data to the table from model.
There is a column, the data I want to show I load separately like this.
<tbody> #foreach (var item in Model.OrderByDescending(i => i.Id)) { <tr>
<td> #Html.DisplayFor(modelItem => item.Id) </td>
<td> #Html.DisplayFor(modelItem => item.ReqestTypeDisplay) </td>
<td> #Html.DisplayFor(modelItem => item.Created_Date) </td>
<td> #Html.DisplayFor(modelItem => item.Req_Heading) </td>
<td> #Company.Find(x => x.Value == item.Company_Id.ToString()).Text </td>
<td id="department">
<span data-toggle="fetch" data-url="#Url.Action(" ReqFromDepartment", "PendingRequestM" , new { id=item.Id })">Loading...</span>
</td>
<td> #Html.ActionLink("View", "View", new { id = item.Id }, new { #class = "btn btn-warning pull-right" }) <button onclick="confirmDelete(#item.Id);" , class="btn btn-danger pull-right">Reject</button>
</td>
</tr> } </tbody></table>
The script I have used after the table
< script >
window.addEventListener('DOMContentLoaded', (event) => {
document.querySelectorAll("[data-toggle='fetch']").forEach(async (el) => {
const url = el.dataset.url;
const response = await fetch(url);
if (!response.ok) {
const errorMessage = await response.text();
console.error(response.status, response.statusText, errorMessage);
el.innerHTML = "Error loading department";
return;
}
const data = await response.text();
$('#department').html(data);
});
}); <
/script>
So the issue is it gets the data and shows it, but only in the 1st row of the table. If there is more than 1 row, it searches and replaces the value From Department. How can I assign row-by-row results?

Show/hide jQuery datatable action link button based upon column value

My LINQ query for retrieving data:
public ActionResult GetRegFirmList()
{
try
{
var data = (from z in db.BusinessModels
select z).OrderByDescending(z => z.BusinessKey).ToList();
return View(data);
}
catch (Exception ex) { throw; }
}
I have two action link buttons in the jQuery datatable. I need to hide the button for Certificate if the value of Status is 1 in the particular row. The action link button for Application should not be hidden. How can I do that?
<link href="~/Content/DataTables/css/dataTables.bootstrap.min.css" rel="stylesheet" />
<table id="tblBusinessData">
<thead class="table-success">
<tr>
<th>generate</th>
<th style="visibility:hidden;">
#Html.DisplayNameFor(model => model.BusinessKey)
</th>
<th>
#Html.DisplayNameFor(model => model.BusinessName)
</th>
<th>
#Html.DisplayNameFor(model => model.PropName)
</th>
<th>
#Html.DisplayNameFor(model => model.Status)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.ActionLink("Certificate", "GenerateCertificate", new { id = item.BusinessKey }, new { #class = "btn btn-warning" })
#Html.ActionLink("Application", "GenerateApplication", new { id = item.BusinessKey }, new { #class = "btn btn-warning" })
</td>
<td style="visibility:hidden;">
#Html.DisplayFor(modelItem => item.BusinessKey)
</td>
<td>
#Html.DisplayFor(modelItem => item.BusinessName)
</td>
<td>
#Html.DisplayFor(modelItem => item.PropName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</td>
</tr>
}
</tbody>
</table>
<script src="~/Scripts/DataTables/jquery.dataTables.min.js"></script>
<script src="~/Scripts/DataTables/dataTables.bootstrap.min.js"></script>
<script type="text/javascript">
$('#tblBusinessData').DataTable({
"columnDefs": [{
"targets": [1],
"visible": false
}],
"order": [
[1, "desc"]
]
});
</script>
You can add condition like this
#if(item.Status!=1)
{
#Html.ActionLink("Certificate", "GenerateCertificate", new { id = item.BusinessKey }, new { #class = "btn btn-warning" })
}
So your foreach loop should be like below
#foreach (var item in Model)
{
<tr>
<td>
#(item.Status!=1){#Html.ActionLink("Certificate", "GenerateCertificate", new { id = item.BusinessKey }, new { #class = "btn btn-warning" })}
#Html.ActionLink("Application", "GenerateApplication", new { id = item.BusinessKey }, new { #class = "btn btn-warning" })
</td>
<td style="visibility:hidden;">
#Html.DisplayFor(modelItem => item.BusinessKey)
</td>
<td>
#Html.DisplayFor(modelItem => item.BusinessName)
</td>
<td>
#Html.DisplayFor(modelItem => item.PropName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</td>
</tr>
}

Whats the best way of using ajax jquery to load partial views onto a specific page?

I have a index page the code looks like this
#model PagedList.IPagedList<PartialViews.Models.Customer>
#using PagedList.Mvc
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<div class="container">
<table class="table">
<tr>
<th>
Title
</th>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Email Address
</th>
<th>
Phone Number
</th>
<th>
Modified Date
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.EmailAddress)
</td>
<td>
#Html.DisplayFor(modelItem => item.Phone)
</td>
<td>
#Html.DisplayFor(modelItem => item.ModifiedDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.CustomerID }) |
#Html.ActionLink("Details", "Details", new { id = item.CustomerID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.CustomerID })
</td>
</tr>
}
</table>
#Html.PagedListPager(Model,page=>Url.Action("Index",new{page,pageSize=Model.PageSize}))
</div>
My CustomersController has this code
private AdventureWorksLT2012Entities db = new AdventureWorksLT2012Entities();
// GET: Customers
public ActionResult Index(int page=1, int pageSize=10)
{
List<Customer> customers = db.Customers.ToList();
PagedList<Customer> cust = new PagedList<Customer>(customers,page,pageSize);
return View(cust);
//return View(db.Customers.ToList());
}
Heres the Main page where i want the Customers List from the Index action to be shown
#model PartialViews.Models.Customer
#{
ViewBag.Title = "Main";
}
<body>
<div class="container">
<h2>Customer's List</h2>
<div id="dvCustomerDetails" style="width: 50%; height: 130px;display: none"></div>
</div>
</body>
<script type="text/javascript">
$.ajax({
url: 'Customers/Index',
contentType: 'application/html;',
type: 'GET',
dataType:'html'
})
.success(function(result) {
$('#dvCustomerDetails').html(result);
})
</script>
I want to display this table onto a new page as a partial view using ajax jquery but I am having trouble implementing it.
I was able to use RenderPartial method to display it as a partial view but i am having trouble doing it with ajax. Any help or suggestion will be appreciated.

MVC Partial View not rendering

Partial view is not rendering while passing ViewModel.. Its rendering without ViewModel.
I mean if I keep #Html.Partial("PartialClientIndex") then its rendering and when I pass ViewModel it directly going to Dispose without rendering partial view.
I'm missing something here.. could you please help in this.
Main View:
<div id="PartialClient">
#Html.Partial("PartialClientIndex", viewModelList)
</div>
Action:
[HttpPost]
public ActionResult PartialClientIndex(int? SelectedGroupId)
{
int SkipRec = 0;
int NextRec = 25;
VMClient vmclient = new VMClient();
vmclient.IEClients = db.client.Where(cl => cl.Groups.id == SelectedGroupId).OrderBy(c => c.id).Skip(SkipRec).Take(NextRec).ToList();
return PartialView("PartialClientIndex", vmclient);
}
Partial View:
#model IEnumerable<HostingManager.Models.VMClient>
<table>
<thead>
<tr>
<th style="width:25px; padding:10px;">
Group
</th>
<th class="tbContent-Name">
Client Name
</th>
<th class="tbContent-Name">
Contact Person
</th>
<th class="tbContent-Name">
Contact Email
</th >
<th></th>
</tr>
</thead>
<tbody>
#if(Model != null)
{
var x = Model.Select(c=>c.IEClients).ToList();
var y = x[0].ToList();
// var y = x[0]["item1"];
foreach (var item in y) {
<tr>
<td class="tbContent-Name">
#Html.DisplayFor(modelItem => item.Groups.name)
</td>
<td class="tbContent-Name">
#Html.DisplayFor(modelItem => item.contactPerson)
</td>
<td class="tbContent-Name">
#Html.DisplayFor(modelItem => item.contactPerson)
</td>
<td class="tbContent-Name">
#Html.DisplayFor(modelItem => item.contactEmail)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.id }, new { onclick = "return confirm('Are you sure you wish to delete this ?');" })
</td>
</tr>
}
}
</tbody>
It seems that the variable vmclient that you are passing as model into your partial view is of type VMClient. Though your partial view is expecting the IEnumerable<VMClient> type.
You basically have to change the model type in your partial view to the following
#model HostingManager.Models.VMClient
and adjust the way you are assigning the y variable
var y = Model.IEClients;

Asp.Net - EF - MVC - Indexing Rows

I am using Asp.Net , EF6 ( MVC ) and have some data stored in my view. What I need is some indexing for each row. Here is the view.
For every row I have 0 Index. I wanna know, if there is some Built in feature in EF, that will help to add indexes for each row, (1,2,3....) and which will be automatically be updated, when new rows are created or deleted.
This is the Code for creating the table and doing Paging in my View.
<div class="bs-example">
<div class="table-responsive">
<div class="panel panel-default">
<table class="table table-striped table-hover table-bordered" cellspacing="0" data-toggle="table" data-click-to-select="true">
<tr>
<th style="vertical-align:middle;" class="text-center">
Index
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("English", "Index", new { sortOrder = ViewBag.EnglishSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Russian", "Index", new { sortOrder = ViewBag.RussianSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Armenian", "Index", new { sortOrder = ViewBag.ArmenianSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("French", "Index", new { sortOrder = ViewBag.FrenchSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Spanish", "Index", new { sortOrder = ViewBag.SpanishSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="vertical-align:middle;" class="text-center">
#Html.ActionLink("Arabic", "Index", new { sortOrder = ViewBag.ArabicSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th></th>
</tr>
#{
foreach (var item in Model.Item1)
{
<tr class="clickableRow">
<td style="vertical-align:middle; font-size:medium;font-style:italic;" class="text-center">
#ViewBag.IndexOfRow.ToInt32
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.English)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Russian)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Armenian)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.French)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Spanish)
</td>
<td style="vertical-align:middle;" class="text-center">
#Html.DisplayFor(modelItem => item.Arabic)
</td>
<td style="vertical-align:middle;" class="text-center">
<span style="color:white;">
#Html.ActionLink("Edit", "Edit", new { id = item.Text, #style = "color:red;" })
#*#Html.ActionLink("Details", "Details", new { id = item.Text })*#
#Html.ActionLink("Delete", "Delete", new { id = item.Text })
</span>
</td>
</tr>
}
}
</table>
</div>
<br />
Page #(Model.Item1.PageCount < Model.Item1.PageNumber ? 0 : Model.Item1.PageNumber) of #Model.Item1.PageCount
#Html.PagedListPager(Model.Item1, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
</div>
</div>
And this is the code from my Controller
public ViewResult Index(int? page)
{
int pageSize = 15;
int pageNumber = (page ?? 1);
var allModels = new Tuple<IPagedList<Translation>, List<Translation>>
(translations.ToPagedList(pageNumber, pageSize), translations.ToList()) { };
return View(allModels);
}
I have removed the unnecessary code, only is left the code for paging.
I have not done anything so far, because I have not find any indexing question or article in Google or SO so far.
Thanks for help.
And if you want to put Index while creating table, you can loop like this in your table body:
<tbody>
#{
int counter = 1;// Index start value
foreach (var Item in Model.SomeList)
{
<tr>
<td> #counter </td>
</tr>
counter++;
}
}
</tbody>
Just set the start row index in the action method to ViewBag.
int pageSize = 15;
int pageNumber = (page ?? 1);
ViewBag.StartRowIndex = ((pageNumber - 1) * pageSize) + 1;
Then use it in the view.
#{
var rowIndex = (int)ViewBag.StartRowIndex;
}
foreach (var item in Model.Item1)
{
<tr class="clickableRow">
<td style="vertical-align:middle; font-size:medium;font-style:italic;" class="text-center">
#(rowIndex++) //#ViewBag.IndexOfRow.ToInt32
</td>
When you dont know what to do, create a new class :))
Im kidding, but the idea remains valid.
Why dont you craete a new class that will represent your "ViewModel" that will have the exact EF model inside and an extra Index property that you will use to bind to an index in the view?
What you will pass from your controller to the view will be the new ViewModel class.
Note:
If you want to go fancy, you could go somewhere on the line of : ObservableCollection http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx which derrives from INotifyPropertyChanged
Basically it means that you have an event at your disposal that you can fire when the list has changed (add, delete) that will be used to update the index.

Categories

Resources