Unable to modify cshtml page in mvc - c#

There is a mvc application, in which I am trying to modify in pre-compiled CSHTML page(Index.cshtml)
#using System.Web.Mvc.Html
#model Services.Admin.ViewModels.IndexViewModel
#{
Layout = "~/Views/Admin/_Layout.cshtml";
ViewBag.Title = Resources.AdminResources.Index_Title;
}
<div class="container">
<div class="masonry">
<div class="item col-lg-4 col-md-4 col-sm-4">
<h3>Event Clinics</h3>
<table class="table table-striped table-bordered table-hover">
<tbody>
<tr>
<td class="max-width">
#Html.ActionLink("Premier Instructors", "Index", "PremierInstructor")
</td>
<td></td>
</tr>
<tr>
<td class="max-width">
#Html.ActionLink("Reports", "Index", "Reports")
</td>
<td></td>
</tr>
<tr>
<td class="max-width">
#Html.ActionLink("Users", "Index", "Users")
</td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
Here is also respective Index.generated.cs, in which all code is written with help of "WriteLiteral".
When I am trying to add/modify in .cshtml form, it's impact not showing on UI.
I have also find out on various sites and found that these cshtml is already compiled using "RazorGenerator" tools.
Now My problem is this, when I am going to make any changes in this type of cshtml file, it is not reflected on screen.

In case of RazorGenerator based pre-compiled .cshtml forms as there is need to modify it's html then follow below steps.
Right Click on .chstml file (ex. index.cshtml).
Click on "Properties".
Under "Advanced" section remove "RazorGenerator" from "Custom Tool" option.
DO CHANGES IN CSHTML FILE.
Again follow above 1,2 steps.
Under "Advanced" section add "RazorGenerator" in "Custom Tool" option.
Save form and run it.
Now you will be seeing all the changes in UI.

Related

How do I select a button before text using Selenium C#

I have a bit of a dilemma. I have a table of 3 columns. Column 1 is a button to make that row active. The 2nd column is the name of the person. And the 3rd column is a button to view the person's details.
Using Selenium C#, I can search for a specific person in the table and click the button to View, using the code below:
currentDriver.FindElement(By.XPath("(.//*[normalize-space(text()) and normalize-space(.)='Name of person'])")).Click();
How do I select the button before the name of the person?
EDIT: Added HTML -
<table class="table table-hover>
<thead>...</thead>
<tbody id="listCompany">
<tr>
<td>
<span id="a5" class="badge btnActivateCompany clsActiveCompany15" ><i class="fas fa-times"></i></span>
</td>
<td>Test Director</td>
<td>
<button.>...</button>
</td>
</tr>
</tbody>
The class btnActivateCompany is used several times depending on how many rows exist. And the id changes depending on the rows as well. So I have to search to find the correct record and then select the span before it.
I tried the following to select the object:
currentDriver.FindElement(By.XPath("(.//*[normalize-space(text()) and normalize-space(.)='Test Director'])[1]/preceding::span[1]")).Click();
I get the feeling you've modified the HTML as you've posted. I guess you stripped out some data and typed other content in. You say you want the button before the person, but in your code the button is after the person?
Either way, both are achievable. I made a few quick additions to help visibility. If i'm wrong please correct me as it influences xpaths.
Quick change log: I ran your html through a beautifier, added text to all the columns for visibility, added "border=1" to the table, remove the . from button, added the </table> and duplicated the row so i can check unique objects are found.
This is the result: (useful if anyone else wants to chip in an identifier)
<html>
<body>
<table class="table table-hover" border=1>
<thead>...</thead>
<tbody id="listCompany">
<tr>
<td>
<span id="a5" class="badge btnActivateCompany clsActiveCompany15" >
<i class="fas fa-times"> Column 1</i>
</span>
</td>
<td>Test Director</td>
<td>
<button> Button in col 3
</button>
</td>
</tr>
<tr>
<td>
<span id="a5" class="badge btnActivateCompany clsActiveCompany15" >
<i class="fas fa-times"> Column 1</i>
</span>
</td>
<td>Second Row!</td>
<td>
<button> Button in col 3
</button>
</td>
</tr>
</tbody>
</table>
</body>
</html>
That renders like this:
Based on fact you say you can get the text in the middle column...
If you want the button in column 3, you can try xpath:
//td[text()='Test Director']/parent::*/td/button
If you want the span in column 1, you can try:
//td[text()='Test Director']/parent::*/td/span[contains(#class,'btnActivateCompany')]
In both of these instances this selects a unique hit in the source.
However, please note, this is dependent on the html provided. If there are other elements/attributes in the table the xpath might need more work. I'm happy to help more but you'll need to share more content.

Blazor is disconnection when switching to another path

I have a strange issue in my blazor app. I don't know why but when I navigate from a specific path of my app to another path then I get a 400 disconnect message in my browser console.
When I navigate back to the entry point the connection becomes established again.
There are these paths right now
/
/Admin/Users
/Admin/Users/{name}
Admin/Users shows me a list of all employees from my SQL-Database.
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>E-Mail</th>
<th>Status</th>
<th>Aktion</th>
</tr>
</thead>
<tbody>
#foreach (var mitarbeiter in UserManager.Users)
{
<tr>
<td>#mitarbeiter.FirstName #mitarbeiter.LastName</td>
<td>#mitarbeiter.Email</td>
<td></td>
<td>
<a href="/Admin/Users/#mitarbeiter.UserName" class="btn btn-primary">
<i class="fa fa-edit"></i>
</a>
</td>
</tr>
}
</tbody>
</table>
As you can see, each employee has a a-Tag to /Admin/Users/{name}. When I click on it, everything works as expected. When I use the navigation now to go back to /Admin/Users then the connection will be terminated. It becomes established again when I go to / or to /Admin/Users manually again.
The navigation is defined as:
<AuthorizeView Roles="Administratoren">
<Authorized>
<div class="sb-sidenav-menu-heading">System</div>
<nav class="sb-sidenav-menu-nested nav">
<NavLink href="/Admin/Users" class="nav-link">Benutzer</NavLink>
</nav>
</Authorized>
</AuthorizeView>
The page /Admin/Users/{name} just displays some razor components to edit the employee. All sites uses the same default layout which contains the blazor.server.js
<script src="/_framework/blazor.server.js"></script>
Does anybody know, how I can fix this issue or what is causing it?
Thanks in advance!
To fix this issue, I added the following code to my _Host.cshtml
<base href="~/" />

Sort Table in asp.net mvc

How can I sort/filter a table using asp.net? I'm not sure exactly how to go about it, do I have to use jquery. Researching but i'm not seeing exactly how to handle this.
<table>
<tr>
<th class="col-lg-3 tablehead">Expense Account</th>
<th class="col-lg-3 tablehead">Description</th>
<th class="col-lg-3 tablehead">Requisition Number</th>
<th class="col-lg-3 tablehead">Item Number</th>
</tr>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>#Html.CheckBoxFor(m => m[i].postTrnx)</td>
#* <td class="label">#Html.DisplayFor(m => m[i].requisitionNumber) </td>*#
#*<td class="label">#Html.DisplayFor(m => m[i].transactionDate)</td>*#
</tr>
foreach (var item in Model[i].items)
{
#Html.HiddenFor(m => item.description)
#Html.HiddenFor(m => item.expense_account)
#Html.HiddenFor(m => item.itemNumber)
<tr>
<td class="col-lg-3 tabledata">#item.expense_account.account_desc</td>
<td class="col-lg-3 tabledata">#item.description</td>
<td class="label">#Html.DisplayFor(m => m[i].requisitionNumber) </td>
<td class="col-lg-3 tabledata">#item.itemNumber</td>
<td class="col-sm-1 tabledata">#item.quantity</td>
<td class="col-sm-1 tabledata">#item.selecteduomtext </td>
<td class="col-sm-1 tabledata">#item.price</td>
<td class="col-sm-1 tabledata">#item.extended_cost</td>
<td class="label">#Html.DisplayFor(m => m[i].transactionDate)</td>
<td>#Html.ActionLink("Edit", "Edit", new { id = #item.lineNum, name = Model[i].docNumber })</td>
</tr>
}
}
</table>
To let the user sort a html table you can use a JQuery plugin. Since I only used datatables so far I'll give you an example with that. Please see the official website for installation instructions. The usage is very easy, all you need to do is call
<script>$('table').DataTable();</script>
At the end of your html file.
Make sure to include DataTable plugin as described in the documentation.
Since you want the user to be able to sort the table by clicking on a column you could use DataTables.net as others have suggested or you could do it yourself with the following general steps:
Add client side javascript click events to each column header element that you want to sort that will call the appropriate controller action.
Add server side controller action event to handle sorting the data on the server.
In the click event do an ajax partial page callback to call the server side action event.
In the controller action event Sort the data as needed.
In the client side ajax response update/load the new table element.
Track the current sort order of each column.
It is probably easier to use DataTables.net since doing it yourself might require much more research.
Some links to help:
partial view with jquery ajax
sorting searching ajax
updating data in table
jquery ajax
jquery load

file upload in asp.net mvc 4 razor

I am using ASP .Net MVC 4.0 and VS10. I am a newbie in web application.
I have designed a page with html razor view. Here is some code of Index.cshtml:
#{
ViewBag.Title = "BAP Automation";
}
#section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>#ViewBag.Title.</h1>
<h2>#ViewBag.Message</h2>
</hgroup>
<form action="Index">
<table> **//EDITED BELLOW**
<tr><form action="" method="post">
<td>Upload Excel File: </td>
<td><input type="text" name="NAMEtxtFileName"/></td>
<td><input type="button" value="Upload" id="IDbtnUpload" name="NAMEbtnUpload"/></td>
</form>
</tr>
<tr>
<td>Company Name: </td>
<td><input type="text" /></td>
<td></td>
</tr>
<tr>
<td></td>
<td align="right"><input type="submit" value="Process" /></td>
<td></td>
</tr>
</table>
</form>
</div>
</section>
}
I am trying to upload an excel file in NAMEbtnUpload's click event. clicking on this button we will be in this page, just a file upload dialog will open and selecting the file, the file location will be shown in the NAMEtxtFileName textbox.
EDIT 1:
I have written some code from the suggested code:
[HttpPost]
public ActionResult Index(HttpPostedFileBase NAMEbtnUpload)
{
if (NAMEbtnUpload.ContentLength > 0)
{
var fileName = Path.GetFileName(NAMEbtnUpload.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/Given Excel's"), fileName);
NAMEbtnUpload.SaveAs(path);
}
return RedirectToAction("Index");
}
but this shows following error:
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /
Try adding the "EncType" attribute to your form.
#using (Html.BeginForm("ACTION", "CONTROLLER", FormMethod.Post, new { EncType="multipart/form-data"})){
//FORM MARKUP HERE
}
Phil Haack shows you how to handle file uploads with his blog post Uploading a File (Or Files) With ASP.NET MVC.
There is quite a bit of stuff you are missing so reading that post will get you further than any answer here.
** UPDATE FOR EDIT 1 **
A couple issues
<form action="index" > - this should be <form action="/ControllerName/Index">
You have multiple form tags that are nested. You can have multiple form tags but they can't be nested. In your case your only need one. Most of the time you only need 1.
<input type="button" value="Upload" id="IDbtnUpload" name="NAMEbtnUpload"/> should be
It is more conventional to use #using(Html.BeginForm()) as opposed to manually writing form tags. See below.
#using(Html.BeginForm("Index"))
{
<table>
<tr>
<td>Upload Excel File: </td>
<td><input type="text" name="NAMEtxtFileName"/></td>
<td><input type="file" id="IDbtnUpload" name="NAMEbtnUpload"/></td>
</tr>
<tr>
<td>Company Name: </td>
<td><input type="text" /></td>
<td></td>
</tr>
<tr>
<td></td>
<td align="right"><input type="submit" value="Process" /></td>
<td></td>
</tr>
</table>
}
clicking on [the upload] button we will be in this page, just a file upload dialog will open and selecting the file, the file location will be shown in the NAMEtxtFileName textbox.
That is not possible because a file upload element is not accessible programatically, anymore. "Back in the days" it was, and malicious sites silently uploaded sensitive information by setting the file upload control's value to well known password file locations and so on.
You'll just have to put an <input type="file" /> on your form and handle the upload serverside, as suggested in the link on #Bretts answer.
Set the name of file control in controller class.
for example in above code
public ActionResult Index(HttpPostedFileBase NAMEbtnUpload)
change NAMEbtnUpload to NAMEtxtFileName
this resolve your problem.

MVC views: How to render a table in a view only when a button clicked

I am new at MVC and have a view that has a search text box + button a navigation tab and table.
I would like the table to be populated only when the search criteria is entered and the button clicked.
The problem I am having now is that the table section of the view is rendered and returns a null object reference error when the page is loaded.
Other than using jquery/java functions how can I get the table to only populate when the the search criteria is entered and the button clicked?
Do I need to create 2 separate views(one with the table and one without)?
Here are parts of my view:
<div class="searchBox">
<label>Please search here
<input type="text" name="searchTerm" id="searchTerm" value="<%= !string.IsNullOrEmpty((string) ViewData["SearchTerm"]) ? Html.Encode(ViewData["SearchTerm"]) : "" %>" />
<input type="button" value="Add" />
</label>
</div>
<ul class="navigation">
<li><a class="selected" href="#name" >Person1</a></li>
<li>Person2</li>
<li>Person3</li>
<li>Person4</li>
</ul>
<div class="tabSection">
<div class="basic">
<table id="person" class="gridview">
<thead>
<tr>
<th>name</th>
<th>dob</th>
<th>address</th>
<th></th>
</tr>
<tr>
<td><%= Model.name %></td>
<td><%= Model.dob%></td>
<td><%= Model.address%></td>
<td></td>
</tr>
</thead>
</table>
</div>
</div>
You should just wrap your table in this:
#if (Model != null)
{
// table code
}
Also, you might want to consider putting your table logic into a partial view, and have the if statement in the partial view. That way, in your main view you could just have Html.RenderPartial("PARTAILVIEWNAME"); Doing it this way would allow you to have the same table in as many views as you want without having to remember to wrap the table in an if statement every time.

Categories

Resources