Best asp.net questions in December 2011

How can I get VisualStudio 2010 with ReSharper to preserve my spaces between '<%:', content, and '%>'?

15 votes

I have Visual Studio 2010 and ReSharper installed and after looking for about an hour, I can't find this formatting setting anywhere.

I'd like it to look like this:

<div><%: Model.Something %></div>

and it keeps removing my space between Model.Something and %> to look like this:

<div><%: Model.Something%></div>

This behavior would be fixed in the next EAP of ReSharper 6.1, maybe even in beta. Sorry, had no time for an option - for 6.1 there would be spaces always, hopefully most of ASP.NET developers would like it that way.

P.S. In older versions you can switch it via option ReSharper | Options | Languages | C# | Formatting Style | Spaces -> Within parentheses -> Method call parentheses. But switching it also affects C# method calls.

ASP.NET, MS11-100, and POST

12 votes

Microsoft recently (12-29-2011) released an update to address several serious security vulnerabilities in the .NET Framework. One of the fixes introduced by MS11-100 temporarily mitigates a potential DoS attack involving hash table collisions. It appears this fix breaks pages that contain a lot of POST data. In our case, on pages that have very large checkbox lists. Why would this be the case?

Some non-official sources seem to indicate that MS11-100 places a limit of 500 on postback items. I can't find a Microsoft source that confirms this. I know that View State and other framework features eat up some of this limit. Is there any configuration setting that controls this new limit? We could switch away from using checkboxes but it works rather well for our particular situation. We'd also like to apply the patch because it protects against some other nasty things.

Unofficial source discussing the 500 limit:

The bulletin fixes the DOS attack vector by providing a limit to the number of variables that can be submitted for a single HTTP POST request. The default limit is 500 which should be enough for normal web applications, but still low enough to neutralize the attack as described by the security researchers in Germany.

EDIT: Source code with example of limit (which appears to be 1,000, not 500) Create a standard MVC app and add the following code to the main index view:

@using (Html.BeginForm()) 
{
    <fieldset class="fields">
        <p class="submit">
            <input type="submit" value="Submit" />
        </p>

        @for (var i = 0; i < 1000; i++)
        {
            <div> @Html.CheckBox("cb" + i.ToString(), true) </div>
        } 
    </fieldset>
}

This code worked before the patch. It doesn't work after. The error is:

[InvalidOperationException: Operation is not valid due to the current state of the object.]
System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded() +82 System.Web.HttpValueCollection.FillFromEncodedBytes(Byte[] bytes, Encoding encoding) +111
System.Web.HttpRequest.FillInFormCollection() +307

Try adding this setting in web.config. I just tested this on .NET 4.0 with an ASP.NET MVC 2 project and with this setting your code doesn't throw:

<appSettings>
  <add key="aspnet:MaxHttpCollectionKeys" value="1001" />
</appSettings>

That should work now (after you have applied the security update) to change the limit.


I hadn't updated my machine yet, so using Reflector I checked the HttpValueCollection class, and it didn't have the ThrowIfMaxHttpCollectionKeysExceeded method:

enter image description here

I installed KB2656351 (update for .NET 4.0), reloaded the assemblies in Reflector and the method appeared:

enter image description here

So that method is definitely new. I used the Disassemble option in Reflector, and from what I can tell from the code it checks an AppSetting:

if (this.Count >= AppSettings.MaxHttpCollectionKeys)
{
  throw new InvalidOperationException();
}

If it doesn't find the value in the web.config file, it will set it to 1000 in System.Web.Util.AppSettings.EnsureSettingsLoaded (an internal static class):

 _maxHttpCollectionKeys = 0x3e8;

Also, Alexey Gusarov tweeted about this setting two days ago:

And here is an official answer from a Q&A with Jonathan Ness (Security Development Manager, MSRC) and Pete Voss (Sr. Response Communications Manager, Trustworthy Computing):

Q: Is AppSettings.MaxHttpCollectionKeys the new parameter that contains the maximum number of form entries?

A: Yes it is.

How was the hash collision issue in ASP.NET fixed (MS11-100)?

11 votes

As reported by Slashdot, MS issued an update to ASP.NET to fix the hash collision attack today. (Listed as "Collisions in HashTable May Cause DoS Vulnerability - CVE-2011-3414" on the linked Technet page.)

The problem is that the POST data are converted into a hash table that uses a known hashing algorithm. And if an attacker uses this by crafting a request that contains lots of collisions, he can easily cause a Denial of Service.

Does anyone know how exactly does that update fix the issue?

The update is not a complete fix, but rather a workaround. It limits the number of POST parameters accepted.

Storing Anything in ASP.NET Session Causes 500ms Delays

9 votes

The Problem:

When you use session in an ASP.NET site, it causes dramatic delays (multiples of 500ms) when loading multiple requests at nearly the same time.

More Specifically, My Problem

Our website uses session exclusively for its SessionId. We use this key to look up a db table that has user info, etc. This seemed to be a good design since it stored minimal session data. Unfortunately, the SessionId will change if you store nothing in session, so we store Session["KeepId"] = 1;. This is enough to convince SessionId to not change.

On a seemingly unrelated note, the site serves customized product images through a controller action. This action generates an image if needed then redirects to the cached image. This means that one web page may contain images or other resources, sending dozens of requests through the ASP.NET pipeline.

For whatever reason, when you (a) send multiple requests at the same time and (b) have session involved in any way then you will end up with random 500ms delays about 1/2 the time. In some cases these delays will be 1000ms or more, always increasing in intervals of ~500ms. More requests means longer wait times. Our page with dozens of images can wait 10+ seconds for some images.

How to Reproduce the Problem:

  1. Create an empty ASP.NET MVC Web Application
  2. Create an empty controller action:

    public class HomeController : Controller
    {
      public ActionResult Test()
      {
        return new EmptyResult();
      }
    }
    
  3. Make a test.html page with a few img tags that hit that action:

    <img src="Home/Test?1" />
    <img src="Home/Test?2" />
    <img src="Home/Test?3" />
    <img src="Home/Test?4" />
    
  4. Run the page & watch the fast load times in firebug:

    Each image loads reasonably fast

  5. Do one of the follow (both have the same result):

    • Add an empty Session_Start handler to your Global.asax.cs

      public void Session_Start() { }
      
    • Put something in session

      public class HomeController : Controller
      {
        public ActionResult Test()
        {
          HttpContext.Current.Session["Test"] = 1;
          return new EmptyResult();
        }
      }
      
  6. Run the page again & notice the occasional/random delays in the responses.

    Some requests experience long delays

What I Know So Far

My Question

How can I use session but avoid these delays? Does anyone know of a fix?

If there's not a fix, I guess we'll have to bypass session & use cookies directly (session uses cookies).

As Gats mentioned, the problem is that ASP.NET locks session so each request for the same session must run in serial.

The annoying part is if I ran all 5 requests in serial (from the example), it'd take ~40ms. With ASP.NET's locking it's over 1000ms. It seems like ASP.NET says, "If session is in use, then sleep for 500ms & try again."

If you use StateServer or SqlServer instead of InProc, it won't help - ASP.NET still locks session.

There are a few different fixes. We ended up using the first one.

Use Cookies Instead

Cookies are sent in the header of every request, so you should keep it light & avoid sensitive info. That being said, session uses cookies by default to remember who is who by storing a ASPNET_SessionId string. All I needed is that id, so there's no reason to endure ASP.NET's session locking when it's just a wrapper around an id in a cookie.

So we avoid session completely & store a guid in the cookie instead. Cookies don't lock, so the delays are fixed.

Use MVC Attributes

You can use session, but avoid the locks on certain requests by making session read-only.

For MVC 3 applications, use this attribute on your controller to make session read-only (it doesn't work on a specific action):

[SessionState(SessionStateBehavior.ReadOnly)]

Disable Session for Some Routes

You can also disable session through MVC routing, but it's a bit complicated.

Disable Session on a Specific Page

For WebForms, you can disable session for certain aspx pages.

Dynamically Insert Pagebreak

9 votes

My team working in a project using asp.net mvc3(c#). Based on the project requirement,we need to implement page break like Microsoft Word. I need to save the pagebreak and the page size may be a4, letter, legal, etc.

Is it possible to control the page size of the content in the ckeditor and insert page breaks shown inside the editor when it crosses a certain height or size, the same way it works in MS Word>

Is there is any alternative solution?

Alternative solution I found after searching the google for solving pagebreak by using RichTextBoxSilverlight

some of the features

  • RichTextBox fully supports paging and printing. You can edit documents in either Print Layout or Draft view; much like Microsoft Word. Print Layout supports continuous page flow when scrolling and even supports facing multiple pages horizontally.

  • RichTextBox supports importing and exporting RTF, Html, and plain text. Load existing rich text or Html into the C1RichTextBox control, edit the document, and then export it back to RTF or Html.

  • Edit and format text containing multiple fonts, decorations, colors, tables, images, lists, and more.

  • RichTextBoxToolbar includes the following commands: Paste, Cut, Copy, Undo, Redo, Font Family, Font Size, Grow Font, Shrink Font, Bold, Italic, Underline, Change Case, Subscript, Superscript, Text Color, Text Highlight Color, Align Left, Align Center, Align Right, Justify, Bullets, Numbering, Text Wrapping, Border Thickness, Border Color, Paragraph Color, Margin, Padding, Insert Image, Insert Symbol, Insert Hyperlink, Remove Hyperlink, Find and Replace, Spell Check, and additional commands for inserting/editing Tables.

  • RichTextBox for inserting and editing images. Users can easily upload images from their computer to the editor or point to an image's url on the web. Users can also select, resize and drag images on the document surface.

  • RichTextBox supports page zooming in both print layout and draft views.

  • RichTextBox content can be exported to PDF format.

  • Edit data in the RichTextBox with confidence. You now have the ability to easily undo and redo your changes with the click of a button.

8 votes

What else needs to be validated apart from what I have below? This is my question.

It is important that any input to a site is properly validated:

  • Textboxes, etc – use .NET validators (or custom code if the validators aren’t appropriate)

  • Querystring or Form values – use manual validation (casting to specific types, boundary checking, etc)

This ties into the problems which XSS can reveal.

Basically you have to validate any input that someone could potentially tamper with:

  • Form Postbacks (mainly .NET Controls – these can be validated with .NET validation controls. Also if you have Request Validation turned on on all pages, this reduces the risk )

  • QueryString Values

  • Cookie values

  • HTTP Headers

  • Viewstate (automatically done for you as long as you have ViewState MAC enabled)

  • Javascript (all JS can be viewed and changed, so need to ensure no crucial functionality is handled by JavaScript- i.e. always enable server side validation)

There is a lot that can go wrong with a web application. Your list is pretty comprehensive, although it is duplication. The http spec only states, GET, POST, Cookie and Header. There are many different types of POST, but its all in the same part of the request.

For your list I would also add everything having to do with file upload, which is a type of POST. For instance, file name, mime type and the contents of the file. I would fire up a network monitoring application like Wireshark and everything in the request should be considered potentially harmful.

There will never be a one size fits all validation function. If you are merging sql injection and xss sanitation functions then you maybe in trouble. I recommend testing your site using automation. A free service like Sitewatch or an open source tool like skipfish will detect methods of attack that you have missed.

Also, on a side note. Passing the view state around with a MAC and/or encrypted is a gross misuse of cryptography. Cryptography is tool used when there is no other solution. By using a MAC or encryption you are opening the door for an attacker to brute force this value or use something like oracle padding attack to take advantage of you. A view state should be kept track by the server, period end of story.

Increasing Session TimeOut

8 votes

Site hosted via IIS 7.0

I would like to set my session time-out to 9 hours in my ASP.NET application.
This has been set at web.config

<sessionState timeout="540"></sessionState>

But, as I understand, if the timeout is set as 20 minutes inside the IIS where the website is hosted, setting an extended session state will be of no use.

Firstly, I would like to confirm whether this assumption is right.

The problem is that I do not have access to the IIS of my shared hosted web server.

Now, after some research, I came up with another solution in code project. This sounds like a wonderful idea. The idea is to insert an iframe to master page. The iframe will contain another page with meta refresh less than 20 minutes.

 Response.AddHeader("Refresh", "20");

This idea seemed good for me. But the article is 7 years old. Plus at comments section a user complaints that this won't work if the page is minimized and I am worried that the same happens when my pages tab is not active.

I would like to know these things

  1. Whether the refresh method will work for my scenario , even if the page is minimized?
  2. Are there any other methods that could increase session time out that overrides IIS timeout setting?
  3. Also I read some questions in Stack Overflow where the answers state that the IIS session timeout is for clasic ASP pages. Then why is not my extended timeout not firing?

Firstly, I would like to confirm whether this assumption is right.

Yes, this assumption is absolutely right in case you are using in-memory session state mode. In this case the session is stored in memory and since IIS could tear down the AppDomain under different circumstances (period of inactivity, CPU/memory tresholds are reached, ...) the session data will be lost. You could use an out-of-process session state mode. Either StateServer or SQLServer. In the first case the session is stored in the memory of a special dedicated machine running the aspstate Windows service and in the second case it is a dedicated SQL Server. The SQL Server is the most robust but obviously the slowest.

1) Whether the refresh method will work for my scenario , even if the page is minimized?

The hidden iframe still works to maintain the session alive but as I said previously there might be some conditions when IIS unloads the application anyway (CPU/memory tresholds are reached => you could configure this in IIS as well).

2) Are there any other methods that could increase session time out that overrides IIS timeout setting?

The previous method doesn't increase the session timeout. It simply maintains the session alive by sending HTTP requests to the server at regular intervals to prevent IIS from bringing the AppDomain down.

3) Also I read some questions in Stack Overflow where the answers state that the IIS session timeout is for clasic ASP pages. Then why is not my extended timeout not firing?

There is no such thing as IIS session timeout. The session is an ASP.NET artifact. IIS is a web server that doesn't know anything about sessions.

Personally I don't use sessions in my applications. I simply disable them:

<sessionState mode="Off"></sessionState>

and use standard HTTP artifacts such as cookies, query string parameters, ... to maintain state. I prefer to persist information in my backend and retrieving it later using unique ids instead of relying on sessions.

Is it possible to call the Razor Compiler Programmatically from a Controller method?

7 votes

I am using ASP .NET MVC 3 and I have an interesting problem to solve that I am hoping for some advice on.

I have a page that has a number of divs inside it. The contents of each div changes over time and so currently I have a timer for each div running that makes a $.ajax request to the server which returns a PartialViewResult with the updated contents of the div. The partial view is quite complex and references other views.

The problem with this approach is that it does not scale very well. It could be that each user has a lot of these timers running and with a lot of users the server is constantly being hit. I would rather, therefore, make a single request to the server that returns, potentially, multiple div contents so it would be:

div1 { some html }
div2 { some html }

...

Then on the client I could put each bit of HTML into the correct position on the page.

I thought that what I could do is return JSON from the server but my problem is - how do I get the HTML? At the moment the razor compiler will run and turn my partial view cshtml files into HTML but if I am returning JSON, is it possible to programmatically call the razor compiler?

I found Razor Engine here: http://razorengine.codeplex.com/ that seems to do what I want but is it possible to do it with just vanilla ASP NET MVC?

Or, given the problem, is there a better way that I could achieve my goal?

Thanks for any help!

Create an Action that returns a new PartialView that renders all of those PartialViews. e.g. an action:

public PartialViewResult AggregatedAction(args)
{
    return PartialView();
}

with a view that contains:

@Html.Action("IndividualAction1", null)
@Html.Action("IndividualAction2", null)
@Html.Action("IndividualAction3", null)

See http://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx for more details.

That way there is only one request and the rendering engine is being called from the right place, i.e. the view.

Then with the result, you can search for the various divs and replace the html in the client.

$('div#id1').html('div#id1',$(data));
$('div#id2').html('div#id2',$(data));

If the structure of your page allows it, you should use: http://api.jquery.com/load/ (as @Jorge says) to replace all of the html with one line.

$('div#targetDiv').load('Controller\AggregatedAction', anyData);

Arabic Characters in URL

6 votes

I have created a website using DNN. The site has arabic characters in URL after the domain name. For example: http://www.example.com/اسعارالعملات.aspx.

My questions are:

  1. Is this URL read by non Arabic supportive operating systems or browsers or will it give the user an error?
  2. Is it good for SEO to have Arabic in URL or not?
  3. Are there any other problems due to the use of Arabic characters?

Edit : To answer your question points directly.

[1] Yes they will work fine due to Internationalized Resource Identifiers.

[2] If you are targeting Arabic search results then yes having arabic in the url bar is good for SEO. I am sure Google does clever translation stuff tho as well.

[3] Copy pasting the URL will look funny due to [1] If you look at Arabic wikipedia and try copy paste their url somewhere you will see what I mean.

More information

I know Google does put some weight into what is in the url so for example having page-title.aspx will be better than pagetitle. I would imagine that the same rules apply for having foreign language urls - it will help increase results when people are searching for terms that are included in your arabic word.

Most browsers will deal with it fine I don't think you need to have a special language pack installed. Arabic Wikipedia works fine though the characters get mapped using Internationalized Resource Identifiers.

http://webapps.stackexchange.com/questions/15539/how-do-special-foreign-language-characters-in-an-url-work-and-are-they-fake

So will look fine in your url bar but will look like this http://ar.wikipedia.org/wiki/%D8%A7%D9%84%D8%B5%D9%81%D8%AD%D8%A9_%D8%A7%D9%84%D8%B1%D8%A6%D9%8A%D8%B3%D9%8A%D8%A9 when copied.

I always liked how backspace and delete work the other way around with Arabic text.

Refactoring method containing LINQ queries

6 votes

I'm having a little trouble deciding the best way to refactor a method which contains LINQ queries which are very similar but not identical.

Consider a method which is something along these lines:

public SomeObject GetTheObject(IMyObject genericObject) {
    Type t = genericObject.GetType();
    SomeObject so = null;

    switch(t.Name) {
        case "Type1":
            var object1 = (from o in object1s where o.object1id == genericObject.id).FirstOrDefault();
            so = (SomeObject)object1;
        break;
        case "Type2":
            var object2 = (from o in object2s where o.object2id == genericObject.id).FirstOrDefault();
            so = (SomeObject)object2;
        break;
        default:
        break;
    }

    return so;
}

This is just an illustration, but imagine I'm needing to execute a different query (different in that it uses a different ObjectSet, uses slightly different fields (object1id vs object2id) and returns a different type. Other than that, the queries are the same.

Is there a sensible way to refactor this kind of method? It feels like I've missed something obvious. Perhaps I have to use the exact method and I can't avoid re-writing the query, it just seems like I SHOULD be able to somehow!

Any pointers greatly appreciated

Maybe you have just oversimplified your scenario, but the smelly part of your function is the cast to SomeObject. Couldn't you just work with interfaces and (if needed) cast the result at the call site? You could have your Type1 and Type2 implement a common interface where id1 and id2 are exposed as id, for example (or decorate them if you don't control Type1 and Type2)

I.e.

public static IMyObject GetTheObject(List<IMyObject> theList,  int id)
{
    var ret = (from o in theList
        where o.id==id
        select o).FirstOrDefault();

    return ret;
}

For instance, if you have:

    public interface IMyObject {int id {get;}}

    public class Foo : IMyObject {public int id {get; set;}}
    public class Bar : IMyObject {public int id {get; set;}}

you can do:

var l1 = new List<IMyObject>(){new Foo(){id=1}, new Foo(){id=2}};
var l2 = new List<IMyObject>(){new Bar(){id=1}, new Bar(){id=2}};   

var obj1 = Test.GetTheObject(l1, 1);
var obj2 = Test.GetTheObject(l2, 2);

And cast the objects after you call the function, if you have to.

EDIT: if you're stuck with concrete objects and casts, the best refactoring I could come up with is:

public static SomeObject GetTheObject(IMyObject genericObject) {
    Type t = genericObject.GetType();

    Func<SomeObject, bool> WhereClause = null;
    IEnumerable<SomeObject> objs = null; // IEnumerable<T> is covariant, 
                      // so we can assign it both an IEnumerable<object1>
                      // and an IEnumerable<object2> (provided object1 and 2 are
                      // subclasses of SomeObject)

    switch(t.Name) {
        case "Type1":
            WhereClause = o => ((Object1)o).object1id == genericObject.id;      
            objs = object1s;
        break;
        case "Type2":
            WhereClause = o =>  ((Object2)o).object2id == genericObject.id;     
            objs = object2s;
        break;
    }

    var ob = objs
    .Where(WhereClause)
    .FirstOrDefault();

    return (SomeObject)ob;
}

Generic syntactic sugar or true improvement

6 votes

I have a question regarding the following method calls:

var ctl1 = this.FindControlRecursively("SomeField") as HiddenField;
var ctl = this.FindControlRecursively<HiddenField>("SomeField");

Here's IL for these two calls:

IL_0010:  ldstr      "AsyncReset"
IL_0015:  call       class [System.Web]System.Web.UI.Control   [Amc.WebG081.MethodExtensions]Amc.WebG081.ControlExtensions::FindControlRecursively(class [System.Web]System.Web.UI.Control,string)

IL_001a:  isinst     [System.Web]System.Web.UI.WebControls.HiddenField
IL_001f:  stloc.0
IL_0020:  ldarg.0
IL_0021:  ldstr      "AsyncReset"
IL_0026:  call       !!0 [Amc.WebG081.MethodExtensions]Amc.WebG081.ControlExtensions::FindControlRecursively<class [System.Web]System.Web.UI.WebControls.HiddenField>(class [System.Web]System.Web.UI.Control,string)

I've always thought in this situation, the generic version of this method was more "syntactic sugar" vs. true improvement. Is the IL telling a different story?

Generics are built into C#, so it is a "true improvement". Hence why run-time co-variance and contra-variance is possible, as well as reflection on generic types and run-time reflection-based creation of generic types (such as List<T> where T is determined at run-time).

This differs from C++, where templates are, in a lot of ways, syntactic sugar. The compiler actually generates code for each generic type you use - so Add<T> would create Add<int>, Add<long>, Add<short>, Add<MyClass>, and so on if you were using those functions, and likewise for classes. The benefit of this is primarily operators and a few other smaller things - if each of those types has a + operator, and Add<T>(T a, T b) returns a + b, all types will work just fine. C#'s compiler would complain because it can't/doesn't resolve the operator declaration for any-and-all types at compile time. Moreover, C# (not 100% sure, but maybe 90%) creates 1 generic type implementation for reference types (if you're using that implementation) and then 1 for each value type (so int, long, Decimal, MyStruct, etc all get their own implementations, as needed).

ASP.NET MVC receives "null" as a string instead of null

5 votes

I have something wrong with either json or ASP.NET MVC, I am using ASP.NET MVC and here is what I am sending from the client.

NOTE After debugging in Chrome, I am explaining that this is what is passed within javascript, I am not manually setting State to null as it is coming as result from somewhere else as null. Which once again is not in my control as it is coming from database.

While debugging, State displays that it is null, instead of "null", but while debugging in MVC it is displaying "null" instead of null.

$.ajax(
   '/Client/Post',
   {
       method: 'POST',
       data: {
                 Country: 'US',
    // this is null because it is coming from somewhere else as null
                 State: null
             }
   });

My ASP.NET MVC Handler receives...

public ActionResult Post(Client model){
    if(model.State == "null") 
    {
         /// this is true... !!!!
    }
    if(model.State == null )
    {
         // :( this should be true...
    }
}

enter image description here

Is it problem of ASP.NET MVC or jQuery?

So is it jQuery that sends null as "null" or is it MVC that is setting null as "null"?

SOLUTION

I had to just recursively create new object hierarchy (cloning the object) and send it to jQuery, as jQuery sent data as Form Encoded, in which there is no way to represent null, however ideally jQuery should not have serialized null at all.

Don't send the field:

$.ajax('/Client/Post',
{
   method: 'POST',
   data: {
             Country: 'US'
         }
});


Edit after I re-READ your post

var data = {
                 Country: 'US',
                 State: null
             }
if (!data.State) delete data.State;
$.ajax('/Client/Post',
    {
       method: 'POST',
       data: data
    }
});

This is the same exact principle as above FYI

Getting last two rows in a text file

5 votes

So I am creating a list of lines in a text file like this:

var lines = File.ReadAllLines("C:\\FileToSearch.txt")
                .Where(x => !x.EndsWith("999999999999"));

and looping through the lines like this

foreach (var line in lines)
{ 
    if (lineCounter == 1)
    {
        outputResults.Add(oData.ToCanadianFormatFileHeader());
    }
    else if (lineCounter == 2)
    {
        outputResults.Add(oData.ToCanadianFormatBatchHeader());
    }
    else
    {
        oData.FromUsLineFormat(line);
        outputResults.Add(oData.ToCanadianLineFormat());

    }
    lineCounter = lineCounter + 1;
    textBuilder += (line + "<br>");
}

Similary like I access the first two rows I would like to access the last and second last row individually

Here you can take advantage of LINQ once again:

var numberOfLinesToTake = 2;
var lastTwoLines = lines
     .Skip(Math.Max(0, lines.Count() - numberOfLinesToTake))
     .Take(numberOfLinesToTake);

var secondToLastLine = lastTwoLines.First();
var lastLine = lastTwoLines.Last();

Or, if you want to retrieve them individually:

var lastLine = lines.Last();
var secondToLastLine = 
    lines.Skip(Math.Max(0, lines.Count() - 2)).Take(1).First();

I added .First() to the end, because .Take(1) will return an array containing one item, which we then grab with First(). This can probably be optimized.

Again, you might want to familiarize yourself with LINQ since it's a real time-saver sometimes.

Creating menus at runtime depending on user role

5 votes

I am trying to create a menu that sorts differently depending on what the user role is.

For example, if the user is an Admin role, the menu shown will be:

  • AdminPane

  • RegisterUser

  • UserRoles

and if the user is Basic role:

  • ViewProducts

  • makeOrder

This is a layout example.

I would appreciate some help as I've been searching the net for 2 hours with no luck.

Thanks.

What you want to do is in your web.config have a section in your system.web section, like so:

    <siteMap>
        <providers>
            <add name="anonymous" type="System.Web.XmlSiteMapProvider" siteMapFile="~/YourAnonymouse.sitemap"/>
            <add name="user" type="System.Web.XmlSiteMapProvider" siteMapFile="~/YourNormalUser.sitemap"/>
            <add name="admin" type="System.Web.XmlSiteMapProvider" siteMapFile="~/YourAdmin.sitemap"/>
        </providers>
    </siteMap>

Then with this, you'll have three site map providers defined, each pointing to their respective sitemap files for the necessary menu you are looking for for each user type.

Then you'll have a SiteMapDataSource that your menu server control will use. This will most likely exist on your master page. On your Page_Load() of your master page you'll have logic to dynamically and programmatically set the sitemap data source of your SiteMapDataSource control:

    if (HttpContext.Current.User.Identity.IsAuthenticated)
    {
        if (HttpContext.Current.User.IsInRole("Admin"))
            SiteMapDataSource1.Provider = SiteMap.Providers("admin");
        else
            SiteMapDataSource1.Provider = SiteMap.Providers("user");
    }
    else
        SiteMapDataSource1.Provider = SiteMap.Providers("anonymous");

Is Caching in C# the right approach for me?

5 votes

I've tried to read up on Caching in ASP.NET and still have a few questions.

  1. When using a Sql Cache Dependency ... I know that you can specify which tables will be monitored but if a change happens to any one of those tables does it reset the entire cache? I understand that I don't want to cache tables that will have frequent changes but we could end up with a good handful of cached tables and even if each table only gets a few updates a day, that could turn into 50ish resets of the cache daily (8 hour window).

  2. I would be creating and maintaining this cache via a GAC DLL. A large number of different applications would be accessing that GAC at any one time. Does each application maintain its own copy of the cache or is it just stored in one global location (or possibly per app pool)?

  3. Is there a physical location on the server where I can see how much space the Cache is currently consuming? This would be extremely pertinent if each application maintains its own Cache as that could end up taking large amounts of disk space.

  4. Is there some way to physically force the cache to rebuild itself? I could see my boss assuming that the cache was at fault for a particular issue and I'd need to be able to rule that out at the rootest level. No "changing a record and saying that SHOULD rebuild the cache" but rather "doing [Action X] and KNOWING that whatever was in the cache is now gone"

Thanks in advance for your answers and time.

  1. SqlCacheDependency only monitors tables in the old-style SQL 2000 approach, which relies on triggers and polling. The SQL 2005+ method monitors changes at the row level, and uses Service Broker. At the level of the Cache object, changes will invalidate just the Cache entries associated with the given SqlCacheDependency (not the entire cache).

  2. Each application has a separate copy of the Cache. If you have many apps sharing the same data, you might consider creating a separate "caching server," and have your apps get their data from there, using WCF -- basically add another tier to your app.

  3. You can look at a couple of cache-related performance counters, but if your concern is disk space, then there's nothing to worry about, since the ASP.NET cache is stored entirely in RAM. In addition, if RAM gets too full, one feature of the cache is that it will let go of old/infrequently referenced objects to make room for new objects.

  4. The easiest way to force the cache to be dropped is to simply recycle your application or AppPool (which happens once a day or so by default anyway). If you want something more targeted, you would need to write some code to forcibly remove certain items from the cache, either using Cache.Remove() or using linked dependencies.

How to create custom MVC3 ActionLink method?

4 votes

Possible Duplicate:
How to put span element inside ActionLink MVC3?

How to create custom MVC3 ActionLink method that generates this output:

<li>
    <a href="/Home/ControllerName" data-ajax-update="#scroll" 
     data-ajax-mode="replace" data-ajax-method="GET" 
     data-ajax-loading="#progress" data-ajax="true">

     <span>LinkText</span> // this span generated inside <a>

    </a>
</li>

You either create a new extension method that returns an MvcHtmlString object that you put together yourself (mind the html encoding, though), our you create a partial view that you can render when you need it, so you don't have to create HTML through code.

public static class MyHtmlExtensions {
    public static MvcHtmlString MyActionLink(this HtmlHelper html, string action, string controller, string ajaxUpdateId, string spanText) {
         var url = UrlHelper.GenerateContentUrl("~/" + controller + "/" + action);
         var result = new StringBuilder();
         result.Append("<a href=\"");
         result.Append(HttpUtility.HtmlAttributeEncode(url));
         result.Append("\" data-ajax-update=\"");
         result.Append(HttpUtility.HtmlAttributeEncode("#" + ajaxUpdateId));
         // ... and so on

         return new MvcHtmlString(result.ToString());
    }
}

Migrating from ASP.NET WebForms to MVC

4 votes

I've read plenty of questions and articles stating that converting from ASP.NET Webforms to MVC is near enough impossible. However I think my scenario is different.

I foolishly started working a project about a year ago in Webforms, but the approach I took (as far as I understand) is very MVC like. I have disabled forms validation, don't use any postbacks, use URL re-writing and all page changes are AJAX requests that load the page contents of ContentPlaceHolders (using a small hack, overriding the RenderControl method). I've also used my own ORM and RESTful Service API in seperate projects, referenced in the website.

Now the system works really well, the pages are partially refreshed fine and the url's are changed when the ajax calls are made, so when the page is refreshed, it looks exactly the same.

Now I've just been told I need to learn MVC for a new big project (but I have to finish another project first), but I've done a bit of reading on the subject and started a few Hello World apps, and it seems that the idea of ASP.NET MVC is pretty much exactly what I have already created.

Would StackOverflow still recommend against converting the Webforms application to MVC? Are there any other benefits of converting to MVC, besides best practices?

I have a very large and old ASP.NET WebForms application (which was originally written for .NET 1.1!) and have enabled MVC to work in it, side-by-side. I've been writing new features using MVC, and converting old WebForms features to MVC controllers and views.

I ran into a few little issues concerning URL authorization and running in IIS integrated mode, but once I understood the issues they were fairly easy to work out. So nearly impossible? Certainly not!

I can't tell you if it's worth your time to convert it, since I don't know the size, scope or nature of your application, or any business constraints. However, moving to MVC has been a considerable boon to ease of development and quality (since it is easier to compartmentalize and unit test). Not to mention, the features I've written (or rewritten) in MVC are much cleaner, faster, and responsive than the WebForms equivalents.

I'm excited to move it from MVC v2 to v3, and convert to Razor views. So would I? I if I were you and I had the time, I'd do it.

Here's a question I posted that outlines the process and one of the more significant problems I had in the conversion. Migrating legacy ASP.NET to MVC 2 (RC): HttpApplication events not firing, User principal is null

What Does UpdateModel() Do?

4 votes

In layman's terms, what does UpdateModel() do, as well as TryUpdateModel()? I can't seem to find (on SO or the web) any clear explanation of what it actually does (in clear terms), just people having problems using it.

VisualStudio's intellisense is not helping me either. The reason why I ask is because, let's say, if I have this in my controller:

[HttpPost]
public ActionResult Index( UserViewModel vm, FormCollection form)
{    
  var statesCheckBoxes = form["StatesList"];       

  vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>();

  return View(vm);
}

Aren't I already updating my model by setting vm.BA.StatesTraveledTo ? Why do I need to run UpdateModel? Also, when I actually try to do the following:

[HttpPost]
public ActionResult Index( UserViewModel vm, FormCollection form)
{    
  var statesCheckBoxes = form["StatesList"];       

  vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>();

  UpdateModel(vm); // IS THIS REDUNDANT TO THE PREVIOUS LINE?

  return View(vm);
}

Nothing seems to happen in that when I inspect the value of the ModelState (after I run UpdateModel() ), I don't see anything indicating that anything has changed. I don't see a new key in the ModelState dictionary.

Really confused. Thanks!

Edit:

Posting the source code for the ViewModel and Model classes:

public class UserViewModel
{
  public BankAccount BA { get; set; }
}

public class BankAccount
{
  public Person User { get; set; }
  public List<string> StatesTraveledTo { get; set; }
}

public class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public int Age { get; set; }
}

what happens when you write

public ActionResult Index( UserViewModel vm)
{    }

and when u inspect in the actionresult you find that vm contains values that you posted from the view. it is because mvc directs the modelbinder to extract values from different sources (form collection, route values, querystring etc) and populate values of your model. But for this to happen your form keys must match the name of properties in your model and if that is the case your model is populated correctly. now we come to the actual question: what does UpdateModel do? simple answer is nothing but model binding. The difference is only that you call it explicitly. The above Actionresult can be rewritten like using UpdateModel

Public ActionResult Index ()
{
   UserViewModel vm = new UserViewModel();
   UpdateModel(vm);// it will do same thing that was previously handled automatically by mvc
}

Now, what was not handled by automatic model binding will not be handled by explicit model binding as well because its not the problem with model binder its the problem with your html. with nested view models like yours, the form field names must be carefully crafted so mvc can correctly inject it to your model without you having to write something like

vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>(); 

and if you don't want to do such thing check this google search

How can I register a client-side event listener on a server-side event?

3 votes

(Assuming it's even possible in .Net, of course.)

Ultimately, what I want to accomplish is an AJAX-based messaging system. I already have a database table for messages, and an ASPX to add new messages (and declare old messages no longer relevant).

The current messaging system simply polls the server every 15 seconds, and re-pulls the current message set.

What I am looking to do is: On $(document).ready(), register an ajax callback function that listens for a server-side event (e.g., MessagesUpdated) On table insert/update, fire MessagesUpdated server-side.

This way, whenever the table is updated (or new records added), any clients listening know that new data is available and can re-poll the server then.

Ideally, I'd also like to make the new data available as an event argument (to minimize re-polling the db).

I can find references to something like this in other languages, but I cannot find any actual code examples to get me started.

Assuming this is possible to do via .Net, can anyone help get me started on this?

I'm using the 2.0 Framework. Also while I added a VB.Net tag, I can read C# reasonably well, so please feel free to post in either language.

Thanks in advance!

Pete

Take a look into long polling. Basically what it does is set a long timeout period on AJAX requests. The client then waits for the server to respond. This is much more efficient and instantaneous than sending requests every few seconds.

How to do a long polling client in C#?