I've been working with a team on a ASP.NET project, a project management tool.
Most of the pages is basically writing stuff from the database to the page and store the changes which where made.
This is our first project in ASP.NET (We currently use ASP Classic for all our other projects), our senior told us not to use MVC.
The problem now is that our Designer/Front-end developer is pretty much clueless if it comes to ASP.NET, he also does not want to use VisualStudio if possible (He uses OSX).
For example:
What would for example be the best way to write a dynamic list?
This is what we currently do:
<div id="tasks" overflow-y="scroll" style="height:400px;">
<ul id='taskList'>
<% PrintTasks(); %>
</ul>
</div>
In the code-behind:
public void PrintTasks()
{
foreach (var task in _tasks)
{
Response.Write("<li rel='#' id='task_"+task.TaskID+"'>" +
...
"</span>" +
"</li>");
}
}
In this case, its not possible for the designer to edit the li tags without going into the code behind.
Thanks.
I'm afraid your front-end developer will have to suck it up and learn how to use VS. If your entire team is working on ASP.Net, there is no way to escape the wrath of VS.
MVC is a good for separation of C# and HTML. Razor engine allows a nice way to separate code and markup.
For you list you would probably do something like that in Razor:
#foreach (var item in items)
{
<li rel="#" id ="blah_#item.id">#item.text</li>
}
You should absolutely raise the question why MVC is not an option. It would be a much better fit for what you're doing, and the code quality would therefore also be much better, which helps the project overall. Not to speak of team productivity (and the ability for your designer to "escape" VS).
Doing some CSHTML with Razor you and your team would almost feel "at home".
According to your context, the main friction point is your front end developper.
So, decide on using a javascript framework (Knockout.js, angular.js, whatever).
Let your front-end developer design the UI that will get all needed info from JSON provided by your web stack of choice (ASP.NET MVC, Web Api, whatever).
This will ensure that he can develop his UI with the tool he wants. And you can work on the backend without worrying about UI. You just need to agree on the JSON contracts and stick to them.
This way, you will keep a clean separation of concerns with :
- everyone developping with the tools they're most at ease with
- no layer mix and match (ie having some HTML "generated" in your code behind)
And, your list will look like (using knockout) (syntax may not be accurate):
<ul data-bind="foreach: myList">
<li><span data-bind="text: Text, attr: { id: Id }" /></li>
</ul>
Code behind (using asp.net mvc) (syntax may not be accurate)
public JsonResult GetList()
{
var res = myServiceLayer
.GetListItems()
.Select(
x => new { Text = x.Val, Id = x.Id }
);
return JsonResult( res );
}
When using ASP.NET WebForms, I would give you the following suggestions:
Take advantage of CSS. Accept that your designer will not be able to edit the HTML produced by your code-behind, but if you use CSS intelligently you can probably overcome that challenge. In your example, you have a div and a ul element with id's, and the designer can then change the CSS to style these elements and child elements using the cascading properties of CSS. (Ex: #taskList > li)
Consider client side templating when appropriate. When presenting data for the user, fx. lists, consider using a templating framework. (jQuery fx) These templates can be placed in separate files that your designer can edit without VS. (Reference: load jQuery-Templates from external file?)
Spend some time learning the different controls available in ASP.NET WebForms, instead of using Response.Write to build HTML. Using Response.Write in the code-behind is generally a really bad practice and should be avoided, because your code will quickly turn into spaghetti and be unmaintainable. And if you're hoping to use ASP.NET WebForms (Or MVC) on later projects and want your senior and management to see the advantages of ASP.NET, then you and your team should spend a little time learning the framework. When you do that, you will be rewarded with more structured code that is easier to maintain. But if you use your current Classic ASP practices in ASP.NET, chances are that neither your senior or your management will see the benefits of using ASP.NET. And that would be a shame, because the benefits are really there. :-)
Good luck!
In the specific case you mentionned, in 'classical' asp.net, you're supposed to use a repeater: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater(v=vs.80).aspx
<asp:Repeater id="Repeater1" runat="server">
<ItemTemplate>
<li rel='#' id='task_<%# DataBinder.Eval(Container.DataItem, "TaskID") %>'>
<span>Whatever</span>
</li>
</ItemTemplate>
</asp:Repeater>
Basically, learn which webcontrols are available, create new ones every time it's necessary, and try to get as much as you can from asp.net webform's limited binding/templating system.
use Repeater here:
<asp:Repeater runat="server" ID="r1">
<ItemTemplate>
<li rel='#' id='<%# Eval("id","prefix{0}") %>'><span>
<asp:Label runat="server" ID="t1"><%# Eval("Caption") %></asp:Label>
</span></li>
</ItemTemplate>
</asp:Repeater>
and in cs file:
r1.DataSource=list;
r1.DataBind();
Related
I am coming from PHP so bear with me with my noobness...
I want to know a few things.
I know PHP, javascript and MySQL very very well now and I understand that browsers understand a few things.. html and javascript.
I ran through a tutorial of c#.net and found that it had pre-made "user controls" and i thought, oh my it's completely different from PHP... Then i realised that in the end it ends up with a bunch of javascript I could have written myself (not saying i want to ;), just saying).
My questions....
1.
If I have a table with some input fields:
<form id="form1" runat="server" method = "post" action = "validate_entry.aspx">
<table>
<tr>
<td>Name: </td><td><input type = "text" name = "name" /></td>
</tr>
<tr>
<td colspan = "2"><input type = "submit" value = "submit" /></td>
</tr>
</table>
</form>
and use the post and action methods, and then in validate_entry.aspx on Page_Load class I call something like:
c.Request["name"];
and do whatever with it.. Is this still a professional way of using c# or am i wanting it to be too much like PHP. Am i missing out on some execute speed or something even though it's running javascript.
2.
If I wanted to simply output the word "arse" in a div... If I do something like this, am I defeating the object of c#.net
<div id = "the_butt_holder">
<% Response.Write("arse"); %>
</div>
or a better example is that in my validate_entry.aspx page I do:
<div id = "the_response">
<% Response.Write(c.Request["name"]); %>
</div>
I think in your case, you would benefit greatly from looking at ASP MVC. It gets much closer to the grain and will probably be much closer to what you're used to working with as you have a great deal of control over the html.
Well James, I think you could start using asp.net mvc. It will be so easier to you than asp.net webforms. WebForms is based on Server Controls and Events, you cannot set a page in tag, instad of it you can create a , double click in it and write your code on .cs file respective of your webform, then, the .net framework will do a thing called PostBack and executes this event. There's a desnecessary long life cycle when a PostBack runs.
In Asp.Net webForms you don't have control of your output HTML code. The SErver Controls will do it for you, and sometimes it is not you want (or need).
With ASP.NET MVC you have a Route Tables and you have a MVC Architecture Pattern, so, if you use a mvc framework in PHP, it would be easy for you. With ASp.NET MVC you have control of your HTML, and you can create Typed Views. Check this link: http://www.asp.net/mvc
I hope it helps you.
Your way is by no means wrong, however there is another way in ASP.NET, which is to use actual TextBox (which renders input field) control instead of input field directly. That way, you will be able to access value as a property of the control.
<asp:TextBox id="tb1" runat="server" />
var text = tb1.Text;
Why not just write literal directly instead of outputting it like this?
<div id = "the_butt_holder">
arse
</div>
You may feel much more at home using ASP.NET MVC, and Razor layout engine. It's much more like PHP and Smarty (or whatever similar templating engine replaced it nowdays :) )
You can find more than enough tutorials right there on the site to get you started.
I'm using Sitecore and just getting the hang of working within ASP.NET. We don't have a second Sitecore license for a development server, so I have to do everything live fire on the site (ack!), so I am trying to avoid working with code behinds due to the necessity of a recompile/DLL insert.
I'm just trying to hide a section header if the following section is empty. I've come up with this, which definitely works, but it seems pretty bulky:
<% if (!string.IsNullOrEmpty(Sitecore.Context.Item.Fields["Grades"].ToString())) { %><h2 class="edu">Timeframe</h2><% } %>
<sc:FieldRenderer runat="server" ID="mhTimeFrame" Fieldname="Timeframe" />
Is there a more straightforward way to do this?
By the way: I'm aware that Sitecore can utilize XSLT templates but our site was built without utilizing XSLT so I'd like to stick to one paradigm so that a future developer can make sense of this.
Just to state the obvious, you need to get a proper development process in place or you will get yourself into trouble! If you haven't already, talk to Sitecore and figure out what you need in terms of licenses to get a proper development environment up and running. You may be entitled to a development instance if you are a certified developer.
Now, to your question, you have to put the logic somewhere. If you are unable to modify the codebehind, compile and deploy then you need to put it on the .ascx. You can trim it up a bit I suppose...
<% if (Sitecore.Context.Item["Grades"] != "") { %><h2 class="edu">Timeframe</h2><% } %>
<sc:FieldRenderer runat="server" ID="mhTimeFrame" Fieldname="Timeframe" />
In order to get rid of the if-statement in your markup, you can set the visible attribute of your <h2 /> element:
<h2 class="edu" runat="server" Visible='<%# Sitecore.Context.Item.Fields["Grades"] != null %>'>
Timeframe
</h2>
To get this up and running, you need to trigger the DataBinding at least one time:
protected void Page_Load(object sender, EventArgs e)
{
Page.DataBind();
}
Nevertheless you NEED a development environment ;)
I'm creating a little view framework. I'm not trying to stick to strict MVC adherence, but I am definitely trying to not get in the way of MVC practices.
Anyway, one of my questions is this: Is it bad for a view to create it's own child views?
For instance, in pseudo-ish C# code:
/*BlogEntryView*/
<h1>my blog entry...</h1>
<div class="Comments">
{# //code
foreach(var comment in Comments){
Write(new CommentView(comment));
}
#}
</div>
Is this bad practice for an MVC style? Would the proper thing to do be to provide a "placeholder" in BlogEntryView where the model populates it with CommentViews?
(also, please do not tag asp.net-mvc, this is similar, but in no way uses ASP.Net MVC technologies)
For comparison, the opposite of this, would be adding views with some placeholder in the model code:
/*BlogEntryView*/
<h1>my blog entry...</h1>
<div class="Comments">
{# SomePlaceholder #}
</div>
/*In the model code for BlogEntry*/
//v is a BlogEntryView
foreach(var comment in Comments){
v.PlaceHolder.Add(new CommentView(comment));
}
Both ASP.NET MVC and Ruby on Rails facilitate the approach I think your referring to through the use of partial views.
Using your example would typically result in a view that called a partial for comment record. In ASP.NET MVC C# this would look like the following: -
<h1>my blog entry...</h1>
<div class="Comments">
<% foreach (var comment in Model.Comments) { %>
<% Html.RenderPartial("Comment", comment); %>
<% } %>
</div>
Following current MVC philosophies and design principals this sort of decomposition into small "atomic" portions of view code is actively encouraged in many circles. However, there is always a balance to be sought between this decomposition and the maintainability.
No. This is actually how the ASP.NET MVC Templates features work in MVC. However, a potential pitfall in ASP.NET MVC is a slight performance cost to searching the file structure for the views. This can be avoided by specifying the full view path explicitly.
http://vishalswami.blogspot.com/2007/11/design-patterns-in-mvc_30.html discusses MVC architecture. The Gang of Four also advises that one of MVC's greatest advantages is that it facilitates a Composite UI (which is what you are describing).
In traditional MVC, there's one view to each controller and model, which is call the "MVC Triad". I think what you what is the view's template to be able to embed other templates for re-usability (think partials).
One piece of tech that gets this correct with mustache. It uses a view model, coupled with a template. The template can request other partials to reuse chunks of other templates.
The problem with many web MVC frameworks is that they treat the view as a template, which is the wrong way to view it (no pun intended). Once you have a class representing the view, this all becomes much easier.
Personally, I think the specific example you posted is bad form, because a template should never have that sort of access to objects and instantiating them like that. Templates should get their data from outside sources (the view model), which cane make those instantiations cleaner.
Is it bad for a view to create it's own child views? My answer is "NO". In face creating partial views gives you more power to change the UI contents in a modular way.
There are always multiple ways of achieving results. I personally think ascx files are a good clean way of creating reusable modules which can inherit from customized user controls. Its modularized approach keeps things very organized for me.
Just my 2 cents...
I understand that there are communities both pro and against views rendering child views.
Personally I consider the use of RenderPartial to still be a view concern. I don't have an issue with view depending on another view, providing it assumes the same model offered by the controller action's model.
RenderAction on the other hand is less of a view concern because it winds up invoking a controller action, which then renders a view. It's an entire request lifecycle unto itself. However, it has a lot of benefits, particularly for cross-cutting concerns such as site navigation, user account state, ads, or other page features that are completely independent of the page's primary goal.
I have a web application I'm working on, and I'd like to avoid the clutter of if/elseif/else in the view, and of having way too many separate ascx files just for conditional inclusion in a view.
What I want to do is create some sort of simple class that works like so (an example will demonstrate what I'd like to achieve)
<% using(RequiresAccessTo.Feature(Features.FancyStuff)) { %>
Special content for users
<% } %>
If the user does not have access to the feature, the class would render a sign up link instead. I know I could simply use if/else, but the content of the else block could be one of 2-3 different standard responses depending on access level, and this mechanism would be used in countless places around the website.
If there a way to simply prevent Special content for users from rendering altogether, it'll mean I can make the templates around the website really easy to maintain.
Another option you might try would be to create a custom server control. Properties on the control could include the feature set you'd want to check permission for. If that permission wasn't met, the control would render the sign up link appropriate for that access level or permission. Your view would end up looking something like:
<controls:SignUpWrapper runat="server" id="signup" access="FancyStuff">
<div>
Approved user contents.
</div>
</controls:SignUpWrapper>
In your control, you would first check permission then render either the appropriate link or the provided HTML. The trickiest bit here might be getting the routing information to your server control code. Not something I've tried. Worst case scenario I imagine you should be able to pass the necessary information or even the entire sign up link through properties. No wait, worse would be bypassing routing altogether and forcing the URL in through a configuration value, erm... yeah. Either way it's a bit wordier than your desired example, but not far off.
I suppose some folk might see even the server control idea as a bit wonky. But as long as you stay away from view state, post back behavior and maybe a few other classic ASP.NET features, there's nothing preventing using server controls. We all use masters and content containers already. Sorry to preach if you're already in the choir. =)
For the time being, this is stretching my imagination and maybe even common sense a bit depending on the difficulty of generating that link. I'll check back if I think of anything else.
I can think of one other decent option to keeping your if/else logic in a partial view.
You could create an HtmlHelper extension method. HtmlHelper is the object used when calling things like Html.ActionLink in a view. You can write your own method that produces whatever HTML you want. The conditionals all take place in the extension method and your view code is reduced to:
<%= Html.MyControl(param1, param2) %>
The rule of thumb I follow when deciding when to create an HtmlHelper extension method and when to create a partial view is generally how much HTML is going to be generated. If I end up with more than a few lines of rendered HTML, a partial control is generally your best bet as it is generally easier to understand and maintain the HTML.
If you're worried about organizing numerous partial views, you can create subfolders under your Shared view directory. The views can then be referenced like this:
<% Html.RenderPartial("Subfolder/PartialView") %>
I just thought of an alternative solution:
<% if(!BlockContentAndRenderPlaceHolder(Feature.Whatever)) { %>
whatever
<% } %>
I know it looks a bit obtuse, but if you saw the content on these pages, you'd understand.
I am looking into binding some data. What method of output would be better. I usually use Gridviews, but I am unsure if the table would be better now.
You should really steer clear of ASP.NET Web Forms controls when using the MVC framework. They don't play nicely together 100% of the time.
The HTML helpers/ standard HTML elements are the replacement. The idea being that you have more control over what you're doing that with Web Forms.
There are some nice grids available:
jqGrid (example of use with MVC here)
And the awesome MVCContrib project.
If all you're looking to do is present(output) a table of data, no need for a gridview at all (besides, in MVC, you most likely wouldn't want to anyway).
Simply loop through your model collection and create a new table row for each item:
<table>
<% foreach (var item in Model) { %>
<tr><td>FieldName</td><td><%= Html.Encode(item.Field) %></tr>
<% } %>
</table>
you can format up your table however you like by applying the appropriate css class to it.
EDIT: a better example to show multiple fields, also showing how to display no data.
<% if (Model.Count() > 0)
{ %>
<table width="35%">
<thead><tr><th>Species</th><th>Length</th></tr></thead>
<% foreach (var item in Model)
{ %>
<tr>
<td><%= item.FishSpecies%></td>
<td align="center"><%=item.Length%></td>
</tr>
<% } %>
</table>
<% }
else
{ %>
No fish collected.
<%} %>
That really depends on what you are outputting.
I only use tables / gridview for tabular data.
For other stuff i use Repeater controller or FormView.
While you can partially use ASP.NET server controls in MVC applications (e.g. a menu will render quite well), you should expect that they won't expose the expected or rich behavior you are used to see in ASP.NET. There's a number of reasons for that:
They typically rely on ViewState (and ControllerState)
You are required to put them inside a form tag with runat="server". Most controls check that this is the case indeed
Related to this, they rely heavily on the postback paradigm, which is not used in ASP.NET MVC
As a typical example of behavior that you won't find back, there is paging and sorting ...
When you delve into it, you soon find out that the helpers available in the MVC framework allow you to generate tabular data quite efficiently ....