Best asp.net-mvc questions in March 2011

How to use ASP.NET MVC 3 and Stackoverflow's Markdown.

11 votes

I've been researching for a few hours now and couldn't find any real sources for this. I'm building a site in ASP.NET MVC 3 and would like to take advantage of the Markdown editor that StackOverflow uses. Does anybody have a good tutorial?

Where do you download the latest markdown? What language is it written in? Where would I start in integrating this into an MVC 3 project? Even after all the searching and reading I've done I'm still pretty confused.

I came across one site. http://daringfireball.net/projects/markdown/ But this seems outlandishly old and it would seem I would have to learn a little something about CGI and PERL which I have absolutely no experience with. A javascript/jQuery version would be splendid. Any ideas, links, references are much much much appreciated.

UPDATE

I noticed this question is getting a fair amount of views so I decided to update it with some helpful references. I managed to get a Markdown editor working nicely on CodeTunnel.com and I wrote a few blogs about it. Hopefully they help anyone who comes across this question.

Stackoverflow open sourced their version of Markdown to the world. Its called MarkdownSharp and is written in C#.

Somebody wrote a HtmlHelper here: http://blog.dantup.com/2011/03/an-asp-net-mvc-htmlhelper-extension-method-for-markdown-using-markdownsharp

If you are looking for how to implement a javascript editor there is an existing question: Integrate Markitup text editor to ASP.NET MVC project

How to remove HTML tags from user content?

11 votes

NOTE: I asked this question already and it migrated to meta. This is not a specific question about stack overflow so much as it's a question about a behavior I would like to include in my own project. i.e. This IS a programming question. It just so happens that SO performs the exact function I'm looking for. This question is not about Stack Overflow, it is about a programming behavior and I would like programming references. Thank you :)


Alright, let's try this again.

I thought the above note was enough, but apparently not so here is a tl;dr:

How do you remove tags from user-submitted content? A site that just so happens to contain this behavior is a very obscure site you may not have heard of called "Stack Overflow". Below is a description of the desired behavior as well as samples of the end results.


I am curious how SO goes about removing HTML tags from posts. I just started using their MarkdownSharp project. By default MarkdownSharp encodes any HTML within code blocks like this:

<span style="color: red;">I am HTML</span>

But if I do the same thing outside of a code block it simply doesn't show up at all:

I am HTML <- tags are removed.

But they have whitelisted certain tags for basic markup, like the header tags:

<h1>test</h1>

test

I can also type HTML entities like &gt; doesn't get re-encoded, it will actually show up as a >

I'm sure the tags that get removed are being removed BEFORE the content is passed to markdown, as markdown generated HTML tags would likely be removed if this tag removal code was run after markdown handled it.

Does anyone know how SO accomplishes this, and if it is code that is available to use? Alternatives are acceptable also. I'm hoping to find something in C# as my project is C# ASP.NET MVC 3.

Thanks in advance!

As I said on Meta: Stack Overflow uses the HtmlSanatizer written by Jeff Atwood.

Real-time ASP.NET MVC Web Application

9 votes

Hi,

I need to add a "real-time" element to my web application. Basically, I need to detect "changes" which are stored in a SQL Server table, and update various parts of the UI when a change has occured.

I'm currently doing this by polling. I send an ajax request to the server every 3 seconds asking for any new changes - these are then returned and processed. It works, but I don't like it - it means that for each browser I'll be issuing these requests frequently, and the server will always be busy processing them. In short, it doesn't scale well.

Is there any clever alternative that avoids polling overhead?

Check out WebSync, a comet server designed for ASP.NET/IIS.

In particular, what I would do is use the SQL Dependency class, and when you detect a change, use RequestHandler.Publish("/channel", data); to send out the info to the appropriate listening clients.

Should work pretty nicely.

What is the difference between <%: item["Title"] %> and <%= item["Title"] %>

7 votes

Possible Duplicate:
Are <%: and <%= the same thing as embbed code (expression) blocks

I am developing an ASP.NET MVC 2 application using .NET 4.0. Just wanted to know, what is the difference between

 <%: item["Title"] %>

and

 <%= item["Title"] %>

?

The first will automatically HTML Encode the value. The second won't.

<%: item["Title"] %>

is equivalent to

<%= Html.Encode(item["Title"]) %>  

MVC 3 Dependency Resolver or Ninject MVC plugin?

6 votes

In MVC 3 they added a Dependency Resolver what I been using. While answering someone question someone commented on you should use the Ninject MVC 3 plugin.

So my question is why use it over the built in one? If it is the way to go how do you setup it up?

Question

So above is the link to the question that I answered.

The Ninject.Web.MVC extension (or Ninject.MVC3 NuGet package) use a dependency resolver internally too. So basically it is using the same mechanism. But there are several reasons to use the extension rather than implementing an own dependency resolver:

  1. Why implementing an own dependency resolver when there's already an extension doing exactly the same? Using the same implementation than others makes it much easier to support you when you have a problem. Furthermore the more using the same implementation the more stable it gets. (See point 4).
  2. The extension is more than just a dependency resolver. See http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/ for a list of all features that come with the extension.
  3. It adds support for fast deactivation of objects InRequestScope after the request ends by default. This prevents that applications with a heavy load run into an OutOfMemory exception.
  4. The dependency resolver in your post and the one above both have a problem. In some situations under heavy load your application will crash and only display yellow pages of death until the application is restarted. I don't like to answers all the question that will come in future only because a faulty dependency resolver is used. Add at least a .ToList() to the GetServices
  5. Support for InRequestScope will be removed in Ninject 2.4 to remove the dependency to System.Web to reduce the number of build targets. This is a breaking change. But projects based on one of the Web extensions will only need a very minimalistic change to get it running again. InRequestScope will still be available to projects using one of these extensions. Custom implementations will have to add support themselves.

CTP5 EF Code First Question

6 votes

You can find the source code demonstrating this issue @ http://code.google.com/p/contactsctp5/

I have three model objects. Contact,ContactInfo,ContactInfoType. Where a contact has many contactinfo's and each contactinfo is a contactinfotype. Fairly simple I guess. The problem I'm running into is when I go to edit the contact object. I pulled it from my contact repository. Then I run "UpdateModel(contact);" and it updates the object with all the values from my form. (monitoring with debug) When I save the changes though, I get the following error:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

It seems like after I call update model it nulls out my references and this seems to break everything? Any thoughts on how to remedy would be greatly appreciated. Thanks.

Here are my models:

public partial class Contact {
    public Contact() {
      this.ContactInformation = new HashSet<ContactInformation>();
    }

    public int ContactId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual ICollection<ContactInformation> ContactInformation { get; set; }
 }

 public partial class ContactInformation {
    public int ContactInformationId { get; set; }
    public int ContactId { get; set; }
    public int ContactInfoTypeId { get; set; }
    public string Information { get; set; }

    public virtual Contact Contact { get; set; }
    public virtual ContactInfoType ContactInfoType { get; set; }
  }

  public partial class ContactInfoType {
    public ContactInfoType() {
      this.ContactInformation = new HashSet<ContactInformation>();
    }

    public int ContactInfoTypeId { get; set; }
    public string Type { get; set; }

    public virtual ICollection<ContactInformation> ContactInformation { get; set; }
  }

My Controller Action:

[AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(Contact person) {
      if (this.ModelState.IsValid) {
        var contact = this.contactRepository.GetById(person.ContactId);
        UpdateModel(contact);
        this.contactRepository.Save();
        TempData["message"] = "Contact Saved.";
        return PartialView("Details", contact);
      } else {
        return PartialView(person);
      }
    }

Context Code:

protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) {
      modelBuilder.Entity<Contact>()
        .HasMany(c => c.ContactInformation)
        .WithRequired()
        .HasForeignKey(c => c.ContactId);

      modelBuilder.Entity<ContactInfoType>()
        .HasMany(c => c.ContactInformation)
        .WithRequired()
        .HasForeignKey(c => c.ContactInfoTypeId);
    }

I figured this question out thanks to Morteza Manavi on the entity framework website. My issue was caused by my ContactInformation model properties, 'contactid' & 'contacttypeid' not being nullable. Once I fixed this everything with UpdateModel() worked correctly. Thank you very much!

Naming convention to differentiate partial views from normal views

6 votes

Is there any unofficial standard naming convention for partial views? I've seen someone suggested prefixing with "_", others postfixing with "Partial", I know the question is subjective, but since there is no official guideline, I'd like to know what the majority here uses for naming their partial views. Perhaps the most voted answer WILL become the standard.

Update: I'm using ASP.NET MVC 3 with Razor as the view engine, in previous versions you didn't need a convention because you had the .ascx extension

If you look at WebMatrix, the convention is to prefix Razor files that are not meant to be served directly with a leading underscore. That includes partials and layout pages. Then if you look at MvcScaffolding, you can see that the default templates generate files using the same naming convention.

Read this for an explanation as to why that convention might be used.

What is to prevent me from using IIS Express exclusively on my development box?

5 votes

I have only read a bit about IIS Express, and am in the process of downloading and installing it now. It seems like i should be able to uninstall IIS proper and just make use of IIS Express when developing/debugging webserver-based technologies in visual studio (2010 SP1).

  1. Is this a sane conclusion?
  2. What development scenarios might not play well with IIS Express?
  3. Are there cases wherein IIS proper would absolutely still be needed?

My use of IIS in the past has been for ASP.NET MVC cases, a few web service debugging sessions, etc. Obviously IIS proper is still needed for actually hosting the resulting solutions, but can i realistically "free up resources" and just use IIS Express on demand?

To my knowledge some known issues with IIS Express:

  1. Only http/https protocols are supported

  2. There is limited UI support (through Visual Studio and WebMatrix) to configure IIS Express. But you can configure it manually by editing applicationhost.config.

  3. IIS Express runs as current logged on user, so you may run into issues like http://forums.iis.net/t/1175734.aspx

  4. It will be slow because by default failed request tracing and console tracing are enabled (failed request tracing can be disabled by editing applicationhost.config file)

  5. Kernel mode caching is not supported

Define Scaffolding. (with respect to Dynamic Data and ASP.NET MVC)

5 votes

There is a lot of information about how to implement and customize scaffolding with Dynamic Data and ASP.NET MVC. What exactly is the definition of scaffolding when used in this context?

It means that the Dynamic Data framework will auto-generate a set of routes based on the table names in a data model (e.g. a Linq to SQL data context), and a predefined set of operations (essentially CRUD). When you e.g. visit http://example.com/Products/Details.aspx, where "Products" is the name of a table in your data model, the framework will auto-generate a details page for displaying product details. The generated pages can be customized by providing partial views named according to a convention based on the naming of e.g. columns in the data model.

WatiN best practices/rules of thumb for an ASP.NET MVC app

5 votes

Hi everyone,

I'm an avid TDD and BDD fan but haven't done much in the ways of UI testing. I have an ASP.NET MVC 3 application with many MSpec tests and I'd like to add presentation tests using WatiN.

What sort of stuff do you test? Do I have to write tests for the initial load of the UI or only for things that changed due to user interaction?

What are, in short, good rules of thumb and best practices when writing WatiN (and UI tests in general) tests?

Where I work now, we test these 5 things (where applicable) for each page:

  1. Layout - should have textbox labeled X, should have dropdown labeled X
  2. Populate - should have dropdown with the following values ... should have textbox with the value
  3. Validate - when I enter X, then I should see the error message Y
  4. Navigate - when I click X button, then I should go to Y page
  5. Save - when I click save button, then I should see the Success message

Handling required fields in ASP.NET MVC when using Entity Framework

5 votes

Ok, this problem is really getting under my skin. Let me start out by describing my app in a step by step format.

First I have my Entity Framework generated model. Within it I have the following entities:

Now, to implement validation on an entity, I use partial classes and handle the OnChanging hooks that EF provides. Here is a sample of the PostComment partial class:

namespace CodeTunnel.Domain.Models
{
    public partial class PostComment : IDataErrorInfo
    {
        private Dictionary<string, string> _errors = new Dictionary<string, string>();

        partial void OnAuthorChanging(string value)
        {
            //Validating anything but required value works fine.
            //Like this pseudo-validator.
            if (value.ToLower() != "fred")
                _errors.Add("Author", "Sorry, your name must be Fred.");
        }

        partial void OnBodyChanging(string value)
        {
            //Required value validation does not work, I will tell you why below.
            if (string.IsNullOrEmpty(value))
                _errors.Add("Body", "Body is required.");
        }

        #region -= IDataErrorInfo methods =-

        public string Error
        {
            get { return string.Empty; }
        }

        public string this[string columnName]
        {
            get
            {
                if (_errors.ContainsKey(columnName))
                    return _errors[columnName];
                return string.Empty;
            }
        }

        #endregion
    }
}

Notice that my class inherits from IDataErrorInfo. MVC checks this for validation errors by default. If it finds any then it invalidates the model and uses the stored errors as the messages for the validation helpers in the view. I'm pretty sure when EF throws an exception, this dictionary never even gets populated with a value for that property. In fact, I'm not even sure that MVC goes so far as to look for a value after detecting and invalidating the model upon the EF generated exception.

Here is a screen shot of the problem, including the sample pseudo-validator so you can see it is working:

As you can see, the error message didn't show up. However, it did correctly validate the field as invalid. If I put a value in there then it validates just fine. I've done A LOT of research on this issue and here is what I know:

The reason you cannot customize the error message that is displayed for required fields is because the model property is not nullable. Because it is not nullable, trying to bind a null value to it throws an exception. MVC swallows this excepion and invalidates the model as it should. The message is generated wherever this exception occurs. I don't know if the message is generated by EF or MVC (I'm guessing MVC since it was responsible for swallowing the exception in the first place). I don't know how to customize this message. As you can see it always says "The value '' is invalid." which I suppose isn't totally horrible but it's really not very user-friendly.

It gets to my name validator and checks if your name is "fred" just fine because no exception is thrown. As far as EF is concerned the value passed in is fine. It isn't until it gets to my OnAuthorChanging method that it realizes it's not okay. This is the correct behavior and works just fine.

If I throw an exception in my OnChanging events instead of adding to my IDataErrorInfo dictionary I can generate the same validation message, only it puts the entered value between the single quotes. Example:

    partial void OnAuthorChanging(string value)
    {
        if (value.ToLower() != "fred")
            //_errors.Add("Author", "Sorry, your name must be Fred.");
            throw new Exception("Sorry, your name must be Fred.");
    }

That code shows this message when "test" is entered as the value for Author: "The value 'test' is invalid.". With the required fields it's just that the value is null so there is nothing to put between the single quotes.

Several people (like this guy) suggest that you simply set the property to nullable in your model. This is NOT an acceptable solution. One reason why not is this:

Error 3031: Problem in mapping fragments starting at line 313:Non-nullable column PostComments.Body in table PostComments is mapped to a nullable entity property.

Also, setting nullable simply will not work on non-nullable types such as int, and switching int to a nullable int is a yucky mess that I won't even get into here.

The bottom line is, I want to handle those exceptions from EF myself or at the very least customize the message it generates but I don't know how. I'm completely lost. All I want to do is customize a message on what I thought was very simple model validation!

Any help is much appreciated.

MVC is validating your model based on the type being non nullible, as you have discovered. This is adding errors to ModelState before your custom validation runs.

I had this before, and got round it by looping through Modelstate at the start of an action and removing everything, then doing my custom validation (bad!!)

Then found even if you are not using data annotations as your main form of validation, you can customise the message that is thrown by adding [Required to the non nullible type in the buddy class, and specify the message.

It's something like this:

[MetadataType(typeof(YourClassMetadata))]
public partial class YourClass
{       
     //buddyclass to entity class
    class YourClassMetadata {
     [Required(ErrorMessage="Your custom overriding error message")]
     public int NonNullablePropertyThatIsGivingYouProblems {get;set;}
    }
}

I've started to look at fluent validation (http://fluentvalidation.codeplex.com) for mvc, and they seem to turn off the problem in global.asax, in on application_start() by adding the line

DataAnnotationsModelValidatorProvider .AddImplicitRequiredAttributeForValueTypes = false;

but I may be wrong about that.

MVC3: WebGrid Column Format Issue

5 votes

I've been trying to change the format of a single column in a WebGrid without much success.

Said column is this:

grid.Column(columnName: "EmailAddress", header: "Email Address", format:(item) => Html.EmailLink(item.EmailAddress, item.EmailAddress, ""), canSort: false),

The error is:

The best overloaded method match for 'System.Web.Helpers.WebGrid.Column(string, string, System.Func, string, bool)' has some invalid arguments

I am confused as the method signature matches. Also, if I change the column to:

grid.Column(columnName: "EmailAddress", header: "Email Address", format:(item) => new HtmlString(String.Format("<a href=\"mailto:{0}\" class=\"{2}\">{1}</a>", item.EmailAddress, item.EmailAddress, "")), canSort: false),

It works without error.

For reference, EmailLink is a very basic HtmlHelper extension method:

    public static IHtmlString EmailLink(this HtmlHelper helper, string emailAddress, string linkText, string linkClass) {
        return new HtmlString(String.Format("<a href=\"mailto:{0}\" class=\"{2}\">{1}</a>", emailAddress, linkText, linkClass));
    }

Apologies if I've missed any detail - this is my first post eek

This is due to the ugliness of WebGrid and all this dynamic crap. You need a cast:

grid.Column(
    columnName: "EmailAddress", 
    header: "Email Address", 
    format: item => Html.EmailLink(
        (string)item.EmailAddress, 
        (string)item.EmailAddress, 
        ""
    ), 
    canSort: false
)

This being said don't hesitate to checkout MvcContrib Grid or the Telerik Grid which are far better.

ASP.NET MVC: Controller created for every request?

5 votes

Very simple question: Are controllers in ASP.NET created for every http request ? Or are they created at application startup and reused throughout requests ?

For some particular http request only the requested controller will created ? Is that right ?

If my previous assumptions are correct can I depend on it ? I want to create database context (Entity framework) that will live only for one request. If I create it as a property initialized in controller's constructor is it granted that new instance of context will be created on for every request ?

A Controller is created for every request by the ControllerFactory (which by default is the DefaultControllerFactory).

http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultcontrollerfactory.aspx

Note that the Html.Action Html Helper will create another controller.

The short version is that ControllerActivator.Create is called (for every request) to create a Controller (Which inits a new Controller either through the DependencyResolver or through the Activator if no Resolver has been set up):

public IController Create(RequestContext requestContext, Type controllerType) {
                    try {
                        return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
                    }

The longer version is this (Here's the code from the source From the MvcHandler)

 protected internal virtual void ProcessRequest(HttpContextBase httpContext)
    {
        SecurityUtil.ProcessInApplicationTrust(() =>
        {
            IController controller;
            IControllerFactory factory;
            ProcessRequestInit(httpContext, out controller, out factory);

            try
            {
                controller.Execute(RequestContext);
            }
            finally
            {
                factory.ReleaseController(controller);
            }
        });
    }

private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
        {
            //non relevant code

            // Instantiate the controller and call Execute
            factory = ControllerBuilder.GetControllerFactory();
            controller = factory.CreateController(RequestContext, controllerName);
            if ( controller == null )
            {
                throw new InvalidOperationException(
                    String.Format(
                        CultureInfo.CurrentCulture,
                        MvcResources.ControllerBuilder_FactoryReturnedNull,
                        factory.GetType(),
                        controllerName));
            }
        }

Here's the Controller factory code

 public virtual IController CreateController(RequestContext requestContext, string controllerName) {
            Type controllerType = GetControllerType(requestContext, controllerName);
            IController controller = GetControllerInstance(requestContext, controllerType);
            return controller;
        }

Which basically calls this :

protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
            return ControllerActivator.Create(requestContext, controllerType);
        }

Which calls this method in the ControllerActivator (This code tries to ask the DependencyResolver for an instance, or just uses the Activator class):

public IController Create(RequestContext requestContext, Type controllerType) {
                try {
                    return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
                }

This might fall under Too much information... But I wanted to show that you really DO get a new controller for EVERY request.

Why does mvccontrib's AssertViewRendered().ForView("Edit") fail due to view name being full cshtml path?

5 votes

I have the following unit test:

    [TestMethod]
    public void Add_Returns_Edit_View()
    {
        // Act
        ActionResult result = _controller.Add();

        // Verify
        result.AssertViewRendered().ForView("Edit");
    }

This should be passing, since the Add action is returning the Edit view. However, this assertion fails with the following exception

MvcContrib.TestHelper.ActionResultAssertionException: Expected view name 'Edit', actual was '~/Views/JobSearch/Edit.cshtml'

Why is the view name coming back as the full path name? Could this be due to my usage of T4MVC, and if so how can I get this to pass?


Edit The Add view looks like this:

    public virtual ActionResult Add()
    {
        return View(MVC.JobSearch.Views.Edit, new JobSearch());
    }

You can test against the T4MVC value like this :

result.AssertViewRendered().ForView(MVC.JobSearch.Views.Edit);

I think it's the cleaner solution... If you have better let me know :)