ASP.NET is an open-source server-side web application framework that was developed by Microsoft. It is mostly used for building dynamic websites and applications. It is free and a cross-platform framework. So, today we will be checking out the 11 most asked ASP.NET questions.
Answer:
includes a Flurl
Url.Combine
. Url.Combine is basically a Path.Combine for URLs, ensuring one and only one separator character between parts:
var url = Url.Combine(
"http://MyUrl.com/",
"/too/", "/many/", "/slashes/",
"too", "few?",
"x=1", "y=2"
// result: "http://www.MyUrl.com/too/many/slashes/too/few?x=1&y=2"
Get Flurl.Http on NuGet:
PM> Install-Package Flurl.Http
Or get the stand-alone URL builder without the HTTP features:
PM> Install-Package Flurl
Alternative Answer:
has a constructor that should do this for you: Uri
new Uri(Uri baseUri, string relativeUri)
. Here’s an example:
Uri baseUri = new Uri("http://www.contoso.com");
Uri myUri = new Uri(baseUri, "catalog/shownew.htm");
Note: Beware, this method does not work as expected. It can cut part of baseUri in some cases.
Answer:
If you are using IIS for hosting your application, then the default upload file size if 4MB. To increase it, please use this below section in your web.config–
<configuration>
<system.web>
<httpRuntime maxRequestLength="1048576" />
</system.web>
</configuration>
For IIS7 and above, you also need to add the lines below:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>
Note:
maxRequestLength
is measured in kilobytesmaxAllowedContentLength
is measured in byteswhich is why the values differ in this config example. (Both are equivalent to 1 GB)
Alternative Answer:
Go to web.config.
In
system.web
<httpRuntime maxRequestLength="1048576" executionTimeout="3600" />
And in
system.webServer
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
Note: Both of these values must match. In this case, the max upload is 1024 megabytes. maxRequestLength has 1048576 KILOBYTES, and maxAllowedContentLength has 1073741824 BYTES.
Answer:
Website:
The Web Site project is compiled on the fly. You end up with a lot more DLL files, which can be a pain. It also gives problems when you have pages or controls in one directory that need to reference pages and controls in another directory since the other directory may not be compiled into the code yet. Another problem can be in publishing.
If Visual Studio isn’t told to re-use the same names constantly, it will come up with new names for the DLL files generated by pages all the time. That can lead to having several close copies of DLL files containing the same class name, which will generate plenty of errors. The Web Site project was introduced with Visual Studio 2005, but it has turned out not to be popular.
Web Application:
The Web Application Project was created as an add-in and now exists as part of SP 1 for Visual Studio 2005. The main differences are, the Web Application Project was designed to work similarly to the Web projects that shipped with Visual Studio 2003. It will compile the application into a single DLL file at build time. In order to update the project, it must be recompiled and the DLL file published for changes to occur.
Another nice feature of the Web Application project is it’s much easier to exclude files from the project view. In the Web Site project, each file that you exclude is renamed with an excluded keyword in the filename. In the Web Application Project, the project just keeps track of which files to include/exclude from the project view without renaming them, making things much tidier.
The article ASP.NET 2.0 – Web Site vs Web Application project also gives reasons on why to use one and not the other. Here is an excerpt of it:
You need to migrate large Visual Studio .NET 2003 applications to VS 2005? use the Web Application project.
You want to open and edit any directory as a Web project without creating a project file? use Web Site project.
You need to add pre-build and post-build steps during compilation? use Web Application project.
You need to build a Web application using multiple Web projects? use Web Application project.
You want to generate one assembly for each page? use Web Site project.
You prefer dynamic compilation and working on pages without building entire site on each page view? use Web Site project.
You prefer single-page code model to code-behind model? use Web Site project.
Web Application Projects versus Web Site Projects (MSDN) explains the differences between the web site and web application projects. Also, it discusses the configuration to be made in Visual Studio.
Additional Answer:
Web Site is what you deploy to an ASP.NET web server such as IIS. Just a bunch of files and folders. There’s nothing in a Web Site that ties you to Visual Studio (there’s no project file). Code-generation and compilation of web pages (such as .aspx, .ascx, .master) are done dynamically at runtime, and changes to these files are detected by the framework and utomatically re-compiled. You can put code that you want to share between pages in the special App_Code folder, or you can pre-compile it and put the assembly in the Bin folder.
Web Application is a special Visual Studio project. The main difference with Web Sites is that when you build the project all the code files are compiled into a single assembly, which is placed in the bin directory. You don’t deploy code files to the web server. Instead of having a special folder for shared code files, you can put them anywhere, just like you would do in a class library. Because Web Applications contains files that are not meant to be deployed, such as project and code files, there’s a Publish command in Visual Studio to output a Web Site to a specified location.
App_Code vs Bin
Deploying shared code files is generally a bad idea, but that doesn’t mean you have to choose Web Application. You can have a Web Site that references a class library project that holds all the code for the Web Site. Web Applications are just a convenient way to do it.
CodeBehind
This topic is specific to .aspx and .ascx files. This topic is decreasingly relevant in new application frameworks such as ASP.NET MVC and ASP.NET Web Pages which do not use codebehind files.
By having all code files compiled into a single assembly, including codebehind files of .aspx pages and .ascx controls, in Web Applications, you have to re-build for every little change, and you cannot make live changes. This can be a real pain during development, since you have to keep re-building to see the changes, while with Web Sites changes are
detected by the runtime, and pages/controls are automatically
recompiled.
Having the runtime manage the codebehind assemblies is less work for you, since you don’t need to worry about giving pages/controls unique names, or organizing them into different namespaces.
It doesn’t mean deploying code files is always a good idea (especially not in the case of shared code files), but codebehind files should only contain code that performs UI specific tasks, wire-up events handlers, etc. Your application should be layered so that important code always ends up in the Bin folder. If that is the case then deploying codebehind files shouldn’t be considered harmful.
Another limitation of Web Applications is that you can only use the language of the project. In Web Sites you can have some pages in C#, some in VB, etc. No need for special Visual Studio support. That’s the beauty of the build provider extensibility.
Also, in Web Applications, you don’t get error detection in pages/controls as the compiler only compiles your codebehind classes and not the markup code (in MVC you can fix this using the MvcBuildViews option), which is compiled at runtime.
Visual Studio
Because Web Applications are Visual Studio projects you get some features not available in Web Sites. For instance, you can use build events to perform a variety of tasks, e.g. minify and/or combine Javascript files.
Another nice feature introduced in Visual Studio 2010 is Web.config transformation. Now works with Web Sites in VS 2013.
Building a Web Application is faster than building a Web Site, especially for large sites. This is mainly because Web Applications do not compile the markup code. In MVC if you set MvcBuildViews to true then it compiles the markup code and you get error detection, which is very useful. The downside is that every time you build the solution it builds the complete site, which can be slow and inefficient, especially if you are not editing the site. We find ourselves turning MvcBuildViews on and off (which requires a project unload). On the other hand, with Web Sites, you can choose if you want to build the site as part of the solution or not. If you choose not to,
then building the solution is very fast, and you can always click on the
Web Site node and select Build if you’ve made changes.
In an MVC Web Application project, you have extra commands and dialogs for common tasks, like ‘Add View’, ‘Go To View’, ‘Add Controller’, etc. These are not available in an MVC Web Site. If you use IIS Express as the development server, in Web Sites you can add virtual directories. This option is not available in Web Applications.
Package Restore now works with Web Sites starting NuGet 2.7.
Answer:
You can use:
@using MyNamespace
For VB.Net:
@Imports Mynamespace
Alternative Answer:
The first way is that use
@using
statement in .cshtml
files, that imports a namespace to the current file only, and the second: In the “web.config” file in “
Views
” directory of your project (notice it is not the main web.config in project’s root), find this section:<system.web.webPages.razor>
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
.
.
<!-- etc -->
</namespaces>
</pages>
</system.web.webPages.razor>
you can add your custom namespace like this:
<add namespace="My.Custom" />
that will add the namespace to all of .cshtml (and/or .vbhtml) files; also you can change views inheritance from here, like:
<pages pageBaseType="My.Custom.MyWebViewPage">
If you’re working within an area, you must add the
namespace
within the Web.config
under /Areas/<AreaName>/Views/
rather than /Views/
Answer:
For MVC v5.1, use Html.EnumDropDownListFor
@Html.EnumDropDownListFor(
x => x.YourEnumField,
"Select My Type",
new { @class = "form-control" })
For MVC v5, use EnumHelper
@Html.DropDownList("MyType",
EnumHelper.GetSelectList(typeof(MyType)) ,
"Select My Type",
new { @class = "form-control" })
For MVC 5 and lower
@Html.DropDownList("MyType",
EnumHelper.GetSelectList(typeof(MyType)) ,
"Select My Type",
new { @class = "form-control" })
This allows you to write:
ViewData["taskStatus"] = task.Status.ToSelectList();
by using
MyApp.Common
Alternative Answer:
You might also find this variant useful, as this one also allows you to use descriptive strings rather than enumeration constants in the dropdown. To do this, decorate each enumeration entry with a [System.ComponentModel.Description] attribute.
For example:
public enum TestEnum
{
[Description("Full test")]
FullTest,
[Description("Incomplete or partial test")]
PartialTest,
[Description("No test performed")]
None
}
Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Reflection;
using System.ComponentModel;
using System.Linq.Expressions;
...
private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
Type realModelType = modelMetadata.ModelType;
Type underlyingType = Nullable.GetUnderlyingType(realModelType);
if (underlyingType != null)
{
realModelType = underlyingType;
}
return realModelType;
}
private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } };
public static string GetEnumDescription<TEnum>(TEnum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if ((attributes != null) && (attributes.Length > 0))
return attributes[0].Description;
else
return value.ToString();
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
return EnumDropDownListFor(htmlHelper, expression, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumType = GetNonNullableModelType(metadata);
IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
IEnumerable<SelectListItem> items = from value in values
select new SelectListItem
{
Text = GetEnumDescription(value),
Value = value.ToString(),
Selected = value.Equals(metadata.Model)
};
// If the enum is nullable, add an 'empty' item to the collection
if (metadata.IsNullableValueType)
items = SingleEmptyItem.Concat(items);
return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
}
You can then do this in your view:
@Html.EnumDropDownListFor(model => model.MyEnumProperty)
Microsoft released MVC 5.1, which now has an EnumDropDownListFor
feature. But, it does not appear to respect the [Description] attribute so the code above still stands. See Enum section in Microsoft’s release notes for MVC 5.1.
It does support the Display attribute
[Display(Name = "Sample")]
though, so one can use that. The code looks like an extended version of the code here: https://blogs.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums/, with a couple of additions. If so, attribution would seem fair.
Answer:
Here’s how to do it. Use IPrincipal instead of IIdentity because it means we don’t have to implement both IIdentity and IPrincipal.
a. Create the interface
interface ICustomPrincipal : IPrincipal
{
int Id { get; set; }
string FirstName { get; set; }
string LastName { get; set; }
}
b. CustomPrincipal
public class CustomPrincipal : ICustomPrincipal
{
public IIdentity Identity { get; private set; }
public bool IsInRole(string role) { return false; }
public CustomPrincipal(string email)
{
this.Identity = new GenericIdentity(email);
}
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
c. CustomPrincipalSerializeModel – for serializing custom information nto userdata field in FormsAuthenticationTicket object.
public class CustomPrincipalSerializeModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
d. LogIn method – setting up a cookie with custom information
if (Membership.ValidateUser(viewModel.Email, viewModel.Password))
{
var user = userRepository.Users.Where(u => u.Email == viewModel.Email).First();
CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
serializeModel.Id = user.Id;
serializeModel.FirstName = user.FirstName;
serializeModel.LastName = user.LastName;
JavaScriptSerializer serializer = new JavaScriptSerializer();
string userData = serializer.Serialize(serializeModel);
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
1,
viewModel.Email,
DateTime.Now,
DateTime.Now.AddMinutes(15),
false,
userData);
string encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
Response.Cookies.Add(faCookie);
return RedirectToAction("Index", "Home");
}
e. Global.asax.cs – Reading cookie and replacing HttpContext.User object, this is done by overriding PostAuthenticateRequest
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
JavaScriptSerializer serializer = new JavaScriptSerializer();
CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);
CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
newUser.Id = serializeModel.Id;
newUser.FirstName = serializeModel.FirstName;
newUser.LastName = serializeModel.LastName;
HttpContext.Current.User = newUser;
}
}
f. Access in Razor views
@((User as CustomPrincipal).Id)
@((User as CustomPrincipal).FirstName)
@((User as CustomPrincipal).LastName)
and in code:
(User as CustomPrincipal).Id
(User as CustomPrincipal).FirstName
(User as CustomPrincipal).LastName
Additionally, to make the access even easier you can create a base controller and override the returned User object (HttpContext.User):
public class BaseController : Controller
{
protected virtual new CustomPrincipal User
{
get { return HttpContext.User as CustomPrincipal; }
}
}
and then, for each controller:
public class AccountController : BaseController
{
// ...
}
which will allow you to access custom fields in code like this:
User.Id
User.FirstName
User.LastName
But this will not work inside views. For that you would need to create a custom WebViewPage implementation:
public abstract class BaseViewPage : WebViewPage
{
public virtual new CustomPrincipal User
{
get { return base.User as CustomPrincipal; }
}
}
public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
{
public virtual new CustomPrincipal User
{
get { return base.User as CustomPrincipal; }
}
}
Make it a default page type in Views/web.config:
public abstract class BaseViewPage : WebViewPage
{
public virtual new CustomPrincipal User
{
get { return base.User as CustomPrincipal; }
}
}
public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
{
public virtual new CustomPrincipal User
{
get { return base.User as CustomPrincipal; }
}
}
and in views, you can access it like this:
@User.FirstName
@User.LastName
Answer:
The RazorGenerator NuGet package is recommended. That way your views have a
.designer.cs
file generated when you save them and on top of getting compile-time errors for your views, they are also precompiled into the assembly (= faster warmup) and Resharper provides some additional help as well. To use this include the RazorGenerator NuGet package in your ASP.NET MVC project and install the “Razor Generator” extension under item under Tools → Extensions and Updates.
We use this and the overhead per compile with this approach is much less. On top of this, we would probably recommend .NET Demon by RedGate which further reduces compile time impact substantially.
Alternative Answer:
From the readme word doc for RC1 (not indexed by Google)
ASP.NET Compiler Post-Build Step
Currently, errors within a view file are not detected until run time. To let you detect these errors at compile-time, ASP.NET MVC projects now include a MvcBuildViews property, which is disabled by default. To enable this property, open the project file and set the MvcBuildViews property to true, as shown in the following example:
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MvcBuildViews>true</MvcBuildViews>
</PropertyGroup>
Note: Enabling this feature adds some overhead to the build time. You can update projects that were created with previous releases of MVC to include build-time validation of views by performing the following steps:
<PropertyGroup>
element: <MvcBuildViews>true</MvcBuildViews>
<Target Name="AfterBuild">
element and modify it to match the following:<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
</Target>
Answer:
Classic mode (the only mode in IIS6 and below) is a mode where IIS only works with ISAPI extensions and ISAPI filters directly. In fact, in this mode, ASP.NET is just an ISAPI extension (aspnet_isapi.dll) and an ISAPI filter (aspnet_filter.dll). IIS just treats ASP.NET as an external plugin implemented in ISAPI and works with it like a black box (and only when it needs to give out the request to ASP.NET). In this mode, ASP.NET is not much different from PHP or other technologies for IIS.
Integrated mode, on the other hand, is a new mode in IIS7 where the IIS pipeline is tightly integrated (i.e. is just the same) as the ASP.NET request pipeline. ASP.NET can see every request it wants to and manipulate things along the way. ASP.NET is no longer treated as an external plugin. It’s completely blended and integrated into IIS. In this mode, ASP.NET HttpModules basically have nearly as much power as an ISAPI filter would have had and ASP.NET HttpHandlers can have the nearly equivalent capability as an ISAPI extension could have. In this mode, ASP.NET is basically a part of IIS.
Alternative Answer:
Integrated application pool mode
When an application pool is in Integrated mode, you can take advantage of the integrated request-processing architecture of IIS and ASP.NET. When a worker process in an application pool receives a request, the request passes through an ordered list of events. Each event calls the necessary native and managed modules to process portions of the request and to generate the response.
There are several benefits to running application pools in Integrated mode. First, the request-processing models of IIS and ASP.NET are integrated into a unified process model. This model eliminates steps that were previously duplicated in IIS and ASP.NET, such as authentication. Additionally, Integrated mode enables the availability of managed features to all content types.
Classic application pool mode
When an application pool is in Classic mode, IIS 7.0 handles requests as in IIS 6.0 worker process isolation mode. ASP.NET requests first go through native processing steps in IIS and are then routed to Aspnet_isapi.dll for processing of managed code in the managed runtime. Finally, the request is routed back through IIS to send the response.
This separation of the IIS and ASP.NET request-processing models results in duplication of some processing steps, such as authentication and authorization. Additionally, managed code features, such as forms authentication, are only available to ASP.NET applications or applications for which you have script mapped all requests to be handled by aspnet_isapi.dll.
Be sure to test your existing applications for compatibility in Integrated mode before upgrading a production environment to IIS 7.0 and assigning applications to application pools in Integrated mode. You should only add an application to an application pool in Classic mode if the application fails to work in Integrated mode. For example, your application might rely on an authentication token passed from IIS to the managed runtime, and, due to the new architecture in IIS 7.0, the process breaks your application.
Original source: Introduction to IIS Architecture
Answer:
Use the base controllers File method.
public ActionResult Image(string id)
{
var dir = Server.MapPath("/Images");
var path = Path.Combine(dir, id + ".jpg"); //validate the path for security or use other means to generate the path.
return base.File(path, "image/jpeg");
}
As a note, this seems to be fairly efficient. We did a test where we requested the image through the controller
(http://localhost/MyController/Image/MyImage)
and through the direct URL (http://localhost/Images/MyImage.jpg)
and the results were:Note: This is the average time of a request. The average was calculated
by making thousands of requests on the local machine, so the totals should not include network latency or bandwidth issues.
Alternative Answer:
Using the release version of MVC:
[AcceptVerbs(HttpVerbs.Get)]
[OutputCache(CacheProfile = "CustomerImages")]
public FileResult Show(int customerId, string imageName)
{
var path = string.Concat(ConfigData.ImagesDirectory, customerId, "\\", imageName);
return new FileStreamResult(new FileStream(path, FileMode.Open), "image/jpeg");
}
Answer:
You’ll want something like this to increase the message size quotas, in the App.config or Web.config file:
<bindings>
<basicHttpBinding>
<binding name="basicHttp" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
</binding>
</basicHttpBinding>
</bindings>
And use the binding name in your endpoint configuration e.g.
...
bindingConfiguration="basicHttp"
...
The justification for the values is simple, they are sufficiently large to accommodate most messages. You can tune that number to fit your needs. The low default value is basically there to prevent DOS type attacks. Making it 20000000 would allow for a distributed DOS attack to be effective, the default size of 64k would require a very large number of clients to overpower most servers these days.
Alternative Answer:
If you’re still getting the error message while using the WCF Test Client, it’s because the client has a separate MaxBufferSize setting.
To correct the issue:
A list of editable settings will appear, including MaxBufferSize.
Note: Auto-generated proxy clients also set MaxBufferSize to 65536 by default.
Answer:
Server.MapPath specifies the relative or virtual path to map to a physical directory.
Server.MapPath(".")
returns the current physical directory of the file (e.g. aspx) being executed.Server.MapPath("..")
returns the parent directory.Server.MapPath("~")
returns the physical path to the root of the application.Server.MapPath("/")
returns the physical path to the root of the domain name (is not necessarily the same as the root of the application).An example:
Let’s say you pointed a web site application
http://www.example.com/)
toC:\Inetpub\wwwroot
and installed your shop application (sub web as a virtual directory in IIS, marked as an application) in
D:\WebApps\shop
For example if you call
Server.MapPath()
in the following request:http://www.example.com/shop/products/GetProduct.aspx?id=2342
then:
Server.MapPath(".")1
returns D:\WebApps\shop\products
Server.MapPath("..")
returns D:\WebApps\shop
erver.MapPath("~")
returns D:\WebApps\shop
erver.MapPath("/")
returns C:\Inetpub\wwwroot
Server.MapPath("/shop")
returns D:\WebApps\shop
If Path starts with either a forward slash (
/
) or backward slash (\
), the MapPath()
returns a path as if Path was a full, virtual path. If Path doesn’t start with a slash, the
MapPath()
returns a path relative to the directory of the request being processed. Note: In C#,
@
is the verbatim literal string operator meaning that the string should be used “as is” and not be processed for escape sequences. In Conclusion
These are the 11 most commonly asked ASP.NET questions. If you have any suggestions or any confusion, please comment below. If you need any
help, we will be glad to help you.
We, at Truemark, provide services like web and mobile app development, digital marketing, and website development. So, if you need any help and want to work with us, please feel free to contact us.
Hope this article helped you.
This post was originally posted on DevPost by Truemark.