Best asp.net questions in April 2012

What is the most efficient way to store / retrieve items in asp.net httpContext.Cache

11 votes

I have a website where I cache a lot of info. I am seeing conflicting information around storing stuff in the asp.net cache.

For example lets say I have this data structure:

 Dictionary<string, List<Car>> mydictionary;

I could store the whole thing with a string key as "MyDictionary" and then drill down once i pull out the object.

 HttpContext.Cache.Add("MyDictionary",  
   mydictionary, 
   null, 
   Cache.NoAbsoluteExpiration,
   new TimeSpan(10, 0, 0),
   CacheItemPriority.Normal,
   null);

 var myDict = HttpContext.Cache["MyDictionary"] as Dictionary<string, List<Car>>;

The other thing i could do is break it down and store each item in my dictionary separately in the cache (given the cache is a dictionary anyway).

 Dictionary<string, List<Car>> mydictionary;

 foreach (var item in mydictionary.Keys)
 {
      HttpContext.Cache.Add(item, mydictionary[item], null, Cache.NoAbsoluteExpiration, new TimeSpan(10, 0, 0), CacheItemPriority.Normal, null);
 }

 var myitem = "test";
 var myDict = HttpContext.Cache[myItem] as List<Car>;

Would the performance implication be very different (given i am assuming that everything is in memory anyway ?)

Adding an additional answer here as I feel the existing one capture the 'what' but not enough of the 'why'.

The reason it's best to store individual entries separately in the cache have little to do with perf. Instead, it has to do with allowing the system to perform proper memory management.

There is a lot of logic in the ASP.NET cache to figure out what to do when it runs into memory pressure. In the end, it needs to kick out some items, and it needs to do this in the least disruptive way possible. Which items it chooses to kick out depends a lot of whether they were accessed recently. There are other factors, like what flags are passed at caching time. e.g. you can make an item non-removable, and it'll never be kicked out.

But going back to the question, if you store your entire dictionary as a single item, you are only leaving two options to the ASP.NET memory manager: keep the entire thing alive, or kill the whole thing. i.e. you completely lose the benefit of having your 'hot' items stay in the cache, while your rarely accessed memory-hogging items get kicked out. In other words, you lose any level of caching granularity.

Of course, you could choose to implement your own scheme in your dictionary to remove items that are rarely used. But at that point you're re-inventing the wheel, and your new wheel will not work as well since it won't coordinate with the rest of the system.

Throwing exceptions and notifying the user

8 votes

I've recently joined an asp.net mvc project well under way where there isnt much consistency in dealing with exceptions in the controller; some devs return data to the client to let the user know whats wrong, others throw them back so they get to the server-level handler that processes and logs them - without letting the user know whats up.

It seems obvious to me that both approaches are wrong on their own, and need to complement each other instead; what I'm stuck at, is how to do that. I assume the eventual exception handler / logger could redirect the user to an error webpage upon catching something particularly nasty, but that limits the mechanism to just severe stuff.

I'm kind of looking for a way to do both "throw" and "return ..." at a time when I catch an exception, so I get it sorted and logged server side and get data client side that lets me tell the user there's been a hiccup.

My expertise with asp.net is very limited, and while I believe I understand mvc enough for it to not be an issue, this is kind of a "what is the best practice?" question from someone working with people who dont bother with best practices much.

There is a good project called Elmah for logging errors and exceptions in ASP.NET applications. You can find it here

ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment.

Once ELMAH has been dropped into a running web application and configured appropriately, you get the following facilities without changing a single line of your code:

  • Logging of nearly all unhandled exceptions.
  • A web page to remotely view the entire log of recoded exceptions.
  • A web page to remotely view the full details of any one logged exception, including colored stack traces.
  • In many cases, you can review the original yellow screen of death that ASP.NET generated for a given exception, even with customErrors mode turned off.
  • An e-mail notification of each error at the time it occurs.
  • An RSS feed of the last 15 errors from the log.

Converting from DateTime to SqlDateTime is inaccurate

8 votes

I have a method that gets a date property from a source (either a DataRow or a SqlDataReader):

protected SqlDateTime GetSqlDateTimePropertyValue(string propertyName, object source)
{
  var objValue = GetPropertyValue(propertyName, source);
  var value = objValue == DBNull.Value ? null : (DateTime?)objValue;
  var sqlValue = new SqlDateTime();
  if (value.HasValue) sqlValue = value.Value;
  return sqlValue;
}

but the conversion appears to be changing the date slightly so that my test always fails.

Does anyone know why this method would be converting wrongly?

At the end of the method, it looks like the conversion to SqlDateTime does some rounding:

value.Value.Ticks:        634698391707468296
sqlValue.Value.Ticks:     634698391707470000

Yes - the SQL Server DATETIME has an accuracy of 3.33ms - the .NET datatype however can represent single milliseconds.

Therefore, you will have some rounding issues at times.

Read a lot more about the DATETIME datatype and its properties and quirks here:

Demystifying the SQL Server DATETIME datatype

Also, SQL Server 2008 introduced a slew of new date-related data types - read more about those here:

SQL Server 2008 New DATETIME datatypes

These types do include a DATETIME2 datatype which is accurate to 100ns.

Weird 404 error in ASP.NET MVC when including "con"

8 votes

I'm going through some of the crawl errors on an MVC application I maintain, and found a 404 error for a URL that looked like it should be valid.

The URL is of the format: /gifts/{categoryName}/{productName}/{productId}/

For some reason, when the productName is set to the value "con" I just get a 404 error. Any other value (different or same length of string) and it seems to work fine.

Has anyone ever seen anything like this before?

con is a reserved word and therefore cannot be put in an MVC route

You need to add the following to your web.config:

<configuration>
  <system.web>
    <httpRuntime relaxedUrlToFileSystemMapping="true"/>

    <!-- ... your other settings ... -->
  </system.web>
</configuration>

See this article for more information:

Putting the Con (COM1, LPT1, NUL, etc.) Back in your URLs

Reloading page when user arrives from back button

7 votes

I have a generic error page, that any handled error will redirect to. I have an admin page that when the user invokes an error, and the user is brought to the error page, hitting the back button from the error page cause the admin page to load improperly.

So what I need, is a way to reload the admin page when I come from the error page. I have tried setting no cache and such on the admin page, and checking for a postback, but nothing works. Setting no cache seems to do nothing, and any javascript on the admin page's document.ready function does not get called either. Is there any other ways to get this to happen?

EDIT:

I should also mention that I have noticed that a table is missing 2 cells I recently added. This makes me believe that there is a old state of the page being cached somewhere, although clearing the browser cache and restarting my server do not help at all.

Edit2:

Also, setting window.onload() gets nuked when I come back to the admin page

So it turns out this is just an IE9 issue. My onload method was just never getting called. Works fine in the other browsers.

The fix I had to make in order get this to work in IE9 as well was to append a query string to the page, so that when I come back to the page, IE9 will go back to the browser incise the query string has changed or needs to be re-evaluated.

Thanks to both of you guys, or help helped me find the issue.

Managing Dynamic Website Settings Persisted in a Database

7 votes

I am trying to create something to hold global site-wide settings in our ASP.NET website - things such as site name, google analytics account number, facebook url etc... The site can have multiple ‘brands’ or sub-sites associated with it, hence the sitguid column, we would also like to have the option to put them into groups, hence the group column – e.g. TEST and PRODUCTION (set via web.config appsetting).

I do not want any of the KEY’s to be hardcoded anywhere, but I would like to be able to reference them as simply as possible in code, e.g. SiteSetting.getSetting(“SiteName”) (these may be used in templates (masterpages and such) that more junior devs will create)

I would also like to be able to administer the existing settings in our admin console and to be able to create new settings.

The datatype column is for the edit form so that the correct input element can be used, e.g. checkbox for bit types, text box for varchar etc...

SiteSettings database table currently:

  [sts_sitGuid] [uniqueidentifier] NOT NULL, -- tells us which site the setting is for
  [sts_group] [nvarchar](50) NOT NULL, -- used to group settings e.g. test/live
  [sts_name] [nvarchar](max) NULL, -- the display name of the setting, for edit forms
  [sts_alias] [nvarchar](50) NOT NULL, -- the name for the setting
  [sts_value] [nvarchar](max) NOT NULL, -- the settings value
  [sts_dataType] [nvarchar](50) NULL, -- indicates the control to render on edit form
  [sts_ord] [tinyint] NULL,  -- The order they will appear in on the admin form

I am part way through having this working at the moment, but I am not happy with the way I have done it and would like any advice people here have that might help find the ‘right’ solution! I'm sure people have done this before me. (I would share what I have so far, but do not want to skew the answers in any particular way) All i'm looking for is an overview of how this might be best done, not looking for anyone to write it for me ;)

I’ve done quite a bit of searching both here and Google and have not really found what I’m looking for, especially the ability to add new setting ‘definitions’ as well as editing the settings that exist.

The system runs on ASP.NET using webforms, it's all written in c# and uses MSSQL 2008.

As always, any help is very much appreciated!

EDIT: To clarify I am going to explain what I have built so far. I am dead set on storing all of this in SQL as we don't want web.config or other xml files or another database floating around since it'll give us more to do when we rollout the app to other customers.

So far I have a SiteSettings class, this has a method GetSetting which i can call with GetSetting("SettingAlias") to get the value for "SettingAlias" in the DB. This class's constructor fetches all the settings for the current site from the database and stores those in a dictionary, GetSetting reads from that dictionary. All of that part I am happy with so far.

The part I am struggling with is generating the edit form. The previous version of this used a webservice to get/set the settings and I am trying to continue using something similar to save work, but they were all defined in the code, such as GoogleAnalyticsID, Sitename etc... and each had a column in the database, the change I am making is to store these settings as ROWS instead (since then it's easier to add more, no need to change the schema & all of the sitesettings class) Currently my SiteSettings class has a SiteSettingsEditForm method which grabs all the info from the db, creates a bunch of controls for the form elements, puts that in a temporary page and executes that, then passes the HTML generated to our management system via ajax. This feels wrong and is a bit clunky, and is the reason for posting it here, I am having trouble figuring out how to save this stuff back via the webservice, but more importantly generating a bunch of HTML by executing a page containing a load of form controls just feels like the wrong way to do it.

So in summary I (think i) want to write a class to be able to cache & read a handful of rows from a database table, and also give me an edit form (or give data to something else to generate the form) that is dynamic based on the contents of the same database table (e.g. where my type column is 'bit' I want a checkbox, where it is 'text' I want a text input)

Sometimes this kind of problem is easier to visualize if you start off with the data model. If you want a setting per row, then two tables would probably be the best way to store this:

Site:

SiteIdSiteKeySiteName
1XYGZ4345Client Site 1
2AZT43752Client Site 2

This would define the list of sites you have config for. I'd use a SiteKey as you'd put this in your web.config and it's better to abstract this away into a random string or GUID (to make it harder to accidentally load someone else's config), the client can change their name and you don't get confused in the future as you didn't use their old name as a key etc etc.

The config table itself is also simple, if we treat every setting as a string:

SiteSetting:

SettingIdSiteIdSettingNameSettingValue
11BrandKrustyBrand
21GoogleIdMSFTSUX0R
32BrandConfigMasters(TM)

You can then load all the config quite simply:

SELECT * FROM SiteSetting INNER JOIN Site ON (SiteSetting.SiteId = Site.SiteId) WHERE Site.SiteKey = 'XYGZ4345'

Now we have a list of key value pairs you could then store in a class like:

public class SiteSetting
{
    public Site Site {
        get; set; //Site would just be a simple class consisiting of Id, Key and Name to match the database table
    }

    protected Dictionary<String, String> Settings { get; set; } //Simple key value pairs

}

So this is a very simple solution. However, we can take it further - things to consider:

1) Can we add an environment to this somewhere?

We could either add a site per environment

OR

Add an environment to the SiteSetting table. The advantage of this is that you could define enironment = 'ALL' to avoid duplication.

OR

The database the configuration is loaded from defines the environment; so you change the config connection string in the app config. Of course, to connect to a different environment you have to change app.config, but you would potentially have to do that anyway to change the client key and/or environment.

2) Add the concept of user defineable settings - some settings you are going to want to change, some you are going to want to lock. A bit column containing "UserDefinable" would allow you to sort this out

3) Typing of settings.

This is slightly more difficult. You might have something like:

PropertyIdPropertyNamePropertyTypeFormatUserDefined
1BrandStringNULL1
2DatePresentationDateTime"yyyy-MM-dd"1

The Settings table then only defines a value, and a PropertyId. The advantage of this is that you can then start to increase the information about each setting you are storing, and reuse this information as the design is more normalized. The Settings class then changes like so:

public List<PropertyValue> { get; set; } //replacing the dictionary

PropertyValue then looks something like:

public class PropertyValue
{
    int Id { get; set; }

    public string Name { get; set; }

    public string Value { get; set; }

    public string PVType { get; set; } //Could be an enum

    public string DisplayFormat { get; set;

    private string _RawValue;

    public string Value{
        get{
          switch(PVType){
            case "DateTime":
                    return Convert.ToDateTime(_RawValue).ToString(DisplayFormat);
            break;
            case "Double":
                    return Convert.ToDouble(_RawValue).ToString(DisplayFormat);
            break;
            default:
                    return _RawValue;
          }
        }
        set{
            _RawValue = value;
        }
    }

}

Things like the Value method need to be improved to support robust error handling (you could also investigate using Convert.ChangeType to simplify the switch block)

This topic is as simple or as complicated as you choose to make it ;-)

Editing

As regards maintaining them; a very simple GUI would allow the user to see all of their properties in a tabular format. You might consider having rows where UserDefinable = 0 as readonly, otherwise the user can edit and add rows. You'd need to validate, especially for duplicate Setting Names for example.

The easiest way to do this is to use the DataGrid; a simple mockup might look something like this:

Mockup of Grid Edit

And a more sophisticated approach might look something like this

Generating the form is therefore as simple as databinding a collection of PropertyValue objects to your chosen grid solution.

SqlDataSource Code Behind Event Order

7 votes

I have an SqlDataSource, a Gridview and a DropDownList on the same page. The DropDownList selection is associated with a set of SelectCommands, UpdateCommands, and DeleteCommands so that I can take advantage of the GridView AutoGenerateEditButton="true" and AutoGenerateUpdateButton="true" mechanism.

Page_Load
{
  switch(ddl.SelectedItem.Text)
  {
     case "A":
       sqlDS.SelectCommand = "Select * From A";
       sqlDS.UpdateCommand = "Update A Set Name = @Name WHERE ID = @ID";
       sqlDS.DeleteCommand = "Delete A WHERE ID = @ID";
       break;
     ...
  }

  sqlDS.DataBind();
  grd.DataSourceID = sqlDS.ID;
  grd.DataBind();
}

How or at what point do I need to add Parameters? Is it automatic? I basically just want the ability to update and delete columns from a table. I want to do all of this in the actual .cs file, as opposed to within the .aspx file as I'd like to make it more dynamic eventually; but for now I just want to get the basics down. I suspect that I may have the DataBind() logic in the inappropriate event because I don't fully understand the order of events associated with the data binding.

The queries are not complicated and involve no joins or views; they are simple SELECTs over single tables.

Edit: It does appear that if you use AutoGenerateColumns="true" on the GridView and populate via SqlDataSource, it will automatically bind the values of the controls by name to the appropriate parameters in the SQL query without any extra code. However, we have to use GetInsertCommand(true), etc. so that the commands use the column names (see code below where I show how to use SqlCommandBuilder. There are a few gotchas, however as I've discovered in testing:

  • You need to set the DataKeyNames of your GridView
  • You'll need to set OldValuesParameterFormatString="Original_{0}" on your sqlDS.
  • You'll need scb.ConflictOption = System.Data.ConflictOption.OverwriteChanges; on your SqlCommandBuilder if you want to just update without comparing old values.
  • It appears that if you are populating Select/Update/DeleteCommand on a SqlDataSource programmatically, you have to do it on every postback.

However, in case you need to customize, the SqlDataSource control provides the events Inserting, Updating, Deleting that you can use to populate the parameters before the SQL actions are taken on the database:

sqlDS.Updating += new SqlDataSourceCommandEventHandler(sqlDS_Updating);

protected void sqlDS_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
    e.Command.Parameters["@Name"].Value = // retrieve value from user entry
}

The same kind of thing can be done in the Inserting and Deleting events via the e.Command.Parameters[...] access.


Note that you can also generate the appropriate Delete/Insert/Update command automatically using the SqlCommandBuilder class so that you don't have to build a giant switch statement containing all of your tables. Here's an example:

string tableName = ddl.SelectedValue;
string connectionString = ConfigurationManager
    .ConnectionStrings["MyConnectionString"].ConnectionString;
string select = "SELECT * FROM [" + tableName + "]";
SqlDataAdapter sda = new SqlDataAdapter(select, connection);
SqlCommandBuilder scb = new SqlCommandBuilder(sda);

sqlDS.SelectCommand = select;
sqlDS.InsertCommand = scb.GetInsertCommand(true).CommandText;
sqlDS.UpdateCommand = scb.GetUpdateCommand(true).CommandText;
sqlDS.DeleteCommand = scb.GetDeleteCommand(true).CommandText;

This will of course require that all of your tables have primary keys that can be used to generate the relevant update and delete statements. If not, you will get an exception about dynamic SQL generation. Even if you don't like this method because of the run-time cost of looking up the schema on the database engine, you could always pre-generate them all with a T4 template instead of typing them all in by hand.

ASP.NET / VS2010 Finding unused files in project

7 votes

Folks, is there any smart way to easily find unused files in entire solution? My project was consolidated by previous developer and it gained size at least 3x. I'd like to shrink the size of project but I cannot find quick and easy way. Any advices?

This open source project might be a good place to start. It's meant to filter out unused images, but it should be pretty easy to change so it looks for unused files.

Find unused images in VS Web Projects

Intersection of two string array (ignore case)

7 votes
string[] array1 = {"Red","blue", "green","black"};
string[] array2 = {"BlUe","yellow", "black"};

I need only matching strings in array(Ignore case)

Result should be

**string[] result  = {"blue","black"} or {"BlUe", "black"};**

How about an Enumerable.Intersect and StringComparer combo:

// other options include StringComparer.CurrentCultureIgnoreCase
// or StringComparer.InvariantCultureIgnoreCase
var results = array1.Intersect(array2, StringComparer.OrdinalIgnoreCase);

Is checking rows affected count after database action (insert, update, delete) overkill?

7 votes

Lately in apps I've been developing I have been checking the number of rows affected by an insert, update, delete to the database and logging an an error if the number is unexpected. For example on a simple insert, update, or delete of one row if any number of rows other than one is returned from an ExecuteNonQuery() call, I will consider that an error and log it. Also, I realize now as I type this that I do not even try to rollback the transaction if that happens, which is not the best practice and should definitely be addressed. Anyways, here's code to illustrate what I mean:

I'll have a data layer function that makes the call to the db:

public static int DLInsert(Person person)
{
    Database db = DatabaseFactory.CreateDatabase("dbConnString");

    using (DbCommand dbCommand = db.GetStoredProcCommand("dbo.Insert_Person"))
    {
        db.AddInParameter(dbCommand, "@FirstName", DbType.Byte, person.FirstName);
        db.AddInParameter(dbCommand, "@LastName", DbType.String, person.LastName);
        db.AddInParameter(dbCommand, "@Address", DbType.Boolean, person.Address);

        return db.ExecuteNonQuery(dbCommand);
    }
}

Then a business layer call to the data layer function:

public static bool BLInsert(Person person)
{
    if (DLInsert(campusRating) != 1)
    {
        // log exception
        return false;
    }

    return true;
}

And in the code-behind or view (I do both webforms and mvc projects):

if (BLInsert(person))
{
    // carry on as normal with whatever other code after successful insert
}
else
{
    // throw an exception that directs the user to one of my custom error pages
}

The more I use this type of code, the more I feel like it is overkill. Especially in the code-behind/view. Is there any legitimate reason to think a simple insert, update, or delete wouldn't actually modify the correct number of rows in the database? Is it more plausible to only worry about catching an actual SqlException and then handling that, instead of doing the monotonous check for rows affected every time?

Thanks. Hope you all can help me out.


UPDATE

Thanks everyone for taking the time to answer. I still haven't 100% decided what setup I will use going forward, but here's what I have taken away from all of your responses.

  • Trust the DB and .Net libraries to handle a query and do their job as they were designed to do.
  • Use transactions in my stored procedures to rollback the query on any errors and potentially use raiseerror to throw those exceptions back to the .Net code as a SqlException, which could handle these errors with a try/catch. This approach would replace the problematic return code checking.

Would there be any issue with the second bullet point that I am missing?

I guess the question becomes, "Why are you checking this?" If it's just because you don't trust the database to perform the query, then it's probably overkill. However, there could exist a logical reason to perform this check.

For example, I worked at a company once where this method was employed to check for concurrency errors. When a record was fetched from the database to be edited in the application, it would come with a LastModified timestamp. Then the standard CRUD operations in the data access layer would include a WHERE LastMotified=@LastModified clause when doing an UPDATE and check the record modified count. If no record was updated, it would assume a concurrency error had occurred.

I felt it was kind of sloppy for concurrency checking (especially the part about assuming the nature of the error), but it got the job done for the business.

What concerns me more in your example is the structure of how this is being accomplished. The 1 or 0 being returned from the data access code is a "magic number." That should be avoided. It's leaking an implementation detail from the data access code into the business logic code. If you do want to keep using this check, I'd recommend moving the check into the data access code and throwing an exception if it fails. In general, return codes should be avoided.

Edit: I just noticed a potentially harmful bug in your code as well, related to my last point above. What if more than one record is changed? It probably won't happen on an INSERT, but could easily happen on an UPDATE. Other parts of the code might assume that != 1 means no record was changed. That could make debugging very problematic :)

Composite Web Client Guidance

6 votes

Good day,

I was wondering if you could perhaps help me,

I was reading the guidance associated with the following: Composite Web Guidance

I was reading through the section titled "Define the Solution Structure for a Modular Web Application", particularily the section "Multiple-Project Modules". I seem to understand the basic concepts surrounding this, however I can't seem to figure out a reasonable way to allow this to work with my web forms in seperate projects.

I realise design time support for masterpages will not be supported here, my question however is how to use something like unity (or another container) to allow me to deploy my projects (which include web form pages and code behind files) as completely independent into a folder and plug them into a solution, the guidance seems a bit unclear as to how to support this and whenever I attempt to import these modules I get run time errors. I've had this working successfully with MVC by exporting the controllers. I would appreciate your support, however I realise that you are an extremely busy people. If you could perhaps link me to a blog or a resource explaining this in detail I would be forever greatful. Thank you for taking the time to read this. To summarise I wish to achieve the following.

  1. Create my web shell project using asp.net web forms (without silverlight or any client technology)
  2. Create my modules which exist inside their own projects, which contain my aspx and aspx code behing pages as well as any dependent assemblies
  3. I wish these pages to be exportable and importable by my shell.
  4. If possible I'd like my module assemblies to be within their own folders as to not muddy my solution.

I've done something similar a while back with regards to a plugin-type system where the plugins where pages and controls but were stored in separate assemblies.

What we ended up doing was this:

Register a custom VirtualPathProvider on Application_Start:

void Application_Start(object sender, EventArgs e)
{
    System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(
        new YourCustomVirtualPathProvider());
}

Override the necessary methods in the VirtualPathProvider (based on your logic):

public class YourCustomVirtualPathProvider : System.Web.Hosting.VirtualPathProvider
{
    private const string RESERVED_PATH = "/components/external";
    public override bool FileExists(string virtualPath)
    {
        if (virtualPath.StartsWith(RESERVED_PATH))
            return true;
        else
            return base.FileExists(virtualPath);
    }

    public override VirtualFile GetFile(string virtualPath)
    {
        if (virtualPath.StartsWith(RESERVED_PATH))
            return new MyCustomVirtualFile(virtualPath);
        else
            return base.GetFile(virtualPath);
    }

    //You'll also need to override methods for directories, omitted for brevity.
}

Now create the MyCustomVirtualFile class to load the files from an assembly:

public class MyCustomVirtualFile : System.Web.Hosting.VirtualFile
{
    private string _virtualPath;
    public MyCustomVirtualFile(string virtualPath) { _virtualPath = virtualPath }

    public override System.IO.Stream Open()
    {
        //You'll need some method to tie a virtual path to an assembly
        //Then load the file from the assembly and return as a Stream
        Assembly assembly = Foo.GetAssemblyByVirtualPath(_virtualPath);
        string fileName = Foo.GetFileNameFromVirtualPath(_virtualPath);
        return assembly.GetManifestresourceStream(fileName);
    }
}

The ASPX/ASCX or resource files you want to load this way will have to be added as an embedded resource to the assembly. You can do this by changing the "Build Action" property of the file:

properties dialogue

The code behinds will be compiled into the assembly, and if you're using a shared bin folder, you shouldn't need to do anything more. If they won't be shared, you'll have to attach to the AssemblyResolve and TypeResolve events in the global application (more on this here).

We eventually scrapped this idea because of security concerns, and ended up going with MEF data contracts but if all of your other assemblies are first party, then this should be quick and easy. Hope this helps.

IE8 Compatibility Mode Asp.net Menu Padding issue

6 votes

Im having an issue with an ASP.net vertical menu, where in certain IE8 modes and other IE browsers, it changes my menu item to have an extra space at the bottom of each menu item, as shown below.

(bad on left, good on right). this is only IE.

bad ___________ good

i did a margin: -1px; for bottom and top and got the following and still adds the space, as shown below.

enter image description here

here is my CSS:

 .SideStaticMenuStyle a, 
 .SideStaticMenuStyle a:visited,
 .SideStaticMenuStyle a:active
 {
    color: #000000;     
    text-decoration: none;
    font-weight: normal;
    font-family: verdana;
    font-size: 12px;
    white-space:normal;
 }
 .SideStaticMenuStyle a:hover 
{
    color: #ffffff;     
    text-decoration: none;
    font-size: 12px;        
    font-weight: normal;
    font-family:  verdana;
 }

 .SideStaticMenuStyle td
 {
    background-color: #c2d0e9;
    width: 160px;
    line-height:14px;
 }

 .SideStaticSelectedStyle td,
 .SideStaticSelectedStyle a, 
 .SideStaticSelectedStyle a:visited,
 .SideStaticSelectedStyle a:active,
 .SideStaticSelectedStyle a:hover
 {
color: #ffffff;     
text-decoration: none;
font-weight: bold;
font-family: verdana;
font-size: 11px;
white-space:normal;
background-color: #6C85B0;
 }

 .SideStaticHoverStyle td
 {
    font-weight: normal;
    font-family:  verdana;
    background-color: #6c85b0;
    color: #ffffff;
}
 .SideStaticHoverStyle td:hover a 
 {
           color: #ffffff;
      }

 .SideStaticMenuItemStyle
 {
    font-weight: normal;
    font-family:  verdana;
    border-bottom: solid 1px #012754;
    border-left: solid 1px #012754;
    border-right: solid 1px #012754;
     border-collapse:collapse;
 }
 .SideStaticMenuItemStyle td
 {      
    padding: 2px 2px 2px 3px;
    text-align: left;
    font-weight: normal;
    font-family:  verdana;
  }
 .SideStaticHoverStyle
 {
    font-weight: normal;
    font-family: verdana;
 }

Here is my HTML:

<asp:Menu ID="Menu2" runat="server"  Orientation="Vertical" ItemWrap="true">
            <DataBindings>
                <asp:MenuItemBinding DataMember="MenuItem" TextField="Title" NavigateUrlField="URL" />
            </DataBindings>
            <StaticMenuStyle CssClass="SideStaticMenuStyle" />
            <StaticSelectedStyle CssClass="SideStaticSelectedStyle" ItemSpacing="0px" />
            <StaticMenuItemStyle CssClass="SideStaticMenuItemStyle" ItemSpacing="0px" />
            <DynamicHoverStyle CssClass="SideDynamicHoverStyle" />
            <DynamicMenuStyle CssClass="SideDynamicMenuStyle" />
            <DynamicSelectedStyle CssClass="SideDynamicSelectedStyle" />
            <DynamicMenuItemStyle CssClass="SideDynamicMenuItemStyle" />
            <StaticHoverStyle CssClass="SideStaticHoverStyle" />
        </asp:Menu>

Page Generate Code:

   <table id="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2" class="SideStaticMenuStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_5 ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_2" cellpadding="0" cellspacing="0" border="0">
    <tr onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(this)" id="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2n1">
        <td><table class="SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_4" cellpadding="0" cellspacing="0" border="0" width="100%">
            <tr>
                <td style="width:100%;"><a class="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_1 SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_3" href="servicelink.aspx" target="_self" style="border-style:none;font-size:1em;">ServiceLink</a></td>
            </tr>
        </table></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr><tr onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(this)" id="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2n2">
        <td><table class="SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_4" cellpadding="0" cellspacing="0" border="0" width="100%">
            <tr>
                <td style="width:100%;"><a class="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_1 SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_3" href="fnpc.aspx" target="_self" style="border-style:none;font-size:1em;">Fidelity National Property and Casualty</a></td>
            </tr>
        </table></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr><tr onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(this)" id="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2n3">
        <td><table class="SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_4" cellpadding="0" cellspacing="0" border="0" width="100%">
            <tr>
                <td style="width:100%;"><a class="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_1 SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_3" href="ceridiancorp.aspx" target="_self" style="border-style:none;font-size:1em;">Ceridian Corporation</a></td>
            </tr>
        </table></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr><tr onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(this)" id="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2n4">
        <td><table class="SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_4" cellpadding="0" cellspacing="0" border="0" width="100%">
            <tr>
                <td style="width:100%;"><a class="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_1 SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_3" href="remy.aspx" target="_self" style="border-style:none;font-size:1em;">Remy International, Inc.</a></td>
            </tr>
        </table></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr><tr onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(this)" id="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2n5">
        <td><table class="SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_4" cellpadding="0" cellspacing="0" border="0" width="100%">
            <tr>
                <td style="width:100%;"><a class="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_1 SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_3" href="abrh.aspx" target="_self" style="border-style:none;font-size:1em;">American Blue Ribbon Holdings, LLC</a></td>
            </tr>
        </table></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr><tr onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(this)" id="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2n6">
        <td><table class="SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_4" cellpadding="0" cellspacing="0" border="0" width="100%">
            <tr>
                <td style="width:100%;"><a class="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_1 SideStaticMenuItemStyle ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_3" href="cascade.aspx" target="_self" style="border-style:none;font-size:1em;">Cascade Timberlands</a></td>
            </tr>
        </table></td>
    </tr><tr style="height:0px;">
        <td></td>
    </tr>
</table><a id="ctl00_ContentPlaceHolder1_ctl00_ctl06_ctl00_Menu2_SkipLink"></a>
    </td>

The problem is in the markup of your <asp:Menu /> control. ItemSpacing="0" on the <StaticMenuItemStyle /> is what creates those extra <tr /> tags. Remove it and they will be gone:

<asp:Menu ID="Menu2" runat="server"  Orientation="Vertical" ItemWrap="true">
    <DataBindings>
        <asp:MenuItemBinding DataMember="MenuItem" TextField="Title" NavigateUrlField="URL" />
    </DataBindings>
    <StaticMenuStyle CssClass="SideStaticMenuStyle" />
    <StaticSelectedStyle CssClass="SideStaticSelectedStyle" />
    <StaticMenuItemStyle CssClass="SideStaticMenuItemStyle" />
    <DynamicHoverStyle CssClass="SideDynamicHoverStyle" />
    <DynamicMenuStyle CssClass="SideDynamicMenuStyle" />
    <DynamicSelectedStyle CssClass="SideDynamicSelectedStyle" />
    <DynamicMenuItemStyle CssClass="SideDynamicMenuItemStyle" />
    <StaticHoverStyle CssClass="SideStaticHoverStyle" />
</asp:Menu>

Here's a screen shot of my local machine where I show it fixed:

enter image description here

Location of the ASP.NET Cache

6 votes

How/where is the ASP.NET cache managed in IIS 7? I know that it's stored in the server's memory, but what is the process that manages it? Is it in the address space of w3wp.exe, or is it in another process/location? And does Session data use the cache, or does Session work differently?

You configure where Session data gets stored in your web.config with the sessionState element. If set to InProc, it will be stored in memory in the w3wp.exe process that corresponds to your application's App Pool. You could also, for example, store it in a SQL Server instance.

If that element isn't defined in your config file, check out the machine level web.config for your target framework version / architecture.

Error message Nullable object must have a value

6 votes

I have a null error on my DTO object at runtime:

enter image description here

I didn't understand because column is nullable:

[DataContract]
public class SearchParametersCompanyDTO
{
    public SearchParametersCompanyDTO();

    [DataMember]
    public CompanyColumnsEnumDTO? Column { get; set; }
    [DataMember]
    public int PageIndex { get; set; }
    [DataMember]
    public int PageSize { get; set; }
    [DataMember]
    public string Term { get; set; }
}

[DataContract]
public enum CompanyColumnsEnumDTO
{
    [EnumMember]
    CompanyName = 0,
    [EnumMember]
    City = 1,
    [EnumMember]
    PostCode = 2,
}

It must be a conversion problem because null is accepted on Column:

        var dto = new SearchParametersCompanyDTO
        {
            PageIndex = pageIndex,
            PageSize = defaultPageSize,
            Term = term,
            Column = null
        };

Any idea?

You're trying to cast a null value to an enum type (rather than a nullable enum type). I'm guessing you actually want to change your cast to:

Column = (CompanyColumnsEnumDTO?) column

Why doesn't this string format as currency?

5 votes

I have the following line:

//Send Email
clntMailBody = clntMailBody + "Order Total: " + String.Format("{0:C}", strOrderTotal + "\n");

Watch shows:

String.Format("{0:C}", strOrderTotal + "\n")    "35\n"  string

But it only outputs "35". I expected "$35.00" Why is this not working as intended?

Thanks

I'm guessing strOrderTotal is a string? I think {0:C} only works for decimal or int types.

how to deploy MVC3 WebApp to windows Azure

5 votes

How is it possible to deploy MVC3 web roles to windows Azure? Most of the tutorials seems done on deploying ASP.NET web roles than the MVC3 one.

can any one give me a link/hint?

Way back in the old days, MVC3 wasn't supported out-of-the-box because the appropriate DLLs needed to be manually added by you (or installed as a startup task). These days, the MVC dll's are all there using the MVC3 template, so there's no difference in what you'd need to do, between asp.net and asp.net mvc deployment. The basic Web Roles and Worker roles are just Windows 2008 Server VMs, and the deployment process is the same. The most important part, when starting out, is making sure your connection strings to storage point to "real" storage and not dev storage (such as your diagnostics connection string). Also, session state defaults to using SQLExpress, which isn't running in Windows Azure, so you'll need to either use a SQL Azure database (plus proper connection string) in web.config, or change session state to use Cache (again, a web.config change).

Does RegisterStartupScript increase page size

4 votes

I'm using this code in a page:

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Timer ID="timer" Interval="4000" runat="server" OnTick="timer_Tick" />

<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:Panel ID="pnlAlarm" runat="server" CssClass="pnlAlarm" ClientIDMode="Static">
            <div id="Alarm">
                <asp:Label ID="lblContent" runat="server" Text="Updating" CssClass="AlarmLogo"></asp:Label>
                    ClientIDMode="Static" />
            </div>
        </asp:Panel>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="timer" />
    </Triggers>
</asp:UpdatePanel>

and in code behind I use this simple code:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        Session["nima"] = 1;
    }
}
protected void timer_Tick(object sender, EventArgs e)
{
    int i = int.Parse(Session["nima"].ToString());
    if (i==3)
    {
        lblContent.Text = i.ToString();
        ScriptManager.RegisterStartupScript(this, GetType(), "AlarmMessage", "$('#pnlAlarm').slideToggle();", true);
        Session["nima"] = 0;
    }
    else
    {
        i = i + 1;
        Session["nima"] = i;
    }
}

I want to know every time that I use RegisterStartupScript , $('#pnlAlarm').slideToggle(); add to my page and increase my page size?

thanlks

By definition, that method will:

register a startup script block that is included every time that an asynchronous postback occurs.

So yes, it will be included, and therefore increase your page size.

msdn ScriptManager.RegisterStartupScript Method

Difference Between Static or NoneStatic Methods in ASP.NET MVC

4 votes

I need a method that return me some parameters in controllers this is implementation of it:

    public List<Parameter> GetParameters(FormCollection collection) {

        List<Parameter> parameters = new List<Parameter>();
        List<string> parameterNames = new List<string>();

        //Get Parameters Names and Values

        return parameters;
    }

I use this method in all of controllers, So I think about 3 option that I have to define it:

1-For any controller class define it in that controller like this:

public class ProductController : Controller {

   public List<Parameter> GetParameters(FormCollection collection) {

   //

    }
  }

2-Define it in static class as static method:

public static class GeneralMethods {

   public static List<Parameter> GetParameters(FormCollection collection) {

   //

    }
  }

3-Define it as a None Static :

public class GeneralMethods {

   public List<Parameter> GetParameters(FormCollection collection) {

   //

    }
  }

which one is better? which one have better performance? or any other option for define methods that used in many controllers? what is your suggestion?

There will be no performance impact in any of the three. (Though last approach will create separate object each time,it will be gracefully handled by GC).

approach 1: NO, as a standard practice we should not duplicate the code.

approach 2: YES, if your method depends only on the input parameter.

approach 3: YES, if you need to set up some instance variable and your method depends on them.

suggested approach: (approach 1+ approach 3) If this method is common to all of your controller (or most), declare a base controller with this method and inherit all other controller from it.

Static methods will not be a problem as any variable declared with in a method are with in scope of the method.

Entity Framework 4 (using EDMX), how to add a field into to model that DB does not have the field actually

4 votes

I need to add a field into model that Database does not have the field actually.

Because, firstly I tried to add the field into Entity class only.

public partial class Weborder
{
  (Auto Generated)
  public int orderno {get; set;}
  .
  .
  .
  (Add Manually)
  public string newField1 {get; set;} //this is new field that DB does not have
  public string newField2 {get; set;} //this is new field that DB does not have
}

and later, when I update EDXM then EDMX remove the new fields because the database does not have the field. :(

So I add the field into EDMX model manually. (Add -> Scalar Property)

then an error occur while compiling, the error message say :

Error   1   Error 3004: Problem in mapping fragments starting at line 399:No mapping specified for properties ...
An Entity with Key (PK) will not round-trip when:...

Anybody know how to add new fields into entity class ?

Thank you!

EDITED FOR : If your model is a representation of your database and in the database you don't have the field, why do you want to add it manually?

=>

When retrieve data, the return type of object is the entity class.

and before passing data from controller to view, I need to add more data(fields) into the IQueryable result.

ex)

public DbSet<WEBORDERLN> WEBORDERLNs { get; set; }

//repository
public IQueryable<WEBORDERLN> WebOrderLns
{
      get { return context.WEBORDERLNs; }
}

and now I get the weborderln data in controller. and before passing view, I need to

add extra data into the result.

var data = webOrderLnRepository.WebOrderLns.Where(e => e.PICKNO == OrderNo).ToList();

foreach (WEBORDERLN weborderln in data)
{
   weborderln.[NEW FIELD] = "EXTRA DATA";   //// FOR THIS, I NEED TO ADD NEW FILED INTO ENTITY CLASS
}

//return data

I hope it could explain the question :)

Thanks again.

You must create a new partial part of your entity class (in the new .cs file) and add new fields to that class. You must not modify the partial part created by autogeneration because autogenerated files will be overwritten every time you change EDMX file. You also must not include the field in EDMX because EDMX defines your mapping to database = it contains only fields in database.

Create a new file WebOrderPart.cs in the same assembly and namespace as your autogenerated classes containing:

public partial class Weborder
{
  public string newField1 {get; set;} 
  public string newField2 {get; set;} 
}