Generating HTML from server-side block in ASP.NET MVC - c#

This is a very newbie kind of ASP.NET question: I simply don't know and can't work out the correct syntax to use.
In my view I want to generate an action link if a certain condition is true on my model. I know how to generate a link using this syntax:
<%: Html.ActionLink("Do Something", "DoSomething", new { id = Model.ID }) %>
But for some reason that syntax doesn't work in this code:
<%
if (Model.CanDoSomething)
Html.ActionLink("Do Something", "DoSomething", new { id = Model.ID });
%>
I really am a newbie to ASP.NET, so I don't even know what the semantic name is for the different syntaxes <% and <%:; all I can tell is that <% is to void as <%: is to string. And clearly executing a line of code that just returns a string (Html.ActionLink()) is not going to have any effect. But what, pray what is the correct method to make my page render the action link?
It's a great pity I can't Google on "<%"! Any links or explanations of this subject will also be much appreciated.

This will do the trick
<% if (Model.CanDoSomething) { %>
<%: Html.ActionLink("Do Something", "DoSomething", new { id = Model.ID }) %>
<% } %>
<%: writes to the output buffer but encodes the string. You could also use <%= for unencoded output because ActionLink returns an encoded MvcHtmlString.
EDIT: This may also work
<%
if (Model.CanDoSomething)
Response.Write(Html.ActionLink("Do Something", "DoSomething", new { id = Model.ID }));
%>

<% - this by itself has no output. You would include code with no output in this block such as an if statement. If you want output - you must use it in conjunction with <%=
The difference with the : is that
<%: means it will output to the response stream, not = required however the : means the output will be htmlencoded.
<%:"sometest&text" %> //will emit "sometesttext" on the page.. htmlencoded.
<%="sometest&text" %> //will give you the same result without the '&' htmlencoded
<% SomeFunction() %> //will just run that function - there is no output
//you want
<%if (Model.CanDoSomething){%>
<%:Html.ActionLink("Do Something", "DoSomething", new { id = Model.ID })%>
<%}%>

Related

How to show the current user using ASP MVC and EF

I am developing an ASP .Net MVC 3 application using C# and SQL Server 2005. I am using also Entity Framework with Code First Method.
I have an interface for the LOG ON (connection) which it is related to my base where i have a USER table (contain Login + password).
I am just want to show the Current User which is logged. So, I created a ViewModel Class for the User but i didn't get any result.
This is what I tried to do in my Controller :
public ActionResult LogOn()
{
var user = new UserViewModel();
user.Nom_User = this.User.Identity.Name;
ViewData["UserDetails"] = user;
return View();
}
and this what I add in the master page :
<% var User = ViewData["UserDetails"] as MvcApplication2.ViewModels.UserViewModel; %>
Hello : <%: User.Nom_User %>!
When I execute, I have this error :
Object reference not set to an instance of an object.
You said that you placed this code in your MasterPage. This means that it will run for every view.
But you have set the ViewData["UserDetails"] only inside the LogOn action. So when you navigate to some other action (such as the Home/Index action for example) it will bomb because there's nothing inside this ViewData["UserDetails"] and of course this User variable which you declared in your MasterPage will be null.
I would recommend you using a child action for that.
[ChildActionOnly]
public ActionResult LogedInUser()
{
if (!Request.IsAuthenticated)
{
return PartialView();
}
var user = new UserViewModel();
user.Nom_User = User.Identity.Name;
return PartialView(user);
}
and in your MasterPage:
<% Html.RenderAction("LogedInUser", "Account"); %>
or if you prefer:
<%= Html.Action("LogedInUser", "Account") %>
And finally you could have the corresponding LogedInUser.ascx partial that will be strongly typed to your view model:
<%# Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<UserViewModel>"
%>
<% if (Model != null) { %>
<div>Hello : <%= Html.DisplayFor(x => x.Nom_User) %></div>
<% } %>
Phil Haack blogged about child actions in more details here.
Try using session
Session["user"]=this.User.Identity.Name;
and in view you can get user name with <% var User =Session["user"]%> or you can directly use:
<% var User =this.User.Identity.Name;%>

Posting two and more lists in asp.net mvc

I'm using asp.net mvc 2 and i found this behavour which i can't understand.I have following view:
<% using (Html.BeginForm("Index", "BlackListGrabber", FormMethod.Post) )
{
<%= Html.DropDownListFor(m => m.selectedArea, new SelectList(Model.areaList, "value", "text")) %>
<% if (Model.districtList != null) { %>
<%= Html.DropDownListFor(m => m.selectedDistrict, new SelectList(Model.districtList, "value", "text")) %>
<% } %>
<% if (Model.townList!= null) { %>
<%= Html.DropDownListFor(m => m.selectedTown, new SelectList(Model.townList, "value", "text")) %>
<% } %>
<input type="submit" value="post" />
<% } %>
and a controller's method like this:
[HttpPost]
public ActionResult Index(BlackListGrabberModel postedModel)
{
BlackListGrabberModel model = new BlackListGrabberModel(postedModel);
return View(model);
}
And, last but not least, my model:
BlackListGrabberModel(BlackListGrabberModel model)
{
if (string.IsNullOrEmpty(model.selectedArea))
{
areaList = GetRegions();
}
else if (string.IsNullOrEmpty(model.selectedDistrict))
{
areaList = model.areaList;
districtList = GetRegions(model.selectedArea);
}
else if (string.IsNullOrEmpty(model.selectedTown))
{
areaList = model.areaList;
districtList = model.districList;
districtList = GetRegions(model.selectedDistrict);
}
}
Idea is that then i load page, i see list of all possible areas.(And i see it - it's my first dropdownlistfor) When i select area, after clicking "post" button, i see list of all districts, they loaded from external source and this part works fine.
So i select district from list, and click "post". After thar i see list of all towns located in selected district, but districtList disappears. Then i traced it in my controller, i found that property postedModel.districtList is null. But postedModel.areaList is fine! Does that mean that i can post only one SelectList, or i'm missing something? Can somebody please give me any help?
P.S. Properties "selectedArea", "selectedDistrict", "selectedTown" are posted as expected.
EDIT. Thanks to everybody, i missed some important things, and you gave me direction to them.
My problem appeared to be areaList. It was filled by default constructor. I forgot about that, so then i saw postedModel.areaList filled, i thought it was magically posted by asp.net mvc mechanisms, and complained that all other lists are not filled because of some strange glithces.
You will have to repopulate your list properties in your model for every request.
The won't get posted back automatically. Just the selected value is posted back and bound to the property in your model (i.e. selectedArea is bound but not areaList).
The lists should not post, only the values of the select elements in your html form will. If you need to hold onto the list values, you might try placing them in TempData in you GET for Index, which will keep them for the next request.

How do I pass model values as javascript function parameters from inside an asp.net mvc Html helper such a Html.Radio?

Okay, pretty simple question. I think I need to drop in some escape characters, but I'm not quite sure where.
Here is the javascript function I'm attempting to call:
function setData(associateValue, reviewDateValue) {
var associate = document.getElementById("Associate");
var reviewDate = document.getElementById("ReviewDate");
associate.value = associateValue;
reviewDate.value = reviewDateValue;
}
Here is the asp .net mvc line where I'm attempting to create a Radio button with a click event that calls the above function and passes data from the model as javascript parameter values.
<%= Html.RadioButton("Selected", item.Selected, new { onClick="setData('<%=item.Associate%>','<%=item.ReviewDate%>' )" } )%>
The above throws a bunch of compile issues and doesn't work. A call such as the following does call the javascript, but doesn't get the data from the model.
<%= Html.RadioButton("Selected", item.Selected, new { onClick="setData('item.Associate','item.ReviewDate' )" } )%>
<%= Html.RadioButton("Selected", item.Selected, new { onClick="setData('item.Associate','item.ReviewDate' )" } )%>
Thoughts?
SOLUTION
<% String functionCall = String.Format("setData('{0}','{1}')", Html.Encode(item.Associate), Html.Encode(item.ReviewDate )) ; %>
<%= Html.RadioButton("Selected", item.Selected, new { onClick=functionCall } )%>
You need to properly build the string that represents the onclick evenet handler:
onClick = String.Format("setData('{0}', '{1}')", item.Association, item.ReviewData)
It should be like this:
<%: Html.RadioButton("Selected", item.Selected, new { onClick="setData('" + Html.Encode(item.Associate) + "','" + Html.Encode(item.ReviewDate) + "' )" } )%>
And if it's MVC2 you should prefer to use : instead of = to make sure it's HTML-encoded.

How to manipulate Html.ActionLink to show a link to another controller?

In the Details view of the HomeController, I'd like to create a link to the Email view on the MiscController. In addition, I need to add an item to the QueryString.
I'd like to create a link that goes something like:
<a href="http://www.blah.com/misc/SendMail?id=6">
<font size="1">Report problems</font>
</a>
I've tried the following:
<% Html.ActionLink("<font size=\"1\">Report</font>", "SendMail", "Misc", Model.ImageID, new object()); %>
It returned no link. What am I missing?
First of all, you missed the = after the <%. That's why it didn't output anything.
Also, the way you passed routeValues parameter was wrong.
It should be :
<%=Html.ActionLink("<font size=\"1\">Report</font>", "SendMail", "Misc",
new { id = Model.ImageID }, null /*htmlAttributes*/) %>
Please keep in mind though the text argument will be encoded in the output, so there's no point in sending HTML with that argument.
It's best to use CSS to style your HTML.
For example :
a.myLink {font-size: 0.5em;color:yellow;}
And to set the class attribute for the anchor element :
<%=Html.ActionLink("Report", "SendMail", "Misc",
new { id = Model.ImageID }, new { #class = "myLink" }) %>

HowTo: Using MvcContrib.Pagination without using MvcContrib.Grid View

This started as a question, but turned into a solution as I did some experimenting! So I thought I would share this with you all. My question WAS:
How to use MvcContrib.Pagination without using MvcContrib.Grid View?
My answer is below...
I am building a Help Desk Ticketing System (I am kind of a C# newbie - got many pointers from NerdDinner) and I wish to use some sort of paging library to help with the view. I found MvcContrib.Pagination and I got it to work for a view. My view does NOT use MvcContrib.Grid because it is custom.
Scaled down version of my view List.aspx :
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<MyProject.Areas.HelpDesk.Models.hd_Ticket>>" %>
<%# Import Namespace="MyProject.Areas.HelpDesk.Controllers" %>
<%# Import Namespace="MvcContrib.Pagination" %>
<h2>Help Desk Tickets (showing <%= Model.Count() %> of <%= ViewData["totalItems"] %>)</h2>
<% foreach (var item in Model) { %>
<h3><%= Html.Encode(item.Subject)%></h3>
<% } %>
<p><%= Html.Pager((IPagination)Model)%></p>
My controller (part) TicketController.cs :
TicketRepository ticketRepository = new TicketRepository();
public ActionResult List(int? page, int? pageSize)
{
IPagination<hd_Ticket> tickets = null;
int dPageSize = 50;
int totalItems;
tickets = ticketRepository.GetTickets().ToList().AsPagination(page ?? 1, pageSize ?? dPageSize);
ViewData["totalItems"] = tickets.TotalItems;
return View("List", tickets);
}
I am using the repository pattern which is returning the results as IQueryable. Here is part of the TicketRepository.cs file:
public class TicketRepository
{
private HelpDeskDataContext db = new HelpDeskDataContext();
public IQueryable<hd_Ticket> FindAllTickets()
{
return from ticket in db.hd_Tickets
orderby ticket.CreatedDate descending
select ticket;
}
}
All this may be trivial to some, but if someone like me is trying to learn C# and ASP.NET MVC and paging, then this may be useful. I recommend newbies to do the NerdDinner tutorial found at:
http://nerddinnerbook.s3.amazonaws.com/Intro.htm
:)

Categories

Resources