No overload for method 'Write' takes 0 arguments - asp.net-mvc-3

what's wrong with that code ? I'm getting the error from this topic's title.
#{ var errors = ViewData.ModelState.Values.Where(x=>x.Errors.Count > 0).ToList();}
SOLVED, look # the comments

Inside a using statement or other code block, Razor expects code, not markup.
Therefore, you must put in code directly, not in #{ ... } blocks.
The Razor parser interprets your code as # (printing an empty expression), followed by a normal C# statement block ({ ... }).
You only use #{ ... } blocks to put code where Razor is expecting markup.

Related

Ruby: How to generate lines of code inside a program?

I am developing a parser in Ruby using the parslet library.
The language I am parsing has a lot of keywords that can be merged into a single parsing rule like this:
rule(:keyword) {
str('keyword1') |
str('keyword2') |
str('keyword2') ...
}
Is there a good way to generate this set of lines of code dynamically, by reading a text file with all the keywords?
This would help me keep my parser clean and small, making it easier to add new keywords without modifying the code.
The pseudo-code of what I want to embed inside the rule(:keyword) would be somethings like this:
File.read("keywords.txt").each { |k| write_line " str(\'#{k}\') "}
So far, the workaround I have found is to have a separate ruby program loading the parser code as:
keywords = ["keyword1", "keyword2","keyword3"]
subs = {:keyword_list => keywords .inject("") { |a,k| a << "str('#{k}') | \n"} }
eval( File.read("parser.rb") % subs)
where the parser code has the following lines:
rule(:keywords){
%{keyword_list}
}
Is there a more elegant way to achieve this?
You can try something like this:
rule(:keyword) {
File.readlines("keywords.txt").map { |k| str(k.chomp) }.inject(&:|)
}
In this case, you don't really need to "generate lines of code". As #Uri tried to explain in his answer, there's nothing special about the contents of that rule method; it's just plain Ruby code. Because of this, anything you can do in Ruby you can do inside that rule method as well, including read files, dynamically call methods, and call methods on objects.
Let me break down your existing code, so I can better explain how a dynamic solution to the same problem would work:
rule(:keyword) {
# Stuff here
}
This code right here calls a rule method and passes it :keyword and a block of code. At some point, parslet will call that block and check its return value. Parslet might choose to call the block using instance_exec, which can change the context the block is being executed in to make methods not available outside the block (like str, perhaps) available inside it.
str('keyword1')
Here, inside the context of the rule block, you are calling a method named str with the string "keyword1", and getting the result. Nothing special here, this is just a normal method call.
str('keyword1') | str('keyword2')
Here, the | operator is actually just a method being called on whatever str('keyword1') is returning. This code is equivalent to str('keyword1').send(:'|', str('keyword2')).
str('keyword1') |
str('keyword2') |
str('keyword2')
Same as before, except this time we're calling | on whatever str('keyword1').send(:'|', str('keyword2')) returned. The result of this method call is returned to the rule method when it calls the block.
So now that you know how all this works, you can perform exactly the same operations (calling str with each keyword, and using the | method to "add up" the results) dynamically, based on the contents of a file perhaps:
rule(:keyword) {
File.readlines("keywords.txt").map(&:chomp).map { |k| str(k) }.inject(:|)
}
Breakdown:
rule(:keyword) { # Call the rule method with the `:keyword` argument, and pass
# it this block of code.
File.readlines("keywords.txt"). # Get an array of strings containing all the
# keywords
map(&:chomp). # Remove surrounding whitespace from each keyword in the array,
# by calling `chomp` on them. (The strings returned by
# `File.readlines` include the newline character at the end of
# each string.)
map { |k| str(k) }. # Convert each keyword in the array into whatever is
# returned by calling `str` with that keyword.
inject(:|) # Reduce the returned objects to a single one using the `|`
# method on each object. (Equivalent to obj1 | obj2 | obj3...)
}
And that's it! See? No need to generate any lines of code, just do what the real code is doing, but do it dynamically!

Express JS Jade Engine If statement nested in For loop

I can't seem to find a solution to this.
I'm trying to nest a if statement inside a for loop in Jade engine (using express js).
The base code is shown below:
form
select
for obj, i in phoneModel
option(value='#{i}') #{obj.phone_model}
What I would like to do is to have a IF statement inside the for loop to check to see if a varaible "deviceIndex" is a certain value. Eg. If deviceIndex == i, then do something, else do some other thing.
I have tried the code below:
form
select
for obj, i in phoneModel
- if(phoneIndex == #{i})
option(value='#{i}') #{obj.phone_model}
- else
option(value='#{i}' selected='selected') #{obj.phone_model}
It gives the "expect indent, but got newline" error. I expect it is my placement of the if statement inside the for loop; however, I have tried just about every combination of tabs and spaces as well as putting the "option(val..." line inside a bracket on the same line as the if statement.
What's with the typeof around a boolean? And shouldn't the phone with phoneIndex == i be the one selected? Also, the point of Jade is to have much cleaner code. Tell me if this works:
form
select
for obj, i in phoneModel
option(value=i, selected=phoneIndex==i)= obj.phone_model

Using a Ternary Conditional with in Asp.Net MVC Razor

I am trying to get the following ternary conditional to work in Asp.Net MVC 3 Razor:
Next
All of the examples I am finding of using a ternary conditional in Razor have return values which are strings. But here I would like to use an expression (Model.PageNumber + 1) and return a number. Is this possible?
Drop the # sign before the value:
Next
Let me just add that in general, Razor doesn't need/want the # prefix unless it's absolutely necessary, for example:
<div>
#foreach(var value in Model.Values)
{
if(value.Flag)
{
<div>#value.Text</div>
}
}
<div>
Notice that you don't need a second # sign until you're actually inside the tag, where Razor wouldn't know whether you wanted to display the text "value.Text" or execute it as code. The if statement is assumed to be code. To escape this and write the line "if(value.Flag)" as text you'd need to explicitly say so with the #: prefix.

Why does this code not remove Layout?

I spent some time trying to remove layout (defined in _ViewStart) using:
#Layout = ""
and
#Layout = null
Why does it only work using block?
#{
Layout = "";
}
In my vision, both ways should work.
#Layout is a code nugget.
It prints the value of the Layout property.
The Razor parser stops at the space after the word Layout, so the = null is parsed as literal markup.
You want to execute a statement, not print a value, so you need to use a code block (#{ ... }).
For more information, see my blog post.

Razor does not work easily with strongly typed Html.ActionLink?

Folks,
We are trying to use the strongly typed action link methods that look like this:
Html.ActionLink<HomeController>
in the Razor view engine.
I know we shouldn't use them all the time because it ignores filters, etc., but the fact is we do use them.
If I try to use this directly in Razor like so:
#Html.ActionLink<HomeController>(c => c.Index, "Home")
I get an error of:
CS1502: The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments
If you look at the compiled code, it's because Razor is not parsing that statement as you would expect. The compiled source, from the error that has the line looks like this:
...
Line 101: #line 13 "C:\dev\TheNetwork\POC\Web\Views\Policy\Edit.cshtml"
Line 102: Write(Html.ActionLink);
Line 103:
Line 104:
Line 105: #line default
Line 106: #line hidden
Line 107: WriteLiteral("<PolicySectionController>(c => c.Edit(null), "New\")\r\n\r\n\r\n\r\n");
Much stuff omitted for brevity :) As you can see, it splits it on the "<" I think it's interpreting that as an HTML tag, but I can't be sure.
I found a workaround, but it's ugly. This works:
#{Write(Html.ActionLink<PolicySectionController>(c => c.Edit(null), "New"));}
Does anyone know of a better way to do this?
Yeah, in order to use generic methods you need to escape the expression using parens. Would this work:
#(Html.ActionLink<PolicySectionController>(c => c.Edit(null), "New"))
I think you can also do:
#Html.ActionLink((FooController c) => c.Edit(null), "New")
This Worked for me:
#using MyProjectNamespace.Controllers;
#using Microsoft.Web.Mvc; // MVC Futures
#{
ViewBag.Title = "Index";
}
<h1>Index</h1>
#(Html.ActionLink<FooController>(f => f.Index(), "Go (Strongly Typed)"))
(Both "#using" statements are mandatory, otherwise it did not work)

Resources