Html.ActionLink with non-C# friendly htmlAttribute names - c#

Disqus wants me to add an attribute called data-disqus-identifier to my links, but for obvious reasons, new { #data-disqus-identifier = "article" } gives me a syntax error.
Any idea what to do in these situations?
Thanks,
Rei

You can pass a Dictionary<string, object> with arbitrary string keys.
The syntax will be more verbose: new Dictionary<string, object> { { "data-disqus-identifier", "article" } }.
You may want to create an extension method or a static method on a static class with a short name that takes a smaller parameter set and returns the dictionary.

In MVC 3, if you use underscore _ instead of hyphens - in your property names then MVC will automatically convert them to hyphens in the resulting HTML. So, something like this should work for you:
new { data_disqus_identifier = "article" }

Related

Anonymous object with key name with hyphen C# [duplicate]

Is it possible to create an object with a property name that contains a dash character?
I am creating an anonymous object so that I can serialize it to Json using Json.Net and one of the properties I need contains a '-' dash character.
An example of what I want is:
var document = {
condtions = new {
acl = "public-read",
bucket = "s3-bucketname",
starts-with = "test/path"
}
};
I know I could replace the dash with underscores when creating the object and then replace them in the serialized string afterwards, but wanted to know if there is a way in the language to do this without this workaround.
You can't do this with anonymous objects; field names must be valid identifiers. You could instead use a Dictionary, which Json.Net should serialise just as easily as an anonymous object:
var document = new {
conditions = new Dictionary<string, string>() {
{ "acl", "public-read" },
{ "bucket", "s3-bucketname" },
{ "starts-with", "test/path" }
}
};
Not in c#, no. However most serializers allow you to customise this - often via attributes. IIRC with JSON.NET you want [JsonProperty("starts-with")] to specify the name. However you can't use attributes on anonymous types, so you may need to define a class with the properties (and attributes) the you desire.
Unfortunately, that's not possible, because the language would not be able to differentiate the two following expressions:
condition.starts-with; // Read "starts-with" property.
condition.starts - with; // Read "starts" property and subtract "with" variable.

Add Like restriction to dictionary

I set an nHibernate restriction for a project Id like so:
var attachmentProperties = new System.Collections.Generic.Dictionary<string, object>();
attachmentProperties.Add("Id", this.project.Id);
so it returns anything with that project Id by setting the Restrictions:
NHibernate.Criterion.Restrictions.AllEq(attachmentProperties));
This works. I now want to add another restriction using the equivalent of a SQL Like. I tried:
attachmentProperties.Add(NHibernate.Criterion.Restrictions.Like("Type", "%dog%"));
There is no argument given that corresponds to required formal
parameter value
I want to get anything in which the Type contains "dog" (in addition to the Id matching). How do I do this?
You have two options:
Have all the Dog classes implement a common interface (IDog). Then, the dictionary will be:
new System.Collections.Generic.Dictionary<string, IDog>();
or, you could do this, which might be a little strange, if what's up top isn't available for some reason where you validate the Add method. You'd similarly have to have checks on other methods.
class DogDictionary : Dictionary<string, object>
{
public virtual void Add(KeyValuePair<string, object> item)
{
if (item.Value.GetType().ToString().ToUpper().Contains("DOG"))
throw new ApplicationException("Invalid Data Type for Value. Should Have 'Dog' in the Object Name");
}
}
I'd go with the first option though.
Another way is to create a Restrictions.Conjunction for the Criteria:
Conjunction conjunction = Restrictions.Conjunction();
conjunction.Add(Restrictions.Eq("Id", this.project.Id));
conjunction.Add(Restrictions.Like("Type", "%dog%"));
conjunction.Add(Restrictions.Not(Restrictions.Like("Type", "%cat%")));

How do I pass query string parameters with names containing hyphens?

I need to pass a query string to a redirect. I know you can do this like so:
return RedirectToAction("Index", new { param1 = "hello" });
will go to /Index?param1=hello.
But I need to pass a parameter which has a hyphen in the name. Let's call it "data-param". Since hyphens aren't allowed in C# names, I can't do this in the above way. I know in some places in MVC, underscores are used to handle this, but that doesn't work here either, the underscore is passed to the query string as-is.
So my question is, how do I redirect to /Index?data-param=hello?
If you are trying to build a url, you can always slightly bypass the MVC routing and just pass the complete url in the old-fashioned way.
string dataParam="hello";
int otherParam=5;
return Redirect( String.Format("/Index?data-param={0}&data-param2={1}", dataParam, otherParam) );
If you are going outside of your own MVC application then you may not want RedirectToAction anyway unless you are redirecting to an action.
This works (I am using ASP.NET Core 3.1 and can't speak to earlier versions):
var params = new Dictionary<string, string>()
{
{ "data-param1", "hello" }
{ "data-param1", "2" }
};
return RedirectToAction("Index", params);
You can use Dictionary<string, object>() instead if you want, though you'll give up some control (e.g. false gets translated to "False" in the URL instead of "false"). And you should use nameof() for better maintainability:
var params = new Dictionary<string, object>()
{
{ "data-param1", "hello" }
{ "data-param2", 2 }
};
return RedirectToAction(nameof(Index), params);
Also note that this dictionary technique works with other methods too like RedirectToRoute().

How to specify a property with - in the name

I am using ASP.NET MVC along with JQueryMobile in a web app. I want to generate a link:
Previous
I have a helper extension method that lets me do:
<%= Html.ActionLink<WhateverController>(c => c.Previous(),
"Previous",
new { data-role = "button", data-icon="arrow-l" } ) %>
Except data-role and data-icon are not valid as property names in C#. Using #data-role doesn't work either.
Is there any syntax to work around this? Or am I stuck with creating a more specialized helper that knows the correct attribute names.
You should be able to use IDictionary<string, object> instead of the anonymous object:
Html.ActionLink<WhateverController>(c => c.Previous(),
"Previous",
new Dictionary<string, object>
{
{ "data-role", "button" },
{ "data-icon", "arrow-l"}
})
In addition to svick's response, we made a neat change in ASP.NET MVC 3 where properties that have an underscore in them will automatically have the underscores converted to dashes.
So, if you have code like this:
<%= Html.ActionLink<WhateverController>(c => c.Previous(),
"Previous",
new { data_role = "button", data_icon="arrow-l") %>
It will render the markup with dashes:
Previous
Because that character is also the subtraction/unary minus operator you can't use it in an identifier. I think the custom helper method is probably your best bet.

How to dynamically create routes in a HTML actionlink

I am trying to send the route values to a method but I cant seem to figure this out. Here is my code
<% string s = "cool";
object d = new { s = "1" };
%>
<%= Html.ActionLink("Home", "Index", d, "ql")%>
The following code produces a url like this
http://localhost:49450/?s=1
the url should be like this
http://localhost:49450/?cool=1
What am I missing
because in the context of a 'new { ... }' expression the 's' does not correspond to a variable as it may first appear - it defines the name of a member of an anonymous class that is created.
when you say :
new { S = 123 }
you are actually generating a class, which is anonymous (you never get to see the name of the class). The type of each member of the class is implicitly determined by whatever you're assigning to it. In the above example a class something like this is generated
class AnonymousClass_S483Ks4 {
public int S {get;set;}
}
There are two ways you can do what you want:
1) you would have to say :
new { cool = 123 }
2)
Now I assume though that you want the name to be dynamic so you need to use RouteValueDictionary which allows you to put key value pairs in.
// RouteValueDictionary is IDictionary<string, object>
var dictionary = new RouteValueDictionary();
string s = "cool";
dictionary.Add(s, 123);
htmlHelper.ActionLink("Home", "Index", dictionary);
As you can see, here you can use a variable 's' to represent whatever you want. This should give you the URL you need.

Categories

Resources