Best asp.net-mvc questions in July 2011

Google AdSense JavaScript causing multiple page-loads?

8 votes

Update

Ok - I now know where the multiple page loads are coming from! (However, the mystery is not yet solved).

It seems that immediately after a request is made to a page containing AdSense ads, Google makes a request for exactly the same URL (one or more times)

e.g. this is what the logs look like (note requests from Mediapartners-Google):

2011-07-20 09:50:20 xxx.xxx.xxx.xxx GET /requestedURL/ 80 - xxx.xxx.xxx.xxx Mozilla/5.0+(Browserstring removed) 200 0 0 1140
2011-07-20 09:50:20 xxx.xxx.xxx.xxx GET /requestedURL/ 80 - 66.249.72.52 Mediapartners-Google 200 0 64 218
2011-07-20 09:50:22 xxx.xxx.xxx.xxx GET /requestedURL/ 80 - 66.249.72.52 Mediapartners-Google 200 0 0 171

(I should have paid more attention to the IIS logs, rather than my own application logs - it just didn't occur to me that these multiple, identical, simultaneous request could have been coming from different sources). This also explains why I couldn't find anything strange when analysing the request with WireShark, and why fiddler didn't show anything strange.

So the question for the bounty now becomes:

  • Why is google making these requests so quickly after the page is requested? (I know they need to asses the page for content, but immediately after, and multiple times sees like abuse to me.)
  • What can I do to stop this?

And out of interest:

  • Has anyone else seem something similar in their logs? (or is this something weird with my AdSense account)

Ok, I'll apologise in advance for the length!...

This question is realted to this one, regarding Google Adsense Javascript code causing errors. (of the form Unable to post message to googleads.g.doubleclick.net. Recipient has origin something.com)

I won't duplicate all of the information there, but the conclusion seems to be that the AdSense JS is buggy. (please read the question for background if you have time). I knew about this problem for some time, but decided to live with the JS errors rather than pulling AdSense from the site.

However, Recently I noticed that in my ASP.NET MVC2 application, Controller Actions seemed to be called twice per page request (sometimes even 3 times). Odly, it was only happening on the production server. After some thought I relalised that one difference between the Dev and Production environments was that the AdSense javscript was only active in production.

To test this I removed all adsense code from one of the production pages, and lone behold, the multiple-page-load problem went away!

I thought that perhaps it was the fact that there were general JS errors on the page that was causing the problem, so to test this I introduced some simple errors into my own JS code, however this did not cause the multiple-page-load problem to reappear.

One known situation where pages can be called multiple times per request is when there are image tags with empty src attributes, or external resource references with empty src attributes. Crucially, The most upvoted answer to the AdSense JS Bug question notes that:

"The targetOrigin argument in this call, this.la is set to http://googleads.g.doubleclick.net. However, the new iframe was written with its src set to about:blank."

This seems eerily similar to the empty src issue.... This seems too much of a co-incidence, and currently I'm of the opinion that this is the problem. [EDIT: This was a red herring]

However, I've no idea wehre to go from here. These multiple action calls are causing real problems (I'm having to use code blocking, serialised transactions, and all sorts of nasty hacks to limit adverse effects). Of course, I could be barking up the wrong tree entirely - I'm puzzled that I can't find any other references to this, given the ubiquity of AdSense, and the nature of the problem (but then again the conclusions of the AdSense JS Bug question are also surprising). I would love this to turn out to be a stupid mistake on my part, so I need a sanity check.

I'd like to ask the community:

  • Has anyone else experienced this problem?, or can anyone who is using AdSense replicate and confirm it? [See note below]
  • Assuming the problem is what it seems, what can I do? (other than pulling AdSense of course)
  • If not, then what might be causing this?

To Sumarise: - My actions are being executed 2 (sometimes 3) times per page request.

  • THIS ONLY HAPPENS WHEN GOOGLE ADSENSE ADS ARE PRESENT
  • I removed all AdSense JS and introduced an error into my own JS : Actions are called only once...
  • A similar problem can happen when empty src properties are present on the page
  • An answer to a previous question sumarises that the AdSense JS sets a src="about:blank" on an iFrame
  • I have come to the conclusion that the src="about:blank" from the AdSense code is the most likely source of the problem.
  • If I disable JavaScript on the browser, the problem goes away

Just to document the things I have ruled out:

  • This is happening across browsers: Chrome(12) Firefox(5) and IE(8).
  • I have dissabled all plugins on browsers (YSlow, Firebug etc...)
  • There are no empty src (src=""/src="#") for images, or other external resources in the html in my code
  • There are no empty url references in the css ( url('') )
  • It's unlikely to be server side code/config problem, as it doesn't happen in Dev (and of the few differences between dev and production is the absence of AdSence JS in Dev)

Note: For anyone looking to replicate this, it should be noted that, strangely, when the multiple action calls happen Fiddler shows only one request being sent to the server. I have no idea why this should be the case, but the server logging doesn't lie :) Perhaps someone who has prior experience with this problem when caused by empty src attributes in img tags can say whether they have seen the same behaviour with Fiddler.


Requested extra information

HTML (@Ivan)

Here's how I'm implementing the Adsense (ids removed)

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<div class="ad">
<%if (!HttpContext.Current.IsDebuggingEnabled) { %>
<script type="text/javascript"><!--
google_ad_client = "ca-pub-xxxxxxxxxxxxxxx";
/* xxxxxxxxxxxxxxx */
google_ad_slot = "xxxxxxxxx";
google_ad_width = 728;
google_ad_height = 15;
//-->
</script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>                     
<%} else { %>
<img src="/Content/images/googleAdMock728x15_4_e.gif" width="728" height="15" />
<%} %>
</div>

This is being inserted by a RenderPartial in the View:

<% Html.RenderPartial("AdSense_XXXXXX"); %>

TCP Logging (@Tomas)

So far I have done a wireshark capture:

  1. on client when requesting page on production with problem
  2. on client when requesting page on production without problem (i.e. Adsense Removed)

I can't really see a significant difference between the two (although my network skills are not great). One thing to note is that they both seem to have a TCP retransmittion of the HTTP request immediately after the initial request - I don't know the significance of that. I can confirm though that in case 1 the server logs reported 2 executions, and in case 2 only one execution.

Next I will try TCP logging on the server side in both cases, and post results here.

Given that the behaviour that you are observing appear to be hard to avoid, can we rather focus on workarounds?

Can you differentiate requests based on UserAgent, and thus filter out requests. Could that be a viable approach for you? If so then you could probably base upon this approach: http://blog.flipbit.co.uk/2009/07/writing-iphone-sites-with-aspnet-mvc.html Here they detect iPhones, but the consept is the same for Mediapartners-Google bot.

Adding custom ValueProviderFactories to ASP.NET MVC3?

8 votes

I was looking to try and add a Protobuf ValueProviderFactory to MVC3 so that I could pick out the MIME type and deserialize the raw data into objects for action parameters. I could also use this to change the default Json serializer.

Looking at JsonValueProviderFactory.cs this shouldn't be too difficult, but the factories all appear to be hard-coded.

For Protobuf I may be able to do something with an IValueProvider but I haven't even checked yet what MVC3 does when it recieves an MIME type of application/x-protobuf.

Am I going about this the right way?

UPDATE

I found this blog post that talks about creating an IValueProvider. It then mentions at the bottom that this changed around MCV2. He changed it to a ValueProviderFactory and calls :

ValueProviderFactories.Factories.Add(new HttpCookieValueProviderFactory());

But in MVC3 this property is read only.

It turns out that it is not read only and you can add providers as follows:

ValueProviderFactories.Factories.Add(new MyValueProviderFactory());

I would have know this had I checked myself!

I've done some more searching today, and this blog post seems to suggest that the DependencyResolver will find any classes that inherit ValueProviderFactory. I'm using MEF for dependency resolution so I can just add an Export attribute and it'll get picked up automatically.

I now have a further issue writing a custom ValueProviderFactory for protobuf-net.

OutputCache serving long-stale data

6 votes

I'm flumoxed... re this and this "meta" questions...

A very basic http request:

GET http://stackoverflow.com/feeds/tag?tagnames=c%23&sort=newest HTTP/1.1
Host: stackoverflow.com
Accept-Encoding: gzip,deflate

which hits a route decorated with:

[OutputCache(Duration = 300, VaryByParam = "tagnames;sort",
    VaryByContentEncoding = "gzip;deflate", VaryByCustom = "site")]

is repeatedly and incorrectly serving either a 304 (no change) if you include if-modified-since, or the old data for a 200, i.e.

HTTP/1.1 200 OK
Cache-Control: public, max-age=0
Content-Type: application/atom+xml; charset=utf-8
Content-Encoding: gzip
Expires: Fri, 01 Jul 2011 09:17:08 GMT
Last-Modified: Fri, 01 Jul 2011 09:12:08 GMT
Vary: *
Date: Fri, 01 Jul 2011 09:42:46 GMT
Content-Length: 14714
(payload, when decoded = some long-stale data)

As you can see, it is serving this nearly half an hour past the 5 minute slot; it looks like the internals of OutputCache simply didn't notice the time ;p It will expire eventually (in fact, it has just done so - my Fri, 01 Jul 2011 09:56:20 GMT request finally got fresh data), but not anywhere like punctually.

UPDATE:

I believed that it was working if we took away the accept-encoding header, but no; this fails too - it just fails on a different cycle (which is what we should expect since the keys are different, courtesy of VaryByContentEncoding):

GET http://stackoverflow.com/feeds/tag?tagnames=c%23&sort=newest HTTP/1.1
Host: stackoverflow.com

gives:

HTTP/1.1 200 OK
Cache-Control: public, max-age=0
Content-Type: application/atom+xml; charset=utf-8
Expires: Fri, 01 Jul 2011 10:09:58 GMT
Last-Modified: Fri, 01 Jul 2011 10:04:58 GMT
Vary: *
Date: Fri, 01 Jul 2011 10:17:20 GMT
Content-Length: 66815
(payload = some stale data)

Once again, you'll notice it is being served after Expires.

So: what could be wrong here?

Additional; while we are using a custom option, our GetVaryByCustomString() correctly calls base.GetVaryByCustomString(ctx, custom) for options it doesn't recognise, as per MSDN (indeed this works fine for the second example above).

Is there any chance you're using a custom output cache provider? Hypothetically, if there was a custom provider using say a sliding expiration instead of an absolute one, you'd see symptoms like this.

What is the best way to apply default date formatting to all such fields in an ASP.NET MVC 3 app?

6 votes

My goals are:

  • Display all dates in d MMM yyyy format
    • Default/existing values on first page load
    • Anything entered by the user, then round-tripped via the server
  • Add class="behaviour-date-picker" to the input field so that I can show a jQuery date picker
  • Build on top of the System.ComponentModel.DataAnnotations infrastructure
  • Still show bad data values such as 12 Joone 2010 after a server roundtrip, with the appropriate validation error message

Here's an example model:

public class DebugDatesStub
{
    [DataType(DataType.Date)]
    public DateTimeOffset Date { get; set; }
}

The DisplayFormat attribute doesn't solve my scenario because it doesn't apply to round-tripped values. (User fills in form, submits it, gets the same form back because of some server-side validation issue - date is still shown in the original format they entered instead of being reformatted.)

Render the field on the page with:

@Html.EditorFor(m => m.Date)

Create this code in ~\Views\Shared\EditorTemplates\Date.cshtml:

@using System.Globalization
@model DateTimeOffset?

@{
    var propertyState = ViewData.ModelState[ViewData.ModelMetadata.PropertyName];
    var displayValue =
        propertyState != null && propertyState.Errors.Any() ? propertyState.Value.AttemptedValue :
        ViewData.Model.HasValue ? string.Format("{0:d MMM yyyy}", ViewData.Model.Value) :
        string.Empty;

    ViewData.ModelState.SetModelValue(
        ViewData.ModelMetadata.PropertyName,
        new ValueProviderResult(displayValue, displayValue, CultureInfo.CurrentCulture));
}

@Html.TextBoxFor(m => m, new { @class = "behaviour-date-picker" })

Get msbuild to deploy clean app remotely

5 votes

We are using msbuild to deploy an ASP.NET MVC application to a few different servers. However, msbuild does not appear to delete the remote application folder first (it just seems to update files). Our msbuild command-line looks like this:

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" OurWebProject.csproj /P:BaseIntermediateOutputPath=c:\temp\tempfolder\ /P:Configuration=Release /P:DeployOnBuild=True /P:DeployTarget=MSDeployPublish /P:MsDeployServiceUrl=https://192.168.0.83:8172/MsDeploy.axd /P:AllowUntrustedCertificate=True /P:MSDeployPublishMethod=WMSvc /P:CreatePackageOnPublish=True /P:UserName=ARemoteWebDeployUser /P:Password=SomePassword

Is msbuild really 'smart' enough to sync the files, eliminating the need for a clean deployment each time? If not, is there an easy way to have the files deleted first?

We are using web.config transforms, so the web.config is rebuilt/redeployed every time (a good thing, since we want the app pool to restart on each deploy).

I'm not sure if there are some specific options to msbuild command, but maybe you could add a target to your project? You could create:

<Target Name=CleanServerFolders>
  <Exec Command="psexec \\$(serverIP) -u $(serverUserName) -p $(serverUserPassword) del $(projectFolderOnServer)"
</Target>

If you don't know PsExec, look here: http://technet.microsoft.com/en-us/sysinternals/bb897553 . It's a lightweight tool from Microsoft, probably the best option to run commands on server. And then modify your msbuild command to call this target (but then you need to specify all other default targets in this command):

msbuild.exe /t:Build,CleanServerFolders,Deploy ...etc

Eventually you can add a post build events to your project file(s).

<Project>
  ...
  <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
  <Target Name="AfterBuild"><CallTarget Targets="CleanServerFolders"/></Target>
</Project>

Of course Microsoft.VisualBasic.targets is a file for .vbproj projects. If you're using c#, then try Microsoft.CSharp.targets (better check the name on MSDN)

View Model Patterns and usage in ASP.NET MVC3 (Also, using EF 4.1)

5 votes

I have been searching for an answer to this question for days and it is driving me insane. Currently I am working on a project using ASP.NET MVC 3 and am trying to utilize a ViewModel per controller approach as has been suggested by so many articles and tutorials I have checked out. To better illistrate what I am asking I will outline below:

Lets say I have a pretty simple and straight forward model. Users, Customers, Addresses, Phone Numbers, Orders, Products, Categories, etc... When a user registers for a new account on my site I would like to: 1) create an account for them (this is just an account id, customer type) 2) Add their customer demographic data to Customers 3) Add N-addresses and address types 4) Add N-phone numbers with type as well.

As far as I have got is deciding that I need a RegisterCustomerForRegistrationControllerViewModel. My predicament is what does this model look like? I am trying to be as DRY as possible yet when implementing this pattern I seem to repeat myself at each turn. At what level do I put DataAnnotations for validation? So do I simply new up a new Customer() even if I only want to use one property from the class in a given ViewModel?

I'm not even confident at this point that this is a correct assumption. There seems to be so much opinion on the topic yet so few concrete examples of implementation. I am hoping someone can point me in the right direction and maybe present some code snippets along the way... I hope this is all clear enough and if not please feel free to ask follow up questions.

Again, Thanks in advance!

Repeating simple properties across two distinct layers of an application is not a violation of DRY. Its just good design.

DataAnnotations go on ViewModels.

ViewModel will look something like

public class RegisterCustomerViewModel
{
    [Required]
    public string Name { get; set; }
    public List<AddressViewModels> Addresses { get; set; }
    public List<PhoneNumberViewModel> PhoneNumbers { get; set; |

} 

How to create a editor template for DateTime with 3 fields?

5 votes

I want to create an editor template for DateTime, I need 3 separated fields:

(DropDown) Day    |    (DropDown) Month    |    (DropDown) Year

How and where do I create this file? And what do I need to do to turn these 3 fields into a single DateTime when I post to a controller?

In your Views/Shared/EditorTemplates folder create a partial view called DateTime.ascx.

The code for this EditorTemplate should be something like

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DateTime?>" %>

<%
    string controlId = ViewData.TemplateInfo.HtmlFieldPrefix.Replace('.', '_');
%>

<script type="text/javascript">
$(function () {
    $('#<%: controlId %>_Day, #<%: controlId %>_Month, #<%: controlId %>_Year').live('change', function () { updateHiddenDate('<%: controlId %>'); });
    $('#<%: controlId %>_Day').val('<%: Model.HasValue ? Model.Value.Day.ToString() : "" %>');
    $('#<%: controlId %>_Month').val('<%: Model.HasValue ? Model.Value.Month.ToString() : "" %>');
    $('#<%: controlId %>_Year').val('<%: Model.HasValue ? Model.Value.Year.ToString() : "" %>');
    updateHiddenDate('<%: controlId %>');
});

function updateHiddenDate(hiddenDateId) {
    $('#' + hiddenDateId).val($('#' + hiddenDateId + '_Year').val() + "-" + $('#' + hiddenDateId + '_Month').val() + "-" + $('#' + hiddenDateId + '_Day').val());
}
</script>

<select id="<%: controlId %>_Day">
<%  for (int dayOrdinal = 1; dayOrdinal <= 31; dayOrdinal++)
    {
        Response.Write(string.Format("<option value=\"{0}\">{0}</option>", dayOrdinal));
    }
%>
</select>
<select id="<%: controlId %>_Month">
<%  for (int monthOrdinal = 1; monthOrdinal <= 12; monthOrdinal++)
    {
        Response.Write(string.Format("<option value=\"{0}\">{1}</option>", monthOrdinal, System.Globalization.DateTimeFormatInfo.CurrentInfo.MonthNames[monthOrdinal - 1]));
    }
%>
</select>
<select id="<%: controlId %>_Year">
<%  for (int yearOrdinal = DateTime.Now.Year - 5; yearOrdinal <= DateTime.Now.Year + 5; yearOrdinal++)
    {
        Response.Write(string.Format("<option value=\"{0}\">{0}</option>", yearOrdinal));
    }
%>
</select>

<%: Html.Hidden("", Model.HasValue ? String.Format("{0:yyyy-MM-dd}", Model) : "") %>

That creates an editor template with a hidden field containing an ISO 8601 representation of the date which the MVC ModelBinder can parse.

The jQuery updates the hidden field whenever the dropdowns change. Note the use of the ViewData.TemplateInfo.HtmlFieldPrefix that I use to get the generated id of the hidden field.

Note that this solution drops in easily without faffing about with Custom ModelBinders because we construct a single form value containing the full datetime. However, this does mean that

  1. You rely on the client having javascript enabled, and
  2. You need to include a script reference to the jQuery library in your masterpage (e.g. <script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>)

If that's not acceptable, you will have to look at Custom ModelBinders as @Jon has pointed to.

Can I modify an MVC route outside of Global.asax?

5 votes

Is it possible to modify the the routes (and thus the RouteTable) outside of the global.asax file, maybe in a controller? Is this even advisable?

My reason for asking has to do with IIS 6 and Integrated Mode not allowing for Request context calls. I'm implementing internationalization for a site and keeping track of the culture in the URL. The culture is originally read from a .config file and loaded as a route default. This file read is what ends up throwing the error (another few steps up the stack). I based this off the method described here.

You can access the routing table pretty much anywhere like so System.Web.Routing.RouteTable.Routes, have tested this from a controller and it worked fine.

Conditional compilation turned off warning when mixing razor and javascript

5 votes

The following snippet triggers a "Conditional compilation turned off" warning in one of my views. Do you have an idea on how to fix it?

<script type="text/javascript">
    $(document).ready(function () {
        @RenderSection("JQueryDocumentReady",false)
    });
</script>

I tried to insert a semicolon at the end of the render section statement but it didn't help.

Thank you.

NOTE: Answer accepted because of alternative suggestion to the question, not solution given for the problem in title.

I'm not 100% sure what Conditional Compilation has to do with being in a <script> block, but I did find that wrapping the statements in parenthesis fixed the problem.

@(RenderSection("JQueryDocumentReady"))

I do think this method has a bit of code small though. It's not a problem to just have a script section and assign things to document ready on each page. It really isn't going to save you much work, and it will force you to put javascript on views outside of script tags the way you have chosen to do it.

Where to place AutoMapper.CreateMaps?

5 votes

I'm using automapper in an asp.net mvc application. I was told that I should move the AutoMapper.CreateMap elsewhere as they have alot of overhead. I'm not too sure how to design my application to put these calls in 1 place.

I have a web layer, service layer and a data layer. Each a project of its own. I use ninject to to DI everything. I'll utilize automapper in both web and service layer.

So what are your setup for automapper's createmap? Where do you put it, how do you call it?

You can really put it anywhere as long as your web project references the assembly that it is in. In your situation I would put it in the service layer as that will be accessible by the web layer and the service layer and later if you decide to do a console app or you are doing a unit test project the mapping configuration will be available from those projects as well.

In your Global.asax you will then call the method that sets all of your maps. See below:

File AutoMapperBootStrapper.cs

public static class AutoMapperBootStrapper()
{
     public static void Bootstrap()
     {  
         AutoMapper.CreateMap<Object1, Object2>();
         // So on...


     }
}

Global.asax on application start

just call

AutoMapperBootStrapper.BootStrap();

Now some people will argue against this method violates some SOLID principles, which they have valid arguments. Here they are for the reading.

Configuring Automapper in Bootstrapper violates Open-Closed Principle?

ASP.NET MVC application to learn from.

5 votes

I'm learning web development with ASP.NET MVC framework as I'd like to create os forum engine. Basic stuff and technology can be learnt from books but it would be useful to check real applications. Can you please advise good examples of real ASP.NET MVC solutions with good code and practices, interesting approaches to learn from? I'm particularly interested in

  • ways to create template (themes) functionality
  • providing extensibility with modules, extensions
  • REST API to be able to work with forum from external software.

Thank you for any help and advice!

The basic examples that there're on the net include NerDinner and MvcMusicStore. You can get sources and explanations about them. But they're not enough for building real life projects. They're just good starting points. I would reccomend reading books - Pro asp.net mvc 3 by steven sanderson, subscribe to asp.net mvc blogs(those by Brad Wilson, Scottgu, Steven Sanderson, Scott Hanselman, Phill Haack and others), read about community tools - mvc screencast series by Brandon Satrom. Also, note that module extensibility, templating and REST API layer are far standalone things to learn. ASP.NET mvc integrates greatly with all those jQuery and http libraries that could help you in development. Read about MEF for extensibility. I would reccomend WCF Web API for the REST layer

How to impelment password check delay in an ASP.NET MVC application?

5 votes

I want all the login attempts to my web application to take no less than 1 second, to make brute force attack less feasible. If I just put something like this in my code:

Thread.Sleep(1000)

I expect that I become susceptible to a very simple ddos attack: just launch several dozen login requests to the site, and thread pool starvation will happen. (I don't believe that Thread.Sleep returns thread to the thread pool, does it?)

What is the correct way to implement this feature?

What you could do instead of sleeping the thread (you're right to be concerned about starvation) is to have a sliding window based upon unsuccessful login attempts for a given username. You could store this in the in-memory cache and ignore login attempts for that username if the sliding window has not yet elapsed.

There's a decent blog post on one possible implementation of this here:

Brute Force Protect Your Website

c# mvc area folder structure and class name

3 votes

I have a web project which the folders are constructed within the areas. There, I have two main folders: Admin and Home. In Home section I will put everything concerning the end user whereas the admin will be my back office. Within the Admin folder, I divided Models and Views into sub-folders. Like the following example:

Areas
  - Admin
     - Controllers
        - CategoryController.cs
        - UserController.cs
     - Models 
        - Category
          - Edit.cs
          - Create.cs
          - Index.cs
        - User
          - Edit.cs
          - Create.cs
          - Index.cs
     - Views
        - Category
          - Edit.cshtml
          - Create.cshtml
          - Index.cshtml
        - User
          - Edit.cshtml
          - Create.cshtml
          - Index.cshtml
  - Home 
     ...

I guess it's fine so far. Since I am using Linq to Sql and I have a table named Category within it, the namespace and table name create some problem for me. Say in Category/Edit.cs:

namespace MyProject.Areas.Admin.Models.Category
{
    public class Edit
    {
        public IQuaryable<Category> // this throws an intellisense error since it
                                    // understands "Category" as the folder/namespace
                                    // instead of the table name in linq to sql class

Well, I know that the solution is easy: to change the table name to something else. But for the sake of the readablity of the code, I want to have a clear table name and to have a clear URL I want the folder name remain as category. So please can someone tell me how to differentiate the namespace from the table class?

EDIT

Though I like the answer, I redesigned my folder structure and class names. While I left the L2S class names as they were, I am naming the models as ModelCategory and trying to avoid subfoldering in Models folder with names of L2S classes. Furthermore, I merged Edit.cs - Create.cs - Index.cs in ModelCategory since they, more or less, use the same model. Therefore, I removed the Category sub-folder within the Models and the problem dissappeared.

In addition to Yuck's suggestions, you can also add a using statement with an alias to make the code less verbose, e.g:

using L2S = MyProject.SomeLinqToSqlNamespace;

And you can now refer to the category entity simply as L2S.Category

Controller - ASP.NET MVC - Does more than one instance of a controller get created per App-Domain? If so under what conditions?

3 votes

Does more than one instance of a controller get created per App-Domain? If so under what conditions?

A new instance of a controller is created for each request by MVC, so you may end up with multiple instances running on different threads.

There is nothing stopping you from creating multiple instances yourself.

The controller should be stateless.

asp .net mvc routing url with custom literal

2 votes

Is it possible to make url with custom literal separator that can have default parameters ?

context.MapRoute(
            "Forums_links",
            "Forum/{forumId}-{name}",
            new { area = "Forums", action = "Index", controller = "Forum" },
            new[] { "Jami.Web.Areas.Forums.Controllers" }
        );

I have this as you see im using to dash to separate id from name so I can have url like:

/Forum/1-forum-name

Instead of:

/Forum/1/forum-name

I see the problem is I'm using multiple dashes. And routing engine don't know which one to separate. But overalll it doesn't change my question because I want to use multiple dashes anyway.

Very interesting question.

The only way I could come up with is much like Daniel's, with one extra feature.

context.MapRoute(
    "Forums_links",
    "Forum/{forumIdAndName}",
    new { area = "Forums", action = "Index", controller = "Forum" },
    new { item = @"^\d+-(([a-zA-Z0-9]+)-)*([a-zA-Z0-9]+)$" } //constraint
    new[] { "Jami.Web.Areas.Forums.Controllers" }
);

That way, the only items that will get matched to this route are ones formatted in the pattern of:

[one or more digit]-[zero or more repeating groups of string separated by dashes]-[final string]

From here you would use the method Daniel posted to parse the data you need from the forumIdAndName parameter.

How to pass parameters to a partial view in ASP.NET MVC?

2 votes

Suppose that I have this partial view:

Your name is <strong>@firstName @lastName</strong>

which is accessible through a child only action like:

[ChildActionOnly]
public ActionResult FullName(string firstName, string lastName)
{

}

And I want to use this partial view inside another view with:

@Html.RenderPartial("FullName")

In other words, I want to be able to pass firstName ans lastName from view to partial view. How should I do that?

use this overload (docs):

public static void RenderPartial( this HtmlHelper htmlHelper, string partialViewName, Object model )

so:

@{Html.RenderPartial("FullName", new { firstName = model.FirstName, lastName = model.LastName});}

Where do you put your validation in asp.net mvc 3?

1 votes

One common recommended practice in asp.net mvc is that you should not send your business models to your views.. instead you should create viewmodels specific to each view.

When that is done and you call the ModelState.IsValid method in your controller you are effectively checking the validity of the viewmodel but not the business object.

What is the conventional approach to dealing with this?

public class Person
{
public int ID {get; set;};

[Required]
public string Name {get; set;}

[Required]
public string LastName {get; set;}

public virtual ICollection<Exam> Exams {get; set;}

}

public class PersonFormViewModel
{

public int ID {get; set;};    


[Required]
public string Name {get; set;}

[Required]
public string LastName {get; set;}

}

This is exactly what I have right now but Im not sure if the [Required] attribute should appear on both models or just the ViewModel or just the Business Model.

Any tips on this issue are appreciatedd.

More links to support my claim that it is a common good practice to always use view models.

How to add validation to my POCO(template) classes

http://blogs.msdn.com/b/simonince/archive/2010/01/26/view-models-in-asp-net-mvc.aspx

My preference is to do input validation on the view models, and business validation on the domain models.

In other words, any data annotations such as required fields, length validation, regex, etc should be done on your view models, and added to the model state when error occurs.

And you'll probably have business/domain rules that rely on more than just a "form", so you should do that either in the domain models (execute the validation after they're mapped back), or with a service layer.

All our models have a method called "Validate", which we call in the services prior to persisting. They throw custom exceptions if they fail business validation, which gets caught by the controller and also added to the model state.

May not be everyone's cup of tea, but it's consistent.

Is there a better solution to this C# List<DateTime> sorting?

0 votes

I am writing a class for an ASP.NET MVC menu. I want to be able to take a list of all blog entries and make an Archive menu similar to this:

1/2011 (2)
3/2011 (1)
4/2011 (12)
etc...

Here is the code that I am using:

public class ArchiveMenuModel
{
    private List<ArchiveMenuItem> menuItems;
    public List<ArchiveMenuItem> MenuItems { get { return menuItems; } }

    public ArchiveMenuModel(List<DateTime> dates, string streamUrl)
    {
        menuItems = new List<ArchiveMenuItem>();
        int itemCount = 0;
        dates = dates.OrderByDescending(x => x).ToList();

        for (int i=0; i<dates.Count; i++)
        {
            itemCount++;
            if(i+1 < dates.Count)
            {
                if(!(dates[i].Month == dates[i + 1].Month && dates[i].Year == dates[i + 1].Year))
                {
                    menuItems.Add(new ArchiveMenuItem(streamUrl, dates[i].Month, dates[i].Year, itemCount));
                    itemCount = 0;
                }
            }
            else
            {
                menuItems.Add(new ArchiveMenuItem(streamUrl, dates[i].Month, dates[i].Year, itemCount));
            }
        }

    }
}

Is there a better way, perhaps by using Linq or something? Specifically, the part of my code that i don't like is:

if(!(dates[i].Month == dates[i + 1].Month && dates[i].Year == dates[i + 1].Year))

If I can avoid such an ugly if statement, that would be great!

Thanks for any input.

menuItems = dates
     .GroupBy(x => new DateTime(x.Year, x.Month, 1))
     .Select(x=> new{Date = x.Key, Count = x.Count()})
     .OrderByDescending(x => x.Date)
     .Select(x => new ArchiveMenuItem(streamUrl, 
                                      x.Date.Month, 
                                      x.Date.Year, 
                                      x.Count))
     .ToList();

MVC3 Controller folder won't appear in URL

0 votes

This is just an example which I can't figure out how to get it work.

In my MVC3 Controller folder, if I add a new folder called "Admin" and add a controller "News" with an action "Index", you get a server error when you try to open that url (404):

http://url/Admin/News

Even when you type "/Index" behind it, it won't work. How can you make a hierarchy which will result in similar URL's? Just to be clear, I want to create URL's like:

http://url/folder1/folder2/controller/action

Thanks

You seem to be thinking in the mindset of "physical file paths" still. .NET MVC uses the concept of routing where you define routes that map to controller classes and actions. In plain words, you're not mapping to a file, you're mapping to a class.

If you look in the global.asax file of your web project you will see a method named RegisterRoutes(). This method wires up all of the available routes for your site that will be utilized to find the correct controller/action/param/pattern to execute.

Now, the way I'd recommend solving what you're looking for would be by creating an area. It sounds like you want to have an administrative section to your website so I'd do the following:

Right click on your website project, select "Add", select "Area"

enter image description here

Give your area a name, in this case "Admin" would make sense

You solution explorer will now have added the "area" Admin. Notice how it mimics the structure and layout of the standard project, only in it's own folder.

enter image description here

Add a controller in the newly created administrative area and name it "News" Add your actions

Here's a test result URL doing this:

enter image description here

This solution is for simplicity's sake. If you want to take if further you will have to delve into creating your own routes in the RegisterRoutes() method I spoke of above. Routing is something you should gain a solid grasp of so I recommend doing so.

jQueryUI + ASP .NET MVC autocomplete with json data

0 votes

I have really big problem with calling JSON with jQueryUI autocomplete. I have this fairly simple JS:

$(document).ready(function() {
    $('#Editor_Tags').autocomplete({
        source: "/Forums/Ajax/GetTags",
        focus: function () {
            // prevent value inserted on focus
            return false;
        },
        select: function (event, ui) {
            var terms = split(this.value);
            // remove the current input
            terms.pop();
            // add the selected item
            terms.push(ui.TagName);
            // add placeholder to get the comma-and-space at the end
            terms.push("");
            this.value = terms.join(", ");
            return false;
        }
    });
});

And this is model I'm trying to return:

public class TagView
{
    public int TagId { get; set; }
    public string TagName { get; set; }
    public int Weight { get; set; }
}

But that's not the main issue. Main issue is, When I start typing, jQuery do not make request to controller. I'm 100% sure, that the Url speciefied is good. Because I can manually access to controller by typing /Forums/Ajax/GetTags?term=text And I get results for it. I'm using newset version of jQuery and jQUI directly rom google CDN.

The jQueryUI autocomplete widget expects data in the source parameter to meet the following requirements:

[..] a simple Array of Strings, or it contains Objects for each item in the array, with either a label or value property or both.

So you have two options:

  1. Change the viewmodel you're serializing to JSON to meet those requirements:

    public class TagView
    {
        public string Label { get; set; }
        public string Value { get; set; }
    }
    
  2. Change the autocomplete widget's source parameter to be a function in which you perform the AJAX call yourself and format the data appropriately:

    $("#Editor_Tags").autocomplete({
        source: function (request, response) {
            $.getJSON("/Forums/Ajax/GetTags", { term: request.term }, function (data) {
                response($.map(data, function (el) {
                    return {
                        label: el.TagName,
                        value: el.TagId
                    };
                }));
            });
        },
        /* other autocomplete options */
    });
    

    This is assuming that the data returned from the server is a JSON array of TagView objects.

The second piece of code is untested, but it should at least get you in the right direction.