Where to place the code for best practice? - asp.net-mvc

I have an asp.net mvc application and I have a page for presenting meteo information. It looks like:
Temperature for today is 34-35 degrees
For this
34-35 degrees
, I have a method that assure that the text will be in format
[Number][Dot][Number]
called AssureCorrectDegressFormat().
Now I am asking where is it suited the best. Untill now I was calling it from the view, smth like this:
But as I think the view is intended only to display data , not to call some methods in order to operate with thise literals. I moved my class SafeData to the Core of my application, and I pass to the view the DTO that has already called this method and obtained the right data for displaying. I am interested in your opinions about this, where is the best place to put this class, maybe in Infrastructure layer and where to call it, now I call itr from my services . I forgot to say that I am using a DDD aproach.

Formatting, from my perspective, is a view-related function and so it should be called in the view. As to the code that actually does the formatting, I might create an HtmlHelper extension to handle the formatting. That way I could use it wherever I wanted, but have the code in only one place.
<%= Html.ShowDegrees( DV.TheDegreeString ) %>

Formatting the display of data in the View seems fine to me. You wouldn't think twice about about putting this on your View:
<%= Model.MyDate.ToString("f") %>
would you? The principal is the same.

If it's a very simple formatting or calculation, I just put it in the view. If it's any more complex than that, I will put a method in the ViewModel. If it is complex and can be used many places, I will create an HtmlHelper for it.

Related

MVC - How to create a wrapper for Html.RenderPartial?

I would like to either override or create a custom function to wrap the RenderPartial shared function found in System.Web.Mvc.Html RenderPartialExtensions.
I found an article talking about this idea here:
http://johncoder.com/Post/AdventuresinDebuggingAFriendlierCalltoRenderPartial
<% Html.TryRenderPartial("ClassB", Model.B); %>
In the example above, they have created a custom sub called TryRenderPartial that does some logic and calls RenderPartial if necessary. Unfortunately this article does not give a code example of the TryRenderPartial sub itself.
I can't figure out how to create this function because the RenderPartialExtensions is not inheritable. Also I'm not sure how to actually output the html because RenderPartial is a sub, not a function, so I don't get how to actually "return" the html. Any ideas?
It's literally trivial to wrap RenderPartial. You just create an HtmlHelper extension like so (in C#, I don't speak VB):
public static class MyRenderPartialExtensions
{
public static void MyRenderPartial(this HtmlHelper htmlHelper, string partialViewName)
{
htmlHelper.RenderPartial(partialViewName)
}
}
You would add similar methods for the other overloads you want to implement.
However, chances are, you probably don't really want to do this... most likely, what you want to do is already possible in a way that the framework exposes.
This is what's known as an XY Problem, which basically means that you have Problem X, and you have decided that you need to do Y to solve it. However, you can't figure out how to do solution Y, so you're asking how to do Y rather than asking how to do your original X problem.
The reason why XY problems are bad is because chances are, the solution you've decided you need to do is not the correct solution, and the reason you're having trouble with it is because it's not the right way to do things.
Frankly, I can't think of a good reason to wrap RenderPartial, since anything you'd do is more than likely doable in some other way.
To respond to your other comment, Html helpers don't "return" anything. That's why they're Sub's. How view rendering works is rather complex, and not a subject easily discussed in an SO answer.
HtmlHelpers don't work via inheritance, they use Extension Methods.
http://msdn.microsoft.com/en-us/library/bb384936.aspx

ASP.NET MVC3 first time questions

I am building my first mvc3 app. A few questions I have are:
1) the razor view engine lets me embed code into the views. Is this not what we were once trying to get away? ie keep code out of the aspx.
2) Do models need to implement an interface?
3) Do models need to have methods? Or just properties?
Thanks
Pretty vague question, but I'll give you my 5c worth:
True, but the code we put in the Razor views are usually only to generate Html-controls.. the helper methods in MVC3 utilizes data attributes from your Viewmodels and generates validation etc.
When that is said, it's completely optional how much code you wish to put in your views.
No.
Viewmodels should be as stupid (POCO) as possible, and business logic method should be put on your domain models, as the good DDD developer you are ;)
The code that you put in the view is supposed to be rendering code only. Simple for loops for repetition, calls to EditorFor or DisplayFor or stuff like using (Html.BeginForm()). The main business logic should never be placed in the View layer.
No.
No, just properties. You can add really simple helper methods, but the important stuff is the properties, so even the helper stuff should be implemented as readonly properties.
Actually, the first part is true for the aspx engine and WebForms as well. And Php, and classic ASP, and...
1) It may seem a bit like that, but really it depends what the code is. IMHO You should really avoid any logic or code in the view, other than that directly related to rendering the view. For this code though, Razor gives a lovely clean way of coding in the view.
2) No - any class can be a model.
3) There is nothing to stop you putting methods on the model - but really they should be very simple data tranfer objects - they just "carry" data around. So more often than not, stick to properties.
1) the razor view engine lets me embed code into the views. Is this not what we were once trying to get away? ie keep code out of the aspx.
No, we were once trying to get the logic out of the view. This gives a bit more control over the view, but should not be used as a method of implementing logic.
2) Do models need to implement an interface?
Nope.
3) Do models need to have methods? Or just properties?
Models are just classes. They define the structure of your class.

why is using if-else blocks inside views dreaded? - MVC

What areas get affected by it?
code readability? maintainability? performance? security? any other?
my views have been using something like
if(Model.Showthis) {<div id = "showthis">...</div>} }
and does doing something like the following have security implications? --
<%if (HttpContext.Current.User.Identity.IsAuthenticated && item.Poster.UserName == HttpContext.Current.User.Identity.Name)%>
<%{%>
...
<%}%>
yes I read "if" considered harmful in ASP.NET MVC View (.aspx) files? too, but it didn't exactly specify what areas get affected by it. I mean I wanted to make sure there are no security and performance implications, which the link didn't answer exactly
I think the stigma persists from the transition from ASP to ASP.NET Forms. MVC is a different beast. With MVC3 and Razor it should help break the stigma and allow for more readable, easier to write Views.
That said, Domain and Business logic should never be in your template. But I see no problem, and frequently make use of conditional statements and loops to render UI in my Views.
I don't see an issue with it as long as the branching logic is purely for UI concerns. With that in mind I would change your second if to:
<%if (item.Poster.UserName == Model.CurrentUserName)%>
<%{%>
...
<%}%>
And set your model up so that the CurrentUserName property looks like this:
public string CurrentUserName
{
get
{
return HttpContext.Current.User.Identity.IsAuthenticated
? HttpContext.Current.User.Identity.Name
: String.Empty;
}
}
Or even better if you're going to be checking author against current user a lot in your system, offload that property to a helper class that can be reused from multiple models. Basically I wanted to get the implementation detail of what the current user's name is out of the view.
There's nothing wrong with if else statements in your view template. What you want to avoid is business or model logic in side your view template. If the conditional is directly related to user interface, then it belongs in the view.
Yes, it can be a bit difficult to read because of the mix of HTML and C#, but so long as your view logic is in your view, and your model logic is in your model, you are properly maintaining separation of concerns.
With your second sample; it might make more sense to only have your Poster available to the View if the correct user is logged in in the first place; this seems like more of a Controller thing than a View thing to me.
A lot of people see if statements in the View and cringe, because it reminds them of classic ASP. But the problem with classic ASP was never that there was code and HTML in the same place; it was that there was business logic and presentation logic in the same place.
Edit Also, perhaps duplicate of "if" considered harmful in ASP.NET MVC View (.aspx) files?.
Why are they bad?
As many people have already suggested it's because it can be a warning sign that business logic is leaking into your views which is a bad thing. Or that you are trying to do too much in your view. Often it's easier to setup the necessary data in your controller and just pass everything required (including any computed values) and have your view render it straight out. The flatter and simpler your view model is the better.
I don't think there is anything wrong with using if/else's for the true purpose of conditionally rendering UI. For example, if a user is logged in render this partial if they aren't than render something else.
I think a lot people get taken back and draw a hard and fast 'it's bad practice' because it can easily lead to tag soup. This phenomena has already been highlighted as a carry over from the asp.net webforms engine. Whilst still a good thing to be aware of, it is likely less of an issue with the razor engine as it's much cleaner and requires less syntax to achieve the same thing. The automatic switching in and out of C#/VB code to html and back is very simple with only an # required to re-enter a code block. I don't think this will create tag soup in the same way that angled brackets did <% %>. The amount of noise in the latter was what most people objected to (and rightly so).
Lastly, circumstances depending, if you find you are starting to get a lot of if/else logic in your view sometimes it is cleaner to put that into a HTML helper. I can't find the reference but I remember Rob Connery once saying that if you find yourself starting to write if statements in your view than it's a candidate for a html helper.
Is there performance of security concerns?
I don't think there is going to be any noticable performance differences or security concerns with what you are asking. But considering an authentication check like that is likely to be used in multiple views I would put it into a Html helper.
If-else blocks are not bad specifically. Code in views is bad because you are mixing HTML markup with code. ASP.NET MVC is bad for separating static page design from dynamic UI code. Web Forms is better at separating static and programmatic UI elements.

Rails- Using a set of functions across the view , controller and model

i have a function that converts an array to a hash which i would like to use across all the model, controller and view files in the rails app.
Does this violate some core design principle, or am i missing something really obvious?
UPDATE: This is actually a software engineering question. I want to understand why some "convenient" things are not allowed in rails, and i suspect it is precisely because they do not want us to do it
This is likely actually a bad practice. It'd likely be better to instead always work with arrays and hashes in your controllers and models and if necessary convert them in the view to the alternative.
That is, if the data is natively represented as a array throughout your application work with it that way and if required to be a hash in the view either convert it first and assign it or convert it in the view using a helper.
View global helpers go in: helpers/application_helper.rb
If you must call a helper from a controller you can still define it there and I believe you can do:
def Something
....
hashData = #template.helper(arrayData)
end
Calling helpers in a model is REALLY not a good idea, there's no point.
As a final note, encapsulating this logic in a library would likely be ideal, your controllers can call a library & your view helpers can as well.
I think you are: views should not need that method. The controller ought to do it and pass it along to the view for display. The controller or, better yet, service layer might apply that method to a model object, but there's little reason for a model object to know about it.

When should I use HtmlHelper Extension Methods?

I am increasingly finding situations where my ASP.NET MVC view requires some logic to perform layout. These routines have no place being in either my model or my controller. I have 3 options:
Write lots of <% %> inline in the view.
Write less <% %> in a number of partial views.
Write an HtmlHelper Extension method.
It is the last option that confuses me. Is it OK to do this if the logic is specific to only that one view? The extension would be 'visible' to the Html object of every other view, and it will never be needed.
Any suggestions?
I personally prefer option 3 ("Write an HtmlHelper Extension method") because those bodies of code lend themselves to be easily unit testable.
I really do wish extension methods could be placed on internal or nested classes because you are right, you will begin to pollute your namespaces with tons of extension methods which are only used in one View.
I'd recommend sequestering these HtmlHelper extension methods in static classes in a custom namespace per View that you manually reference in the View so as to limit the number of extension methods available throughout your project.
I would, generally, limit both partial views and extension methods to reusable components, but am not pedantic about it. If you feel that either one improves the readability of your code, then go ahead and use them. You might want to consider a separate namespace/helper class for helper methods that are only used by one set of views -- sort of like segregating your partials per controller.
You might also want to consider using more whitespace (even though it's the silent killer) to improve readability. I've implemented output compression in my base controller to limit the impact of whitespace on download time.
Is it OK to do this if the logic
is specific to only that one view?
Yes. Read on...
The
extension would be 'visible' to the
Html object of every other view, and
it will never be needed.
No true. It depende how you register the extension method for the view. This is only the case if you add the namespace to the web.config namespaces section.
If you want to use the extension method on a single view just import its namespace to the single view:
<%# Import Namespace="NamespaceOf.Your.ExtensionMethods.ForThisViewOnly"%>

Resources