Conditional ActionLink in Razor view not rendering(asp.net mvc 3) - asp.net-mvc

I am scratching my head as to why not this isn't working:
#if (Model.Guid != null) { Html.ActionLink("Fil", "GetFile", new { id = Model.DocumentID }); }
The conditional on its own is working as putting som random HTML in there instead of an actionlink works:
#if (Model.Guid != null){<span>Test</span>}
Likewise the actionlink on it's own renders without a problem.
Could anybody clue me in to what is going on here?

You need to put an # sign before the Html.ActionLink.
Like this:
#if (Model.Guid != null) { #Html.ActionLink("Fil", "GetFile", new { id = Model.DocumentID }); }
EDIT: Forgot to add that you don't need the semi colon, but you can leave it in if you want.

Related

ASP.net IF Request.Url.Host == Wildcard

How do I use a wildcard in the URL of my comparison for Request.URL.Host? I have a site that's been running for years with the test site showing as blue. The comparison used to use the entire URL.
#if (Request.Url.Host == "URLtest.site.com") //
{
bodyclass = "test";
}
We are adding a second test site and I'd like to set this one time. So I would like to use a wildcard. Something like this, but it doesn't seem to work. I'm sure I'm missing something simple.
#if (Request.Url.Host == "*test.*") //
{
bodyclass = "test";
}
You can use RegEx as suggested in other answers.
A simpler check would be to use string.Contains()
#if (Request.Url.Host.Contains("test.")) //
{
bodyclass = "test";
}
Please use Regex Match method
using System.Text.RegularExpressions;
var pattern = #"\w*test.\w*";
string input = "url2test.site.com";
var match = Regex.Match(input, pattern, RegexOptions.IgnoreCase);
if (match .Success)
{
}

MVC Session global variable

Here is what I'm trying to achieve. Certain options at the navbar should be available only if the user has "subordinates" in the database.
So, at the navbar I have:
The Approvals should be hidden for some users, but available to others. For those whom it should be available, the user must:
A) Be a Supervisor or,
B) Have a subornidate at the DB table
So, as for "A" it's pretty straightforward. I did:
#if (User.IsInRole("Supervisor"))
{
<li>#Html.ActionLink("Approvals", "Index", "Approval")</li>
}
For "B", I was suggested to use Sessions. Well, great. So I came to the question: how can I make a single request to the DB and assign it to a Session["HasSubordinates"] so I can do this check?
#if (User.IsInRole("Supervisor") || (bool)Session["HasSubordinates"])
{
<li>#Html.ActionLink("Approvals", "Index", "Approval")</li>
}
What I tried was to have:
Session["HasSubordinates"] = _uow.ApprovalService.GetSubordinates(User.Identity.Name).Count() > 0;
for every single controller, but that didn't worked well because sometimes I get null pointer and it looks absolutely rubbish.
I know it may sound like a trivial question for some (or most), but I'm really stuck and I do really appreciate any help.
Looking at your code, getting a user subordinates should only happen once. In your Login method:
Session["HasSubordinates"] = _uow.ApprovalService.GetSubordinates(User.Identity.Name).Count() > 0;
Create a new class to extend IPrincipal:
public class IPrincipalExtensions
{
public bool HasSubordinates(this IPrincipal user)
{
return Session != null && Session["HasSubordinates"] != null && Session["HasSubordinates"] > 0;
}
}
Now, in the View:
#if (User.IsInRole("Supervisor") || User.HasSubordinates() )
{
}
Writing from memory, may have left something out, but this should be the cleanest.
Don't use the session for this. What you need is a child action.
[ChildActionOnly]
public ActionResult Nav()
{
var model = new NavViewModel
{
IsSupervisor = User.IsInRole("Supervisor");
HasSubordinates = _uow.ApprovalService.GetSubordinates(User.Identity.Name).Count() > 0;
}
return ParialView("_Nav", model);
}
Then, just create a partial view, _Nav.cshtml and utilize the properties on the view model to render your nav however you like.
If you want, you can even use output caching on the child action, so it's only evaluated once per user. There's no built-in way to vary the cache by user, so first, you'll need to override the following method in Global.asax:
public override string GetVaryByCustomString(System.Web.HttpContext context, string custom)
{
var args = custom.ToLower().Split(';');
var sb = new StringBuilder();
foreach (var arg in args)
{
switch (arg)
{
case "user":
sb.Append(User.Identity.Name);
break;
case "ajax":
if (context.Request.Headers["X-Requested-With"] != null)
{
// "XMLHttpRequest" will be appended if it's an AJAX request
sb.Append(context.Request.Headers["X-Requested-With"]);
}
break;
default:
continue;
}
}
return sb.ToString();
}
With that, you can then just decorate your child action with:
[OutputCache(Duration = 3600, VaryByCustom = "User")]

check member existence in Mvc ViewBag

Sometimes I have to check the existence of a member inside the ViewBag from inside an Mvc View, to see if for any problem the action forgot to assign the member. Inside my Razor View I have:
#if(ViewBag.Utente.Ruolo.SysAdmin)
how can I check that ViewBag.Utente is defined?
You must check all objects are null or not. Utente, Utente.Ruolo and Utente.Ruolo.SysAdmin may be null:
#if (ViewBag.Utente != null)
{
if (ViewBag.Utente.Ruolo != null)
{
if (!string.IsNullOrEmpty(ViewBag.Utente.Ruolo.SysAdmin))
{
//ViewBag.Utente.Ruolo.SysAdmin has value..you can use it
}
}
}
As simple as this:
#if (ViewBag.Utente != null)
{
// some code
}
If you are using MVC4 you can use
#if (ViewBag.Utente != null)
For previous versions take a look at those answers:
Checking to see if ViewBag has a property or not, to conditionally inject JavaScript
You can you use it;
#if (string.IsNullOrEmpty(ViewBag.Utente.Ruolo.SysAdmin))
{
}
But if you want to check your users are confirmed or not, I think it is not a good way..

Change the Telerik DateTimePicker element ID, but keep the name

I have a ASP.NET MVC page with multiple forms on it, where each form edits a different instance of the same class. Each form also includes a Telerik DateTimePicker control. What I want is to have the element IDs change, but not the element name. So I have something like this:
string idString = string.Format("MyObject{0}", Model.ID)
#Html.Telerik().DatePickerFor(m => m.SomeDate).HtmlAttributes(new { id = idString + "-SomeDate" })
Now this works mostly fine, except that at the bottom of the page, the auto-generated Javascript that Telerik puts in looks like:
jQuery('#SomeDate').tDateTimePicker({
format:'M/d/yyyy h:mm tt',
minValue:new Date(1899,11,31,0,0,0,0),
maxValue:new Date(2100,0,1,0,0,0,0),
startTimeValue:new Date(2013,3,22,0,0,0,0),
endTimeValue:new Date(2013,3,22,0,0,0,0),
interval:30,
selectedValue:new Date(2013,3,22,11,9,1,180)
});
Note that my idString value didn't get put in. I can try:
#Html.Telerik().DatePickerFor(m => m.SomeDate).Name(idString + "SomeDate")
And this makes the auto-generated Javascript correct (jQuery('#MyObject123-SomeDate')) but now the element name is wrong, so TryUpdateModel fails.
How can I get this to work? Thanks.
EDIT: I hacked this using the following Javascript, but this is a kludgy way to fix this.
$(function () {
window.setTimeout(function () {
for (var i = 0; i < document.getElementsByTagName("input").length; i++) {
var obj = document.getElementsByTagName("input")[i];
if (obj.id.indexOf("SomeDate") == -1)
continue;
obj.name = "SomeDate";
}
}, 150)
});
The solution was to use the Telerik object's .InputHtmlAttributes method.
#Html.Telerik().DatePickerFor(m => m.SomeDate).InputHtmlAttributes(new { id = idString + "-SomeDate" })

MVC3 - Model set to null but still entering IF statement

I have a Model (BusinessPlaceDetailsViewModel) which has another Model (Hub) inside it.
However if I set my Hub to null it still enters my IF condition, see here:
I have tried loads of different combinations like putting each IF statement inside its own braces.
Why is it entering the If block?
I'm betting that it is a problem with the controller not passing the model down to the view.
If you post the controller code it might be helpful.
Just out of curiosity, can you try this and see if the h1 displays?
#if (!User.Identity.IsAuthenticated)
{
if (Model.Hub == null)
{
<h1>wtf shouldn't have gotten here</h1>
}
else
{
...
}
}
Could you handle your check in the controller first? If not maybe try .Any() with Ling.
#using System.Linq
#if( !Model.Any() )
{
...
}
else
I solved this problem by using the following in the BusinessPlaceDetailsViewModel
public BusinessPlaceDetailsViewModel()
{
Hub = new HubViewModel();
}

Resources