How to create a function in a cshtml template? - asp.net-mvc

I need to create a function that is only necessary inside one cshtml file. You can think of my situation as ASP.NET page methods, which are min web services implemented in a page, because they're scoped to one page. I know about HTML helpers (extension methods), but my function is just needed in one cshtml file. I don't know how to create a function signature inside a view.
Note: I'm using Razor template engine.

why not just declare that function inside the cshtml file?
#functions{
public string GetSomeString(){
return string.Empty;
}
}
<h2>index</h2>
#GetSomeString()

You can use the #helper Razor directive:
#helper WelcomeMessage(string username)
{
<p>Welcome, #username.</p>
}
Then you invoke it like this:
#WelcomeMessage("John Smith")

If your method doesn't have to return html and has to do something else then you can use a lambda instead of helper method in Razor
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
Func<int,int,int> Sum = (a, b) => a + b;
}
<h2>Index</h2>
#Sum(3,4)

Take a look at Declarative Razor Helpers

In ASP.NET Core Razor Pages, you can combine C# and HTML in the function:
#model PagerModel
#{
}
#functions
{
void PagerNumber(int pageNumber, int currentPage)
{
if (pageNumber == currentPage)
{
<span class="page-number-current">#pageNumber</span>
}
else
{
<a class="page-number-other" href="/table/#pageNumber">#pageNumber</a>
}
}
}
<p>#PagerNumber(1,2) #PagerNumber(2,2) #PagerNumber(3,2)</p>

If you want to access your page's global variables, you can do so:
#{
ViewData["Title"] = "Home Page";
var LoadingButtons = Model.ToDictionary(person => person, person => false);
string GetLoadingState (string person) => LoadingButtons[person] ? "is-loading" : string.Empty;
}

Related

How to configure an MVC dropdown depending on which view calls it

I have two views, BatchReceipt and Receipt which utilise the same model. Until now they have used the same display template of ReceiptType. But I want to have one exclude certain items and the other to have the full list (so essentially a second .cshtml display template called ReceiptTypeFull). How do I configure each of these views in Visual Studio to utilise the different Display Templates?
Some additions to show the code being used:
I have file ReceiptType.cshtml being used as a DisplayTemplate which contains the following to setup the receipt dropdown
#using Clinton.Web.Helpers.EnumHelpers
#{
var item = EnumsHelper.GetNameFromEnumValue(Model);
}
I want to use a different DisplayTemplate, call it ReceiptTypeFull.cshtml
#using Clinton.Web.Helpers.EnumHelpersFull
#{
var item = EnumsHelper.GetNameFromEnumValue(Model);
}
#item
The difference is in calling the enumhelper or the enumhelperfull to vary the query populating the dropdown. My problem is that I cannot see how to redirect the view to use the different enumhelper/displaytemplate/
Thanks
I think I understand what you are getting at. You want to control which template is used for an Enum in the view.
I will explain using editor templates but it works the same way if you use display templates. You should be able to follow and apply for your scenario.
The idea is to use this overload of the editor html helper.
public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName);
It is called like this
#Html.Editor("{property name}", "{template name}").
Below is an example to show it being used.
Suppose we have this enum
public enum MyItems
{
Item1 = 1,
Item2 = 2,
Item3 = 3
}
This helper
public static class MyEnumHelper
{
public static List<MyItems> GetAllItems()
{
return new List<MyItems>()
{
MyItems.Item1,
MyItems.Item2,
MyItems.Item3
};
}
public static List<MyItems> GetSomeItems()
{
return new List<MyItems>()
{
MyItems.Item1,
MyItems.Item2
};
}
}
This controller
public class HomeController : Controller
{
public ActionResult AllItems()
{
return View();
}
public ActionResult SomeItems()
{
return View();
}
}
We have these 2 editor templates, which are put in views/shared/editortemplates
First one called MyItems.cshtml which is the all one
#model MyItems?
#{
var values = MyEnumHelper.GetAllItems().Cast<object>()
.Select(v => new SelectListItem
{
Selected = v.Equals(Model),
Text = v.ToString(),
Value = v.ToString()
});
}
#Html.DropDownList("", values)
Second one called MyItems2.cshtml which is the some one
#model MyItems?
#{
var values = MyEnumHelper.GetSomeItems().Cast<object>()
.Select(v => new SelectListItem
{
Selected = v.Equals(Model),
Text = v.ToString(),
Value = v.ToString()
});
}
#Html.DropDownList("", values)
Then in the AllItems.cshtml to get the MyItems.cshtml template called we need
#model MyItemsViewModel
#using (Html.BeginForm())
{
#Html.EditorFor(x => x.MyItem)
<submit typeof="submit" value="submit"/>
}
And in the SomeItems.cshtml to get some of the items by calling MyItems2.cshtml we use
#model MyItemsViewModel
#using (Html.BeginForm())
{
#Html.Editor("MyItem", "MyItems2") #* this bit answers your question *#
<submit typeof="submit" value="submit" />
}

Is it possible to add where clause in html.partial

i have html.partial in my html markup which is getting and displaying all the records from database. but i want to change it to selected records.. i mean i want to put where clause in html.partial.. is it possible to add where clause in partial and filter the records?
my html markup is like this
#Html.Partial("ListProductPartial", Model.Data.OrderByDescending(o => o.Id))
i am very much new to asp.net mvc. i am using pre defined code and want to understand the code. i hope you guys will help me to resolve this issue..
Depending on your model, this should work (keeping the OrderByDescending):
#Html.Partial("ListProductPartial", Model.Data.Where(o => o.Name == "FilterText").OrderByDescending(o => o.Id))
I do not recommend this style but you can try this sample;
Partial View
#model List<WebApplication4.Models.WebModelData>
#{
foreach (var item in Model)
{
#Html.Raw(item.Value)
}
}
Call to partial
#Html.Partial("PartialView", Model.Data.Where(o => o.Id > 5).ToList())
Controller:
public ActionResult Index()
{
List<Student> ob = new List<Student>()
{
new Student{ id=1, Name="x"},
new Student{ id=2, Name="y"},
};
return View(ob);
}
Index:
#model List<WebApplication15.Controllers.Student>
#{
ViewBag.Title = "Index";
}
#Html.Partial("Name",Model.OrderByDescending(x=>x.id))
<h2>Index</h2>
Partial View:
#model IEnumerable<WebApplication15.Controllers.Student>
#foreach (var student in Model)
{
<li>#student.id</li>
<li>#student.Name</li>
}

How to pass Controller Element value to View(.cshtml) div element value?

I developing WEB API project using .net C#
I need to get the value from controller.cs file and use that value into View(.cshtml) file.
My Controller Code:
HomeController.cs
XmlDocument doc = new XmlDocument();
doc.Load(httpWebResponse.GetResponseStream());
XmlElement TransID = (XmlElement)doc.SelectSingleNode("/CensusUploadResponse/TransactionID");
if (TransID != null)
{
string ResultID = TransID.InnerText;
}
I need to pass the ResultID to Index.cshtml(Ex:ResultID = 17)
MY View .cshtml file code:
Index.cshtml
<div runat="server" id="CensusuploadDiv" style="border:1px solid black; width:420px;">
</div>
I need to assign that ResultID value to CensusuploadDiv.
I try with following method using ViewBag. but's it's not working.
Assign ResultID to ViewBag like below
if (TransID != null)
{
string ResultID = TransID.InnerText;
ViewBag.Test2 = ResultID;
}
and i get the value in index file like below
<div runat="server" id="CensusuploadDiv" style="border:1px solid black; width:420px;">
#ViewBag.Test2
</div>
But value not bind to div.
I find out solution for my problem by Using TempData.
TempData help me lot...
I use TempData as follow in HomeController.cs
string result = strBind.ToString();
TempData["Result"] = result;
In view.cshtml
#TempData["Result"]
It's work fine for me...
Do you develop Web API or ASP.NET MVC project? Best way to access values from controller in view is to use strongly typed models:
#model int
<div>#Model</div>
Example:
Index.cshtml
#model int
<div>#Model</div>
HomeController.cs
public ActionResult GetId()
{
int id;
....
return View(id);
}
Please note, that WebApi and MVC controllers are slightly different. But this is how it works.

Looking for alternate ways to create blocks of HTML code in ASP.NET MVC 3

I'm not sure how to phrase my question, so I essentially want to be able to do something like this, in ASP.NET MVC 3:
#myJsHtmlCustomCode
{
<div><h1>Title</h1></div>
}
where anything in that myJsHtmlCustomCode block would be surrounded with some custom JavaScript/HTML code that I wrote.
I know I could use something like myJsHtmlCustomCode.Begin() and myJsHtmlCustomCode.End() in my code, but that doesn't provide the same formatting structure.
If anyone knows of a similar way to achieve the same objective, and get the automatic outlining/indent formatting, that would be great.
Just for reference, I wanted the the #myJsHtmlCustomCode to surround the code with for instance, another <div id="myTestId" onclick="thisClickEvent"></div> for the resulting code to look like...
<div id="myTestId" onclick="thisClickEvent">
<div><h1>Title</h1></div>
</div>
Option 1
You can wrap your code in an object that implements IDisposable, just like you use #using (Html.BeginForm())
Your code could be like this:
public class MyJsHtmlCustomCode : IDisposable {
private ViewContext _ctx;
public MyJsHtmlCustomCode (HtmlHelper html, /* other params */) {
_ctx = html.ViewContext;
/* Write begin tags */
_ctx.Writer.Write("html => opening tags"); }
public Dispose() {
_ctx.Writer.Write("html => closing tags");
}
}
and the extension:
public static MyJsHtmlCustomCode BeginMyJsHtmlCustomCode(this HtmlHelper html /* other params */) {
var result = new MyJsHtmlCustomCode(html);
return result;
}
Usage:
#using(Html.BeginMyMyJsHtmlCustomCode()) {
<div>This is surrounded by your code </div>
}
Option 2
You can use Razor Templated Delegates:
#{
Func<dynamic, object> b = #<strong>#item</strong>;
}
<span>This sentence is #b("In Bold").</span>
<div>#b(
#<span>
#DateTime.Now
</span><span>Example of more complex logic
</span>
)</div>
While I must admit I do not completely understand your question, whenever I need to do programatic custom HTML manipulation in .Net MVC 3 I use the Html Agility Pack.
Could you achieve your desired result using #section ?
e.g.: in one cshtml, possibly the _Layout:
<script type="text/javascript">
// whatever you want
// more whatever you want
#RenderSection("jsCode", false)
// even more whatever you want
</script>
Then in your actual view cshtml:
#section jsCode{
<div><h1>Title</h1></div>
}
You could possibly use a partial view for the js bit e.g.

Partial view inherits from master layout

I have a partial view and int it, there is no trace of any inheritance from any layout. But whenever I want to use it (render it) inside a view, the layout gets repeated once for the view, and once for the partial view. This post suggests to create an empty layout. But I think this is the workaround. Is there anyway to stop loading layout (master layout) for partial views. I don't understand, why when there is no code to use the master layout, why should it get loaded. It's just like creating a page in ASP.NET and seeing that it inherits from a master page without having <%# Master ... directive.
This is my partial view:
#* Recursive category rendering *#
#using Backend.Models;
#{
List<Category> categories = new ThoughtResultsEntities().Categories.ToList();
int level = 1;
}
#RenderCategoriesDropDown(categories, level)
#helper RenderCategoriesDropDown(List<Category> categories, int level)
{
List<Category> rootCategories = categories.Where(c => c.ParentId == null).ToList();
<select id='categoriesList' name='categoriesList'>
#foreach (Category rootCategory in rootCategories)
{
<option value='#rootCategory.Id' class='level-1'>#rootCategory.Title</option>
#RenderChildCategories(categories, level, rootCategory.Id);
}
</select>
}
#helper RenderChildCategories(List<Category> categories, int level, int parentCategoryId)
{
string padding = string.Empty;
level++;
List<Category> childCategories = categories.Where(c => c.ParentId == parentCategoryId).ToList();
foreach (Category childCategory in childCategories)
{
<option value='#childCategory.Id' class='level-#level'>#padding.PadRight(level, '-') #childCategory.Title</option>
#RenderChildCategories(categories, level, childCategory.Id);
}
level--;
}
I was able to reproduce this issue when rendering partial pages through ajax calls. The
return View("partialpage")
would always accompany with layout. I have overridden this behavior by explicitly calling
return PartialView("partialpage")
The layout might be coming from your ~/Views/_ViewStart.cshtml
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
You could try overriding this in your partial view like:
#{
Layout = null;
}

Resources