This document was uploaded by user and they confirmed that they have the permission to share
it. If you are author or own the copyright of this book, please report to us by using this DMCA
report form. Report DMCA
.NET Framework Conceptual Overview The .NET Framework is an integral Windows component that supports building and running the next generation of applications and XML Web services. The .NET Framework is designed to fulfill the following objectives: •
To provide a consistent object-oriented programming environment whether object code is stored and executed locally, executed locally but Internet-distributed, or executed remotely.
•
To provide a code-execution environment that minimizes software deployment and versioning conflicts.
•
To provide a code-execution environment that promotes safe execution of code, including code created by an unknown or semi-trusted third party.
•
To provide a code-execution environment that eliminates the performance problems of scripted or interpreted environments.
•
To make the developer experience consistent across widely varying types of applications, such as Windows-based applications and Web-based applications.
•
To build all communication on industry standards to ensure that code based on the .NET Framework can integrate with any other code.
The .NET Framework has two main components: the common language runtime and the .NET Framework class library. The common language runtime is the foundation of the .NET Framework. You can think of the runtime as an agent that manages code at execution time, providing core services such as memory management, thread management, and remoting, while also enforcing strict type safety and other forms of code accuracy that promote security and robustness. In fact, the concept of code management is a fundamental principle of the runtime. Code that targets the runtime is known as managed code, while code that does not target the runtime is known as unmanaged code. The class library, the other main component of the .NET Framework, is a comprehensive, object-oriented collection of reusable
types that you can use to develop applications ranging from traditional command-line or graphical user interface (GUI) applications to applications based on the latest innovations provided by ASP.NET, such as Web Forms and XML Web services. The .NET Framework can be hosted by unmanaged components that load the common language runtime into their processes and initiate the execution of managed code, thereby creating a software environment that can exploit both managed and unmanaged features. The .NET Framework not only provides several runtime hosts, but also supports the development of third-party runtime hosts. For example, ASP.NET hosts the runtime to provide a scalable, serverside environment for managed code. ASP.NET works directly with the runtime to enable ASP.NET applications and XML Web services, both of which are discussed later in this topic. Internet Explorer is an example of an unmanaged application that hosts the runtime (in the form of a MIME type extension). Using Internet Explorer to host the runtime enables you to embed managed components or Windows Forms controls in HTML documents. Hosting the runtime in this way makes managed mobile code (similar to Microsoft® ActiveX® controls) possible, but with significant improvements that only managed code can offer, such as semi-trusted execution and isolated file storage. The following illustration shows the relationship of the common language runtime and the class library to your applications and to the overall system. The illustration also shows how managed code operates within a larger architecture. .NET Framework in context
The following sections describe the main components and features of the .NET Framework in greater detail. Features of the Common Language Runtime The common language runtime manages memory, thread execution, code execution, code safety verification, compilation, and other system services. These features are intrinsic to the managed code that runs on the common language runtime. With regards to security, managed components are awarded varying degrees of trust, depending on a number of factors that include their origin (such as the Internet, enterprise network, or local computer). This means that a managed component might or might not be able to perform file-access operations, registry-access operations, or other sensitive functions, even if it is being used in the same active application. The runtime enforces code access security. For example, users can trust that an executable embedded in a Web page can play an animation on screen or sing a song, but cannot access their personal
data, file system, or network. The security features of the runtime thus enable legitimate Internet-deployed software to be exceptionally feature rich. The runtime also enforces code robustness by implementing a strict type-and-code-verification infrastructure called the common type system (CTS). The CTS ensures that all managed code is selfdescribing. The various Microsoft and third-party language compilers generate managed code that conforms to the CTS. This means that managed code can consume other managed types and instances, while strictly enforcing type fidelity and type safety. In addition, the managed environment of the runtime eliminates many common software issues. For example, the runtime automatically handles object layout and manages references to objects, releasing them when they are no longer being used. This automatic memory management resolves the two most common application errors, memory leaks and invalid memory references. The runtime also accelerates developer productivity. For example, programmers can write applications in their development language of choice, yet take full advantage of the runtime, the class library, and components written in other languages by other developers. Any compiler vendor who chooses to target the runtime can do so. Language compilers that target the .NET Framework make the features of the .NET Framework available to existing code written in that language, greatly easing the migration process for existing applications. While the runtime is designed for the software of the future, it also supports software of today and yesterday. Interoperability between managed and unmanaged code enables developers to continue to use necessary COM components and DLLs. The runtime is designed to enhance performance. Although the common language runtime provides many standard runtime services, managed code is never interpreted. A feature called just-in-time (JIT) compiling enables all managed code to run in the native machine language of the system on which it is executing. Meanwhile, the memory manager removes the possibilities of fragmented memory and increases memory locality-of-reference to further increase performance. Finally, the runtime can be hosted by high-performance, server-side applications, such as Microsoft® SQL Server™ and Internet Information Services (IIS). This infrastructure enables you to use managed code to write your business logic, while still enjoying the
superior performance of the industry's best enterprise servers that support runtime hosting. .NET Framework Class Library The .NET Framework class library is a collection of reusable types that tightly integrate with the common language runtime. The class library is object oriented, providing types from which your own managed code can derive functionality. This not only makes the .NET Framework types easy to use, but also reduces the time associated with learning new features of the .NET Framework. In addition, third-party components can integrate seamlessly with classes in the .NET Framework. For example, the .NET Framework collection classes implement a set of interfaces that you can use to develop your own collection classes. Your collection classes will blend seamlessly with the classes in the .NET Framework. As you would expect from an object-oriented class library, the .NET Framework types enable you to accomplish a range of common programming tasks, including tasks such as string management, data collection, database connectivity, and file access. In addition to these common tasks, the class library includes types that support a variety of specialized development scenarios. For example, you can use the .NET Framework to develop the following types of applications and services: •
Console applications. See Building Console Applications.
•
Windows GUI applications (Windows Forms). See Windows Forms.
•
Windows Presentation Foundation (WPF) applications. See Introduction to Windows Presentation Foundation.
•
ASP.NET applications. See Creating ASP.NET Web Pages.
•
Web services. See Creating Web Services in Managed Code.
•
Windows services. See Introduction to Windows Service Applications.
For example, the Windows Forms classes are a comprehensive set of reusable types that vastly simplify Windows GUI development. If you
write an ASP.NET Web Form application, you can use the Web Forms classes.
Common Language Runtime Overview Compilers and tools expose the runtime's functionality and enable you to write code that benefits from this managed execution environment. Code that you develop with a language compiler that targets the runtime is called managed code; it benefits from features such as cross-language integration, cross-language exception handling, enhanced security, versioning and deployment support, a simplified model for component interaction, and debugging and profiling services. To enable the runtime to provide services to managed code, language compilers must emit metadata that describes the types, members, and references in your code. Metadata is stored with the code; every loadable common language runtime portable executable (PE) file contains metadata. The runtime uses metadata to locate and load classes, lay out instances in memory, resolve method invocations, generate native code, enforce security, and set run-time context boundaries. The runtime automatically handles object layout and manages references to objects, releasing them when they are no longer being used. Objects whose lifetimes are managed in this way are called managed data. Garbage collection eliminates memory leaks as well as some other common programming errors. If your code is managed, you can use managed data, unmanaged data, or both managed and unmanaged data in your .NET Framework application. Because language compilers supply their own types, such as primitive types, you might not always know (or need to know) whether your data is being managed. The common language runtime makes it easy to design components and applications whose objects interact across languages. Objects written in different languages can communicate with each other, and their behaviors can be tightly integrated. For example, you can define a class and then use a different language to derive a class from your original class or call a method on the original class. You can also pass an instance of a class to a method of a class written in a different language. This cross-language integration is possible because language compilers and tools that target the runtime use a common type system defined by the runtime, and they follow the runtime's
rules for defining new types, as well as for creating, using, persisting, and binding to types. As part of their metadata, all managed components carry information about the components and resources they were built against. The runtime uses this information to ensure that your component or application has the specified versions of everything it needs, which makes your code less likely to break because of some unmet dependency. Registration information and state data are no longer stored in the registry where they can be difficult to establish and maintain. Rather, information about the types you define (and their dependencies) is stored with the code as metadata, making the tasks of component replication and removal much less complicated. Language compilers and tools expose the runtime's functionality in ways that are intended to be useful and intuitive to developers. This means that some features of the runtime might be more noticeable in one environment than in another. How you experience the runtime depends on which language compilers or tools you use. For example, if you are a Visual Basic developer, you might notice that with the common language runtime, the Visual Basic language has more object-oriented features than before. Following are some benefits of the runtime: •
Performance improvements.
•
The ability to easily use components developed in other languages.
•
Extensible types provided by a class library.
•
New language features such as inheritance, interfaces, and overloading for object-oriented programming; support for explicit free threading that allows creation of multithreaded, scalable applications; support for structured exception handling and custom attributes.
If you use Microsoft® Visual C++® .NET, you can write managed code using Visual C++, which provides the benefits of a managed execution environment as well as access to powerful capabilities and expressive data types that you are familiar with. Additional runtime features include:
•
Cross-language integration, especially cross-language inheritance.
•
Garbage collection, which manages object lifetime so that reference counting is unnecessary.
•
Self-describing objects, which make using Interface Definition Language (IDL) unnecessary.
•
The ability to compile once and run on any CPU and operating system that supports the runtime.
You can also write managed code using the C# language, which provides the following benefits: •
Complete object-oriented design.
•
Very strong type safety.
•
A good blend of Visual Basic simplicity and C++ power.
•
Garbage collection.
•
Syntax and keywords similar to C and C++.
•
Use of delegates rather than function pointers for increased type safety and security. Function pointers are available through the use of the unsafe C# keyword and the /unsafe option of the C# compiler (Csc.exe) for unmanaged code and data.
Managed Execution Process The managed execution process includes the following steps: 1. Choosing a compiler. To obtain the benefits provided by the common language runtime, you must use one or more language compilers that target the runtime.
2. Compiling your code to Microsoft intermediate language (MSIL). Compiling translates your source code into MSIL and generates the required metadata. 3. Compiling MSIL to native code. At execution time, a just-in-time (JIT) compiler translates the MSIL into native code. During this compilation, code must pass a verification process that examines the MSIL and metadata to find out whether the code can be determined to be type safe. 4. Running code. The common language runtime provides the infrastructure that enables execution to take place as well as a variety of services that can be used during execution. Choosing a Compiler To obtain the benefits provided by the common language runtime (CLR), you must use one or more language compilers that target the runtime, such as Visual Basic, C#, Visual C++, JScript, or one of many third-party compilers such as an Eiffel, Perl, or COBOL compiler. Because it is a multilanguage execution environment, the runtime supports a wide variety of data types and language features. The language compiler you use determines which runtime features are available, and you design your code using those features. Your compiler, not the runtime, establishes the syntax your code must use. If your component must be completely usable by components written in other languages, your component's exported types must expose only language features that are included in the Common Language Specification (CLS). You can use the CLSCompliantAttribute attribute to ensure that your code is CLS-compliant. For details, see Writing CLS-Compliant Code. Compiling to MSIL When compiling to managed code, the compiler translates your source code into Microsoft intermediate language (MSIL), which is a CPUindependent set of instructions that can be efficiently converted to
native code. MSIL includes instructions for loading, storing, initializing, and calling methods on objects, as well as instructions for arithmetic and logical operations, control flow, direct memory access, exception handling, and other operations. Before code can be run, MSIL must be converted to CPU-specific code, usually by a just-in-time (JIT) compiler. Because the common language runtime supplies one or more JIT compilers for each computer architecture it supports, the same set of MSIL can be JIT-compiled and run on any supported architecture. When a compiler produces MSIL, it also produces metadata. Metadata describes the types in your code, including the definition of each type, the signatures of each type's members, the members that your code references, and other data that the runtime uses at execution time. The MSIL and metadata are contained in a portable executable (PE) file that is based on and extends the published Microsoft PE and common object file format (COFF) used historically for executable content. This file format, which accommodates MSIL or native code as well as metadata, enables the operating system to recognize common language runtime images. The presence of metadata in the file along with the MSIL enables your code to describe itself, which means that there is no need for type libraries or Interface Definition Language (IDL). The runtime locates and extracts the metadata from the file as needed during execution. Compiling MSIL to Native Code Before you can run Microsoft intermediate language (MSIL), it must be compiled against the common language runtime to native code for the target machine architecture. The .NET Framework provides two ways to perform this conversion: •
A .NET Framework just-in-time (JIT) compiler.
•
The .NET Framework Native Image Generator (Ngen.exe).
Compilation by the Just-in-time Compiler JIT compilation converts MSIL to native code on demand at application run time, when the contents of an assembly are loaded and executed. Because the common language runtime supplies a JIT compiler for each supported CPU architecture, developers can build a set of MSIL assemblies that can be JIT-compiled and run on different computers with different machine architectures. However, your managed code will run only on a specific operating system if it calls platform-specific native APIs, or a platform-specific class library.
JIT compilation takes into account the fact that some code might never get called during execution. Rather than using time and memory to convert all the MSIL in a portable executable (PE) file to native code, it converts the MSIL as needed during execution and stores the resulting native code in memory so that it is accessible for subsequent calls in the context of that process. The loader creates and attaches a stub to each method in a type when the type is loaded and initialized. When a method is called for the first time, the stub passes control to the JIT compiler, which converts the MSIL for that method into native code and modifies the stub to point directly to the generated native code. Subsequent calls to the JIT-compiled method therefore proceed directly to the native code. Install-Time Code Generation Using NGen.exe Because the JIT compiler converts an assembly's MSIL to native code when individual methods defined in that assembly are called, it necessarily involves a performance hit at run time. In most cases, that performance hit is acceptable. More importantly, the code generated by the JIT compiler is bound to the process that triggered the compilation. It cannot be shared across multiple processes. To allow the generated code to be shared across multiple invocations of an application or across multiple processes that share a set of assemblies, the common language runtime supports an ahead-of-time compilation mode. This ahead-of-time compilation mode uses the Native Image Generator (Ngen.exe) to convert MSIL assemblies to native code much like the JIT compiler does. However, the operation of Ngen.exe differs from that of the JIT compiler in three ways: •
It performs the conversion from MSIL to native code before rather than while running the application.
•
It compiles an entire assembly at a time, rather than a method at a time.
•
It persists the generated code in the Native Image Cache as a file on disk.
Code Verification As part of compiling MSIL to native code, the MSIL code must pass a verification process unless an administrator has established a security policy that allows the code to bypass verification. Verification examines MSIL and metadata to find out whether the code is type safe, which means that it only accesses the memory locations it is authorized to access. Type safety helps isolate objects from each other and
therefore helps protect them from inadvertent or malicious corruption. It also provides assurance that security restrictions on code can be reliably enforced. The runtime relies on the fact that the following statements are true for code that is verifiably type safe: •
A reference to a type is strictly compatible with the type being referenced.
•
Only appropriately defined operations are invoked on an object.
•
Identities are what they claim to be.
During the verification process, MSIL code is examined in an attempt to confirm that the code can access memory locations and call methods only through properly defined types. For example, code cannot allow an object's fields to be accessed in a manner that allows memory locations to be overrun. Additionally, verification inspects code to determine whether the MSIL has been correctly generated, because incorrect MSIL can lead to a violation of the type safety rules. The verification process passes a well-defined set of type-safe code, and it passes only code that is type safe. However, some type-safe code might not pass verification because of some limitations of the verification process, and some languages, by design, do not produce verifiably type-safe code. If type-safe code is required by the security policy but the code does not pass verification, an exception is thrown when the code is run.
Running Code The common language runtime provides the infrastructure that enables managed execution to take place as well as a variety of services that can be used during execution. Before a method can be run, it must be compiled to processor-specific code. Each method for which Microsoft intermediate language (MSIL) has been generated is just-in-time-compiled (JIT-compiled) when it is called for the first time, and then run. The next time the method is run, the existing JITcompiled native code is run. The process of JIT-compiling and then executing the code is repeated until execution is complete. During execution, managed code receives services such as garbage collection, security, interoperability with unmanaged code, cross-
language debugging support, and enhanced deployment and versioning support. In Microsoft Windows XP and Windows Vista, the operating system loader checks for managed modules by examining a bit in the common object file format (COFF) header. The bit being set denotes a managed module. If the loader detects managed modules, it loads mscoree.dll, and _CorValidateImage and _CorImageUnloading notify the loader when the managed module images are loaded and unloaded. _CorValidateImage performs the following actions: 1. Ensures that the code is valid managed code. 2. Changes the entry point in the image to an entry point in the runtime. On 64-bit Windows, _CorValidateImage modifies the image that is in memory by transforming it from PE32 to PE32+ format. Automatic Memory Management Automatic memory management is one of the services that the common language runtime provides during Managed Execution. The common language runtime's garbage collector manages the allocation and release of memory for an application. For developers, this means that you do not have to write code to perform memory management tasks when you develop managed applications. Automatic memory management can eliminate common problems, such as forgetting to free an object and causing a memory leak, or attempting to access memory for an object that has already been freed. This section describes how the garbage collector allocates and releases memory. Allocating Memory When you initialize a new process, the runtime reserves a contiguous region of address space for the process. This reserved address space is called the managed heap. The managed heap maintains a pointer to the address where the next object in the heap will be allocated. Initially, this pointer is set to the managed heap's base address. All reference types are allocated on the managed heap. When an application creates the first reference type, memory is allocated for the type at the base address of the managed heap. When the application creates the next object, the garbage collector allocates memory for it in the address space immediately following the first object. As long as address space is available, the garbage collector continues to allocate space for new objects in this manner.
Allocating memory from the managed heap is faster than unmanaged memory allocation. Because the runtime allocates memory for an object by adding a value to a pointer, it is almost as fast as allocating memory from the stack. In addition, because new objects that are allocated consecutively are stored contiguously in the managed heap, an application can access the objects very quickly. Releasing Memory The garbage collector's optimizing engine determines the best time to perform a collection based on the allocations being made. When the garbage collector performs a collection, it releases the memory for objects that are no longer being used by the application. It determines which objects are no longer being used by examining the application's roots. Every application has a set of roots. Each root either refers to an object on the managed heap or is set to null. An application's roots include global and static object pointers, local variables and reference object parameters on a thread's stack, and CPU registers. The garbage collector has access to the list of active roots that the just-in-time (JIT) compiler and the runtime maintain. Using this list, it examines an application's roots, and in the process creates a graph that contains all the objects that are reachable from the roots. Objects that are not in the graph are unreachable from the application's roots. The garbage collector considers unreachable objects garbage and will release the memory allocated for them. During a collection, the garbage collector examines the managed heap, looking for the blocks of address space occupied by unreachable objects. As it discovers each unreachable object, it uses a memorycopying function to compact the reachable objects in memory, freeing up the blocks of address spaces allocated to unreachable objects. Once the memory for the reachable objects has been compacted, the garbage collector makes the necessary pointer corrections so that the application's roots point to the objects in their new locations. It also positions the managed heap's pointer after the last reachable object. Note that memory is compacted only if a collection discovers a significant number of unreachable objects. If all the objects in the managed heap survive a collection, then there is no need for memory compaction. To improve performance, the runtime allocates memory for large objects in a separate heap. The garbage collector automatically releases the memory for large objects. However, to avoid moving large objects in memory, this memory is not compacted. Generations and Performance
To optimize the performance of the garbage collector, the managed heap is divided into three generations: 0, 1, and 2. The runtime's garbage collection algorithm is based on several generalizations that the computer software industry has discovered to be true by experimenting with garbage collection schemes. First, it is faster to compact the memory for a portion of the managed heap than for the entire managed heap. Secondly, newer objects will have shorter lifetimes and older objects will have longer lifetimes. Lastly, newer objects tend to be related to each other and accessed by the application around the same time. The runtime's garbage collector stores new objects in generation 0. Objects created early in the application's lifetime that survive collections are promoted and stored in generations 1 and 2. The process of object promotion is described later in this topic. Because it is faster to compact a portion of the managed heap than the entire heap, this scheme allows the garbage collector to release the memory in a specific generation rather than release the memory for the entire managed heap each time it performs a collection. In reality, the garbage collector performs a collection when generation 0 is full. If an application attempts to create a new object when generation 0 is full, the garbage collector discovers that there is no address space remaining in generation 0 to allocate for the object. The garbage collector performs a collection in an attempt to free address space in generation 0 for the object. The garbage collector starts by examining the objects in generation 0 rather than all objects in the managed heap. This is the most efficient approach, because new objects tend to have short lifetimes, and it is expected that many of the objects in generation 0 will no longer be in use by the application when a collection is performed. In addition, a collection of generation 0 alone often reclaims enough memory to allow the application to continue creating new objects. After the garbage collector performs a collection of generation 0, it compacts the memory for the reachable objects as explained in Releasing Memory earlier in this topic. The garbage collector then promotes these objects and considers this portion of the managed heap generation 1. Because objects that survive collections tend to have longer lifetimes, it makes sense to promote them to a higher generation. As a result, the garbage collector does not have to reexamine the objects in generations 1 and 2 each time it performs a collection of generation 0. After the garbage collector performs its first collection of generation 0 and promotes the reachable objects to generation 1, it considers the
remainder of the managed heap generation 0. It continues to allocate memory for new objects in generation 0 until generation 0 is full and it is necessary to perform another collection. At this point, the garbage collector's optimizing engine determines whether it is necessary to examine the objects in older generations. For example, if a collection of generation 0 does not reclaim enough memory for the application to successfully complete its attempt to create a new object, the garbage collector can perform a collection of generation 1, then generation 0. If this does not reclaim enough memory, the garbage collector can perform a collection of generations 2, 1, and 0. After each collection, the garbage collector compacts the reachable objects in generation 0 and promotes them to generation 1. Objects in generation 1 that survive collections are promoted to generation 2. Because the garbage collector supports only three generations, objects in generation 2 that survive a collection remain in generation 2 until they are determined to be unreachable in a future collection. Releasing Memory for Unmanaged Resources For the majority of the objects that your application creates, you can rely on the garbage collector to automatically perform the necessary memory management tasks. However, unmanaged resources require explicit cleanup. The most common type of unmanaged resource is an object that wraps an operating system resource, such as a file handle, window handle, or network connection. Although the garbage collector is able to track the lifetime of a managed object that encapsulates an unmanaged resource, it does not have specific knowledge about how to clean up the resource. When you create an object that encapsulates an unmanaged resource, it is recommended that you provide the necessary code to clean up the unmanaged resource in a public Dispose method. By providing a Dispose method, you enable users of your object to explicitly free its memory when they are finished with the object. When you use an object that encapsulates an unmanaged resource, you should be aware of Dispose and call it as necessary. For more information about cleaning up unmanaged resources and an example of a design pattern for implementing Dispose, see Garbage Collection. Common Type System The common type system defines how types are declared, used, and managed in the runtime, and is also an important part of the runtime's support for cross-language integration. The common type system performs the following functions:
•
Establishes a framework that helps enable cross-language integration, type safety, and high performance code execution.
•
Provides an object-oriented model that supports the complete implementation of many programming languages.
•
Defines rules that languages must follow, which helps ensure that objects written in different languages can interact with each other.
Common Type System Overview This section describes concepts and defines terms that will help you understand and work with your language's implementation of the common type system. Classification of Types The common type system supports two general categories of types, each of which is further divided into subcategories: •
Value types Value types directly contain their data, and instances of value types are either allocated on the stack or allocated inline in a structure. Value types can be built-in (implemented by the runtime), user-defined, or enumerations. For a list of built-in value types, see the .NET Framework Class Library.
•
Reference types Reference types store a reference to the value's memory address, and are allocated on the heap. Reference types can be self-describing types, pointer types, or interface types. The type of a reference type can be determined from values of selfdescribing types. Self-describing types are further split into arrays and class types. The class types are user-defined classes, boxed value types, and delegates.
Variables that are value types each have their own copy of the data, and therefore operations on one variable do not affect other variables.
Variables that are reference types can refer to the same object; therefore, operations on one variable can affect the same object referred to by another variable. All types derive from the System..::.Object base type. The following example shows the difference between reference types and value types. using System; class Class1 { public int Value = 0; } class Test { static void Main() { int val1 = 0; int val2 = val1; val2 = 123; Class1 ref1 = new Class1(); Class1 ref2 = ref1; ref2.Value = 123; Console.WriteLine("Values: {0}, {1}", val1, val2); Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value); } } output Values: 0, 123 Refs: 123, 123 The following diagram illustrates how these various types are related. Note that instances of types can be simply value types or selfdescribing types, even though there are subcategories of these types. Type classification
For more information about each type, see value types, enumerations, classes, delegates, arrays, interfaces, and pointers. Values and Objects Values are binary representations of data, and types provide a way of interpreting this data. A value type is stored directly as a binary representation of the type's data. The value of a reference type is the location of the sequence of bits that represent the type's data. Every value has an exact type that completely defines the value's representation and the operations that are defined on the value. Values of self-describing types are called objects. While it is always possible to determine the exact type of an object by examining its value, you cannot do so with a value type or pointer type. A value can have more than one type. A value of a type that implements an interface is also a value of that interface type. Likewise, a value of a type that derives from a base type is also a value of that base type. Types and Assemblies The runtime uses assemblies to locate and load types. The assembly manifest contains the information that the runtime uses to resolve all type references made within the scope of the assembly. A type name in the runtime has two logical parts: the assembly name and the name of the type within the assembly. Two types with the same name but in different assemblies are defined as two distinct types.
Assemblies provide consistency between the scope of names seen by the developer and the scope of names seen by the runtime system. Developers author types in the context of an assembly. The content of the assembly a developer is building establishes the scope of names that will be available at run time. Types and Namespaces From the viewpoint of the runtime, a namespace is just a collection of type names. Particular languages might have constructs and corresponding syntax that help developers form logical groups of types, but these constructs are not used by the runtime when binding types. Thus, both the Object and String classes are part of the System namespace, but the runtime only recognizes the full names of each type, which are System..::.Object and System..::.String, respectively. You can build a single assembly that exposes types that look like they come from two different hierarchical namespaces, such as System.Collections and System.Windows.Forms. You can also build two assemblies that both export types whose names contain MyDll.MyClass. If you create a tool to represent types in an assembly as belonging to a hierarchical namespace, the tool must enumerate the types in an assembly or group of assemblies and parse the type names to derive a hierarchical relationship. .NET Framework Class Library Overview The .NET Framework includes classes, interfaces, and value types that expedite and optimize the development process and provide access to system functionality. To facilitate interoperability between languages, most .NET Framework types are CLS-compliant and can therefore be used from any programming language whose compiler conforms to the common language specification (CLS). The .NET Framework types are the foundation on which .NET applications, components, and controls are built. The .NET Framework includes types that perform the following functions: •
Represent base data types and exceptions.
•
Encapsulate data structures.
•
Perform I/O.
•
Access information about loaded types.
•
Invoke .NET Framework security checks.
•
Provide data access, rich client-side GUI, and server-controlled, client-side GUI.
The .NET Framework provides a rich set of interfaces, as well as abstract and concrete (non-abstract) classes. You can use the concrete classes as is or, in many cases, derive your own classes from them. To use the functionality of an interface, you can either create a class that implements the interface or derive a class from one of the .NET Framework classes that implements the interface. Naming Conventions .NET Framework types use a dot syntax naming scheme that connotes a hierarchy. This technique groups related types into namespaces so they can be searched and referenced more easily. The first part of the full name — up to the rightmost dot — is the namespace name. The last part of the name is the type name. For example, System.Collections.ArrayList represents the ArrayList type, which belongs to the System.Collections namespace. The types in System.Collections can be used to manipulate collections of objects. This naming scheme makes it easy for library developers extending the .NET Framework to create hierarchical groups of types and name them in a consistent, informative manner. It also allows types to be unambiguously identified by their full name (that is, by their namespace and type name), which prevents type name collisions. It is expected that library developers will use the following guideline when creating names for their namespaces: CompanyName.TechnologyName For example, the namespace Microsoft.Word conforms to this guideline. The use of naming patterns to group related types into namespaces is a very useful way to build and document class libraries. However, this naming scheme has no effect on visibility, member access, inheritance, security, or binding. A namespace can be partitioned across multiple assemblies and a single assembly can contain types from multiple namespaces. The assembly provides the formal structure for versioning, deployment, security, loading, and visibility in the common language runtime. For more information on namespaces and type names, see Common Type System.
System Namespace The System namespace is the root namespace for fundamental types in the .NET Framework. This namespace includes classes that represent the base data types used by all applications: Object (the root of the inheritance hierarchy), Byte, Char, Array, Int32, String, and so on. Many of these types correspond to the primitive data types that your programming language uses. When you write code using .NET Framework types, you can use your language's corresponding keyword when a .NET Framework base data type is expected. The following table lists the base types that the .NET Framework supplies, briefly describes each type, and indicates the corresponding type in Visual Basic, C#, C++, and JScript. Class Category Description name
Integer
Byte
SByte
An 8-bit unsigned integer. An 8-bit signed integer.
Visual JScript C# data C++ data Basic data type type data type type Byte
byte
unsigned Byte char char
SByte
sbyte
-or-
SByte
signed char
Not CLScompliant. Int16
A 16-bit signed integer.
Int32
A 32-bit signed integer.
Integer
A 64-bit signed integer.
Long
long
__int64
UShort
ushort
unsigned UInt16 short
Int64
UInt16 A 16-bit unsigned integer. Not CLS-
Short
short
short
short
int int
-or-
int
long long
compliant. A 32-bit unsigned UInt32 integer.
unsigned int UInteger uint
Not CLScompliant. A 64-bit unsigned UInt64 integer.
-or-
UInt32
unsigned long
ULong
ulong
unsigned UInt64 __int64
Single
float
float
A doubleprecision (64-bit) Double floatingpoint number.
Double
double double
Logical
A Boolean Boolean value (true or false).
Boolean bool
bool
Other
Char
Char
wchar_t char
Not CLScompliant.
Floating point
Single
A singleprecision (32-bit) floatingpoint number.
A Unicode (16-bit) character.
A decimal Decimal (128-bit) value. IntPtr
char
Decimal decimal Decimal
float
double
bool
Decimal
A signed IntPtr IntPtr IntPtr IntPtr integer No built-in No built- No built-in whose size type. in type. type. depends on the
underlying platform (a 32-bit value on a 32-bit platform and a 64-bit value on a 64-bit platform). An unsigned integer whose size depends on the underlying platform (a UIntPtr UIntPtr UIntPtr 32- bit value UIntPtr on a 32-bit No built-in No built- No built-in UIntPtr platform and type. in type. type. a 64-bit value on a 64-bit platform). Not CLScompliant. Class objects
Object
The root of the object hierarchy.
Object
object
Object*
Object
String
An immutable, fixed-length String string of Unicode characters.
string
String*
String
In addition to the base data types, the System namespace contains over 100 classes, ranging from classes that handle exceptions to classes that deal with core runtime concepts, such as application domains and the garbage collector. The System namespace also contains many second-level namespaces.
For more information about namespaces, browse the .NET Framework Class Library reference. The reference documentation provides a brief overview of each namespace as well as a formal description of each type and its members.
Using Delegates (C# Programming Guide) A delegate is a type that safely encapsulates a method, similar to a function pointer in C and C++. Unlike C function pointers, delegates are object-oriented, type safe, and secure. The type of a delegate is defined by the name of the delegate. The following example declares a delegate named Del that can encapsulate a method that takes a string as an argument and returns void: public delegate void Del(string message); A delegate object is normally constructed by providing the name of the method the delegate will wrap, or with an anonymous Method. Once a delegate is instantiated, a method call made to the delegate will be passed by the delegate to that method. The parameters passed to the delegate by the caller are passed to the method, and the return value, if any, from the method is returned to the caller by the delegate. This is known as invoking the delegate. An instantiated delegate can be invoked as if it were the wrapped method itself. For example: // Create a method for a delegate. public static void DelegateMethod(string message) { System.Console.WriteLine(message); } // Instantiate the delegate. Del handler = DelegateMethod; // Call the delegate. handler("Hello World"); Delegate types are derived from the Delegate class in the .NET Framework. Delegate types are sealed—they cannot be derived from— and it is not possible to derive custom classes from Delegate. Because the instantiated delegate is an object, it can be passed as a parameter, or assigned to a property. This allows a method to accept a delegate as a parameter, and call the delegate at some later time. This is known as an asynchronous callback, and is a common method of
notifying a caller when a long process has completed. When a delegate is used in this fashion, the code using the delegate does not need any knowledge of the implementation of the method being used. The functionality is similar to the encapsulation interfaces provide. For more information, see When to Use Delegates Instead of Interfaces. Another common use of callbacks is defining a custom comparison method and passing that delegate to a sort method. It allows the caller's code to become part of the sort algorithm. The following example method uses the Del type as a parameter: public void MethodWithCallback(int param1, int param2, Del callback) { callback("The number is: " + (param1 + param2).ToString()); } You can then pass the delegate created above to that method: MethodWithCallback(1, 2, handler); and receive the following output to the console: The number is: 3 Using the delegate as an abstraction, MethodWithCallback does not need to call the console directly—it does not have to be designed with a console in mind. What MethodWithCallback does is simply prepare a string and pass the string to another method. This is especially powerful since a delegated method can use any number of parameters. When a delegate is constructed to wrap an instance method, the delegate references both the instance and the method. A delegate has no knowledge of the instance type aside from the method it wraps, so a delegate can refer to any type of object as long as there is a method on that object that matches the delegate signature. When a delegate is constructed to wrap a static method, it only references the method. Consider the following declarations: public class MethodClass { public void Method1(string message) { } public void Method2(string message) { } }
Along with the static DelegateMethod shown previously, we now have three methods that can be wrapped by a Del instance. A delegate can call more than one method when invoked. This is referred to as multicasting. To add an extra method to the delegate's list of methods—the invocation list—simply requires adding two delegates using the addition or addition assignment operators ('+' or '+='). For example: MethodClass obj = new MethodClass(); Del d1 = obj.Method1; Del d2 = obj.Method2; Del d3 = DelegateMethod; //Both types of assignment are valid. Del allMethodsDelegate = d1 + d2; allMethodsDelegate += d3; At this point allMethodsDelegate contains three methods in its invocation list—Method1, Method2, and DelegateMethod. The original three delegates, d1, d2, and d3, remain unchanged. When allMethodsDelegate is invoked, all three methods are called in order. If the delegate uses reference parameters, the reference is passed sequentially to each of the three methods in turn, and any changes by one method are visible to the next method. When any of the methods throws an exception that is not caught within the method, that exception is passed to the caller of the delegate and no subsequent methods in the invocation list are called. If the delegate has a return value and/or out parameters, it returns the return value and parameters of the last method invoked. To remove a method from the invocation list, use the decrement or decrement assignment operator ('-' or '-='). For example: //remove Method1 allMethodsDelegate -= d1; // copy AllMethodsDelegate while removing d2 Del oneMethodDelegate = allMethodsDelegate - d2; Because delegate types are derived from System.Delegate, the methods and properties defined by that class can be called on the delegate. For example, to find the number of methods in a delegate's invocation list, you may write: int invocationCount = d1.GetInvocationList().GetLength(0);
Delegates with more than one method in their invocation list derive from MulticastDelegate, which is a subclass of System.Delegate. The above code works in either case because both classes support GetInvocationList. Multicast delegates are used extensively in event handling. Event source objects send event notifications to recipient objects that have registered to receive that event. To register for an event, the recipient creates a method designed to handle the event, then creates a delegate for that method and passes the delegate to the event source. The source calls the delegate when the event occurs. The delegate then calls the event handling method on the recipient, delivering the event data. The delegate type for a given event is defined by the event source. For more, see Events (C# Programming Guide). Comparing delegates of two different types assigned at compile-time will result in a compilation error. If the delegate instances are statically of the type System.Delegate, then the comparison is allowed, but will return false at run time. For example: delegate void Delegate1(); delegate void Delegate2(); static void method(Delegate1 d, Delegate2 e, System.Delegate f) { // Compile-time error. //Console.WriteLine(d == e); // OK at compile-time. False if the run-time type of f // is not the same as that of d. System.Console.WriteLine(d == f); } When to Use Delegates Instead of Interfaces (C# Programming Guide) Both delegates and interfaces enable a class designer to separate type declarations and implementation. A given interface can be inherited and implemented by any class or struct. A delegate can be created for a method on any class, as long as the method fits the method signature for the delegate. An interface reference or a delegate can be used by an object that has no knowledge of the class that implements the interface or delegate method. Given these similarities, when should a class designer use a delegate and when should it use an interface?
Use a delegate in the following circumstances: •
An eventing design pattern is used.
•
It is desirable to encapsulate a static method.
•
The caller has no need to access other properties, methods, or interfaces on the object implementing the method.
•
Easy composition is desired.
•
A class may need more than one implementation of the method.
Use an interface in the following circumstances: •
There is a group of related methods that may be called.
•
A class only needs one implementation of the method.
•
The class using the interface will want to cast that interface to other interface or class types.
•
The method being implemented is linked to the type or identity of the class: for example, comparison methods.
One good example of using a single-method interface instead of a delegate is IComparable or the generic version, IComparable<(Of <(T>)>). IComparable declares the CompareTo method, which returns an integer that specifies a less than, equal to, or greater than relationship between two objects of the same type. IComparable can be used as the basis of a sort algorithm. Although using a delegate comparison method as the basis of a sort algorithm would be valid, it is not ideal. Because the ability to compare belongs to the class and the comparison algorithm does not change at run time, a singlemethod interface is ideal. See Also Using Namespaces (C# Programming Guide) Namespaces are heavily used within C# programs in two ways. Firstly, the .NET Framework classes use namespaces to organize its many classes. Secondly, declaring your own namespaces can help control the scope of class and method names in larger programming projects.
Accessing Namespaces Most C# applications begin with a section of using directives. This section lists the namespaces that the application will be using frequently, and saves the programmer from specifying a fully qualified name every time that a method that is contained within is used. For example, by including the line: C# using System; At the start of a program, the programmer can use the code: C# Console.WriteLine("Hello, World!"); Instead of: C# System.Console.WriteLine("Hello, World!"); The using Directive (C# Reference) can also be used to create an alias for a namespace. For example, if you are using a previously written namespace that contains nested namespaces, you might want to declare an alias to provide a shorthand way of referencing one in particular, as in the following example: C# using Co = Company.Proj.Nested; represent a namespace
// define an alias to
Using Namespaces to control scope The namespace keyword is used to declare a scope. The ability to create scopes within your project helps organize code and lets you create globally-unique types. In the following example, a class titled SampleClass is defined in two namespaces, one nested inside the other. The . Operator (C# Reference) is used to differentiate which method gets called. C# namespace SampleNamespace { class SampleClass
{ public void SampleMethod() { System.Console.WriteLine( "SampleMethod inside SampleNamespace"); } } // Create a nested namespace, and define another class. namespace NestedNamespace { class SampleClass { public void SampleMethod() { System.Console.WriteLine( "SampleMethod inside NestedNamespace"); } } } class Program { static void Main(string[] args) { // Displays "SampleMethod inside SampleNamespace." SampleClass outer = new SampleClass(); outer.SampleMethod(); // Displays "SampleMethod inside SampleNamespace." SampleNamespace.SampleClass outer2 = new SampleNamespace.SampleClass(); outer2.SampleMethod(); // Displays "SampleMethod inside NestedNamespace." NestedNamespace.SampleClass inner = new NestedNamespace.SampleClass(); inner.SampleMethod(); } } } Fully Qualified Names Namespaces and types have unique titles described by fully qualified names that indicate a logical hierarchy. For example, the statement
A.B implies that A is the name of the namespace or type, and B is nested inside it. In the following example, there are nested classes and namespaces. The fully qualified name is indicated as a comment following each entity. C# कोड कॉपी करें
namespace N1 // N1 { class C1 // N1.C1 { class C2 // N1.C1.C2 { } } namespace N2 // N1.N2 { class C2 // N1.N2.C2 { } } } In the previous code segment: •
The namespace N1 is a member of the global namespace. Its fully qualified name is N1.
•
The namespace N2 is a member of N1. Its fully qualified name is N1.N2.
•
The class C1 is a member of N1. Its fully qualified name is N1.C1.
•
The class name C2 is used two times in this code. However, the fully qualified names are unique. The first instance of C2 is declared inside C1; therefore, its fully qualified name is: N1.C1.C2. The second instance of C2 is declared inside a namespace N2; therefore, its fully qualified name is N1.N2.C2.
Using the previous code segment, you can add a new class member, C3, to the namespace N1.N2 as follows:
C# कोड कॉपी करें
namespace N1.N2 { class C3 // N1.N2.C3 { } } In general, use :: to reference a namespace alias or global:: to reference the global namespace and . to qualify types or members. It is an error to use :: with an alias that references a type instead of a namespace. For example: C# कोड कॉपी करें
using Alias = System.Console; C# कोड कॉपी करें
class TestClass { static void Main() { // Error //Alias::WriteLine("Hi"); // OK Alias.WriteLine("Hi"); } } Remember that the word global is not a predefined alias; therefore, global.X does not have any special meaning. It acquires a special meaning only when it is used with ::. A warning (see Compiler Warning (level 2) CS0440) is generated if you define an alias named global because global:: always references the global namespace and not an alias. For example, the following line generates the warning: C# कोड कॉपी करें
using global = System.Collections; // Warning Using :: with aliases is a good idea and protects against the unexpected introduction of additional types. For example, consider this example:
C# कोड कॉपी करें
using Alias = System; C# कोड कॉपी करें
namespace Library { public class C : Alias.Exception { } } This works, but if a type named Alias were to subsequently be introduced, Alias. would bind to that type instead. Using Alias::Exception insures that Alias is treated as a namespace alias and not mistaken for a type. See the topic How to: Use the Namespace Alias Qualifier (C# Programming Guide) for more information regarding the global alias. Main() and Command-Line Arguments (C# Programming Guide) The Main method is the entry point of a C# console application or windows application. (Libraries and services do not require a Main method as an entry point.). When the application is started, the Main method is the first method that is invoked. There can only be one entry point in a C# program. If you have more than one class that has a Main method, you must compile your program with the /main compiler option to specify which Main method to use as the entry point. For more information, see /main (Specify Location of Main Method) (C# Compiler Options). C# कोड कॉपी करें
class TestClass { static void Main(string[] args) { // Display the number of command line arguments: System.Console.WriteLine(args.Length); } } Overview • The Main method is the entry point of an .exe program; it is where the program control starts and ends.
•
Main is declared inside a class or struct. Main must be static and it should not be public. (In the earlier example, it receives the default access of private.) The enclosing class or struct is not required to be static.
•
Main can either have a void or int return type.
•
The Main method can be declared with or without a string[] parameter that contains command-line arguments. When using Visual Studio to create Windows Forms applications, you can add the parameter manually or else use the Environment class to obtain the command-line arguments. Parameters are read as zero-indexed command-line arguments. Unlike C and C++, the name of the program is not treated as the first command-line argument
Command-Line Arguments (C# Programming Guide) The Main method can use arguments, in which case, it takes one of the following forms: C# कोड कॉपी करें
static int Main(string[] args) C# कोड कॉपी करें
static void Main(string[] args) Note: To enable command-line arguments in the Main method in a Windows Forms application, you must manually modify the signature of Main in program.cs. The code generated by the Windows Forms designer creates a Main without an input parameter. You can also use Environment..::.CommandLine or Environment..::.GetCommandLineArgs to access the command-line arguments from any point in a console or Windows application. The parameter of the Main method is a String array that represents the command-line arguments. Usually you determine whether arguments exist by testing the Length property, for example:
C# कोड कॉपी करें
if (args.Length == 0) { System.Console.WriteLine("Please enter a numeric argument."); return 1; } You can also convert the string arguments to numeric types by using the Convert class or the Parse method. For example, the following statement converts the string to a long number by using the Parse method: कोड कॉपी करें
long num = Int64.Parse(args[0]); It is also possible to use the C# type long, which aliases Int64: कोड कॉपी करें
long num = long.Parse(args[0]); You can also use the Convert class method ToInt64 to do the same thing: कोड कॉपी करें
long num = Convert.ToInt64(s); For more information, see Parse and Convert. Example The following example shows how to use command-line arguments in a console application. The program takes one argument at run time, converts the argument to an integer, and calculates the factorial of the number. If no arguments are supplied, the program issues a message that explains the correct usage of the program. Note: When running an application in Visual Studio, you can specify command-line arguments in the Debug Page, Project Designer. For more examples about how to use command-line arguments, see How to: Create and Use C# DLLs (C# Programming Guide). C# कोड कॉपी करें
public class Functions { public static long Factorial(int n)
{ // Test for invalid input if ((n < 0) || (n > 20)) { return -1; } // Calculate the factorial iteratively rather than recursively: long tempResult = 1; for (int i = 1; i <= n; i++) { tempResult *= i; } return tempResult; } } class MainClass { static int Main(string[] args) { // Test if input arguments were supplied: if (args.Length == 0) { System.Console.WriteLine("Please enter a numeric argument."); System.Console.WriteLine("Usage: Factorial "); return 1; } // Try to convert the input arguments to numbers. This will throw // an exception if the argument is not a number. // num = int.Parse(args[0]); int num; bool test = int.TryParse(args[0], out num); if (test == false) { System.Console.WriteLine("Please enter a numeric argument."); System.Console.WriteLine("Usage: Factorial "); return 1; }
// Calculate factorial. long result = Functions.Factorial(num); // Print result. if (result == -1) System.Console.WriteLine("Input must be >= 0 and <= 20."); else System.Console.WriteLine("The Factorial of {0} is {1}.", num, result); return 0; } } // If 3 is entered on command line, the // output reads: The factorial of 3 is 6.
How to: Display Command Line Arguments (C# Programming Guide) Updated: July 2008 Arguments provided to an executable on the command-line are accessible through an optional parameter to Main. The arguments are provided in the form of an array of strings. Each element of the array contains one argument. White-space between arguments is removed. For example, consider these command-line invocations of a fictitious executable: Input on Command-line
Array of strings passed to Main "a"
executable.exe a b c
"b" "c"
executable.exe one two
executable.exe “one two” three
"one" "two" "one two" "three"
Note: When you are running an application in Visual Studio, you can specify command-line arguments in the Debug Page, Project Designer.
Example This example displays the command line arguments passed to a command-line application. The output shown is for the first entry in the table above. C# कोड कॉपी करें
class CommandLine { static void Main(string[] args) { // The Length property provides the number of array elements System.Console.WriteLine("parameter count = {0}", args.Length); for (int i = 0; i < args.Length; i++) { System.Console.WriteLine("Arg[{0}] = [{1}]", i, args[i]); } } } /* Output (assumes 3 cmd line args): parameter count = 3 Arg[0] = [a] Arg[1] = [b] Arg[2] = [c] */ How to: Access Command-Line Arguments Using foreach (C# Programming Guide) Another approach to iterating over the array is to use the foreach statement as shown in this example. The foreach statement can be used to iterate over an array, a .NET Framework collection class, or any class or struct that implements the IEnumerable interface. Note: When running an application in Visual Studio, you can specify command-line arguments in the Debug Page, Project Designer. Example This example demonstrates how to print out the command line arguments using foreach. C#
कोड कॉपी करें
// arguments: John Paul Mary C# कोड कॉपी करें
class CommandLine2 { static void Main(string[] args) { System.Console.WriteLine("Number of command line parameters = {0}", args.Length); foreach (string s in args) { System.Console.WriteLine(s); } } } /* Output: Number of command line parameters = 3 John Paul Mary */ Main() Return Values (C# Programming Guide) Updated: July 2009 The Main method can return void: C# कोड कॉपी करें
static void Main() { //... } It can also return an int: C# कोड कॉपी करें
static int Main() { //... return 0;
} If the return value from Main is not used, returning void allows for slightly simpler code. However, returning an integer enables the program to communicate status information to other programs or scripts that invoke the executable file. The following example shows how the return value from Main can be accessed. Example In this example, a batch file is used to run a program and test the return value of the Main function. When a program is executed in Windows, any value returned from the Main function is stored in an environment variable called ERRORLEVEL. A batch file can determine the outcome of execution by inspecting the ERRORLEVEL variable. Traditionally, a return value of zero indicates successful execution. The following example is a simple program that returns zero from the Main function. The zero indicates that the program ran successfully. Save the program as MainReturnValTest.cs. C# कोड कॉपी करें
class MainReturnValTest { static int Main() { //... return 0; } } Because this example uses a batch file, it is best to compile the code from a command prompt. Follow the instructions in How to: Set Environment Variables to enable command-line builds, or use the Visual Studio Command Prompt, available from the Start menu under Visual Studio Tools. From the command prompt, navigate to the folder in which you saved the program. The following command compiles MainReturnValTest.cs and produces the executable file MainReturnValTest.exe. csc MainReturnValTest.cs Next, create a batch file to run MainReturnValTest.exe and to display the result. Paste the following code into a text file and save it as test.bat in the folder that contains MainReturnValTest.cs and MainReturnValTest.exe. Run the batch file by typing test at the command prompt.
Because the code returns zero, the batch file will report success. However, if you change MainReturnValTest.cs to return a non-zero value and then re-compile the program, subsequent execution of the batch file will report failure. कोड कॉपी करें
rem test.bat @echo off MainReturnValueTest @if "%ERRORLEVEL%" == "0" goto good :fail echo Execution Failed echo return value = %ERRORLEVEL% goto end :good echo Execution succeeded echo Return value = %ERRORLEVEL% goto end :end Sample Output Execution succeeded Return value = 0 Types (C# Programming Guide) Updated: February 2009 Types, Variables, and Values C# is a strongly-typed language. Every variable and constant has a type, as does every expression that evaluates to a value. Every method signature specifies a type for each input parameter and for the return value. The .NET Framework class library defines a set of built-in numeric types as well as more complex types that represent a wide variety of logical constructs, such as the file system, network connections, collections and arrays of objects, and dates. A typical C# program uses types from the class library as well as user-defined types that model the concepts that are specific to the program's problem domain. The information stored in a type can include the following: •
The storage space that a variable of the type requires.
•
The maximum and minimum values that it can represent.
•
The members (methods, fields, events, and so on) that it contains.
•
The base type it inherits from.
•
The location where the memory for variables will be allocated at run time.
•
The kinds of operations that are permitted.
The compiler uses type information to make sure that all operations that are performed in your code are type safe. For example, if you declare a variable of type int, the compiler allows you to use the variable in addition and subtraction operations. If you try to perform those same operations on a variable of type bool, the compiler generates an error, as shown in the following example: C# कोड कॉपी करें
int a = 5; int b = a + 2; //OK bool test = true; * // Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'. int c = a + test; Note: C and C++ developers, notice that in C#, bool is not convertible to int. The compiler embeds the type information into the executable file as metadata. The common language runtime (CLR) uses that metadata at run time to further guarantee type safety when it allocates and reclaims memory. Specifying Types in Variable Declarations When you declare a variable or constant in a program, you must either specify its type or use the var keyword to let the compiler infer the type. The following example shows some variable declarations that use both built-in numeric types and complex user-defined types: C# कोड कॉपी करें
// Declaration only: float temperature; string name; MyClass myClass; // Declaration with initializers (four examples): char firstLetter = 'C'; var limit = 3; int[] source = { 0, 1, 2, 3, 4, 5 }; var query = from item in source where item <= limit select item; The types of method parameters and return values are specified in the method signature. The following signature shows a method that requires an int as an input argument and returns a string: C# कोड कॉपी करें
public string GetName(int ID) { if (ID < names.Length) return names[ID]; else return String.Empty; } private string[] names = { "Spencer", "Sally", "Doug" }; After a variable is declared, it cannot be re-declared with a new type, and it cannot be assigned a value that is not compatible with its declared type. For example, you cannot declare an int and then assign it a Boolean value of true. However, values can be converted to other types, for example when they are assigned to new variables or passed as method arguments. A type conversion that does not cause data loss is performed automatically by the compiler. A conversion that might cause data loss requires a cast in the source code. For more information, see Casting and Type Conversions (C# Programming Guide). Built-in Types C# provides a standard set of built-in numeric types to represent integers, floating point values, Boolean expressions, text characters, decimal values, and other types of data. There are also built-in string and object types. These are available for you to use in any C# program. For a more information about the built-in types, see Types Reference Tables (C# Reference). Custom Types
You use the struct, class, interface, and enum constructs to create your own custom types. The .NET Framework class library itself is a collection of custom types provided by Microsoft that you can use in your own applications. By default, the most frequently used types in the class library are available in any C# program. Others become available only when you explicitly add a project reference to the assembly in which they are defined. After the compiler has a reference to the assembly, you can declare variables (and constants) of the types declared in that assembly in source code. For more information, see .NET Framework Class Library. The Common Type System It is important to understand two fundamental points about the type system in the .NET Framework: •
It supports the principle of inheritance. Types can derive from other types, called base types. The derived type inherits (with some restrictions) the methods, properties, and other members of the base type. The base type can in turn derive from some other type, in which case the derived type inherits the members of both base types in its inheritance hierarchy. All types, including built-in numeric types such as System..::.Int32 (C# keyword: int), derive ultimately from a single base type, which is System..::.Object (C# keyword: object). This unified type hierarchy is called the Common Type System (CTS). For more information about inheritance in C#, see Inheritance (C# Programming Guide).
•
Each type in the CTS is defined as either a value type or a reference type. This includes all custom types in the .NET Framework class library and also your own user-defined types. Types that you define by using the struct keyword are value types; all the built-in numeric types are structs. Types that you define by using the class keyword are reference types. Reference types and value types have different compile-time rules, and different run-time behavior.
The following illustration shows the relationship between value types and reference types in the CTS.
Value types and reference types in the CTS
Note: You can see that the most commonly used types are all organized in the System namespace. However, the namespace in which a type is contained has no relation to whether it is a value type or reference type. Value Types Value types derive from System..::.ValueType, which derives from System..::.Object. Types that derive from System..::.ValueType have special behavior in the CLR. Value type variables directly contain their values, which means that the memory is allocated inline in whatever context the variable is declared. There is no separate heap allocation or garbage collection overhead for value-type variables. There are two categories of value types: struct and enum. The built-in numeric types are structs, and they have properties and methods that you can access: C# कोड कॉपी करें
// Static method on type Byte.
byte b = Byte.MaxValue; But you declare and assign values to them as if they were simple nonaggregate types: C# कोड कॉपी करें
byte num = 0xA; int i = 5; char c = 'Z'; Value types are sealed, which means, for example, that you cannot derive a type from System..::.Int32, and you cannot define a struct to inherit from any user-defined class or struct because a struct can only inherit from System..::.ValueType. However, a struct can implement one or more interfaces. You can cast a struct type to an interface type; this causes a boxing operation to wrap the struct inside a reference type object on the managed heap. Boxing operations occur when you pass a value type to a method that takes a System..::.Object as an input parameter. For more information, see Boxing and Unboxing (C# Programming Guide). You use the struct keyword to create your own custom value types. Typically, a struct is used as a container for a small set of related variables, as shown in the following example: C# कोड कॉपी करें
public struct CoOrds { public int x, y; public CoOrds(int p1, int p2) { x = p1; y = p2; } } For more information about structs, see Structs (C# Programming Guide). For more information about value types in the .NET Framework, see Value Types in the Common Type System. The other category of value types is enum. An enum defines a set of named integral constants. For example, the System.IO..::.FileMode enumeration in the .NET Framework class library contains a set of named constant integers that specify how a file should be opened. It is defined as shown in the following example: C#
कोड कॉपी करें
public enum FileMode { CreateNew = 1, Create = 2, Open = 3, OpenOrCreate = 4, Truncate = 5, Append = 6, } The Create constant has a value of 2. However, the name is much more meaningful for humans reading the source code, and for that reason it is better to use enumerations instead of constant literal numbers. All enums inherit from System..::.Enum, which inherits from System..::.ValueType. All the rules that apply to structs also apply to enums. For more information about enums, see Enumeration Types (C# Programming Guide). Reference Types A type that is defined as a class, delegate, array, or interface is a reference type. At run time, when you declare a variable of a reference type, the variable contains the value null until you explicitly create an instance of the object by using the new operator, or assign it an object that has been created elsewhere by using new, as shown in the following example: C# कोड कॉपी करें
MyClass mc = new MyClass(); MyClass mc2 = mc; An interface must be initialized together with a class object that implements it. If MyClass implements IMyInterface, you create an instance of IMyInterface as shown in the following example: C# कोड कॉपी करें
IMyInterface iface = new MyClass(); When the object is created, the memory is allocated on the managed heap, and the variable holds only a reference to the location of the object. Types on the managed heap require overhead both when they are allocated and when they are reclaimed by the automatic memory management functionality of the CLR, which is known as garbage collection. However, garbage collection is also highly optimized, and in
most scenarios it does not create a performance issue. For more information about garbage collection, see Automatic Memory Management. All arrays are reference types, even if their elements are value types. Arrays implicitly derive from the System..::.Array class, but you declare and use them with the simplified syntax that is provided by C#, as shown in the following example: C# कोड कॉपी करें
// Declare and initialize an array of integers. int[] nums = { 1, 2, 3, 4, 5 }; // Access an instance property of System.Array. int len = nums.Length; Reference types fully support inheritance. When you create a class, you can inherit from any other interface or class that is not defined as sealed, and other classes can inherit from your class and override your virtual methods. For more information about how to create your own classes, see Classes and Structs (C# Programming Guide). For more information about inheritance and virtual methods, see Inheritance (C# Programming Guide). Types of Literal Values In C#, literal values receive a type from the compiler. You can specify how a numeric literal should be typed by appending a letter to the end of the number. For example, to specify that the value 4.56 should be treated as a float, append an "f" or "F" after the number: 4.56f. If no letter is appended, the compiler will infer a type for the literal. For more information about which types can be specified with letter suffixes, see the reference pages for individual types in Value Types (C# Reference). Because literals are typed, and all types derive ultimately from System..::.Object, you can write and compile code such as the following: C# कोड कॉपी करें
string s = "The answer is " + 5.ToString(); // Outputs: "The answer is 5" Console.WriteLine(s); Type type = 12345.GetType(); // Outputs: "System.Int32"
Console.WriteLine(type); Generic Types A type can be declared with one or more type parameters that serve as a placeholder for the actual type (the concrete type) that client code will provide when it creates an instance of the type. Such types are called generic types. For example, the .NET Framework type System.Collections.Generic..::.List<(Of <(T>)>) has one type parameter that by convention is given the name T. When you create an instance of the type, you specify the type of the objects that the list will contain, for example, string: C# कोड कॉपी करें
List<string> strings = new List<string>(); The use of the type parameter makes it possible to reuse the same class to hold any type of element, without having to convert each element to object. Generic collection classes are called strongly-typed collections because the compiler knows the specific type of the collection's elements and can raise an error at compile-time if, for example, you try to add an integer to the strings object in the previous example. For more information, see Generics (C# Programming Guide). Implicit Types, Anonymous Types, and Nullable Types As stated previously, you can implicitly type a local variable (but not class members) by using the var keyword. The variable still receives a type at compile time, but the type is provided by the compiler. For more information, see Implicitly Typed Local Variables (C# Programming Guide). In some cases, it is inconvenient to create a named type for simple sets of related values that you do not intend to store or pass outside method boundaries. You can create anonymous types for this purpose. For more information, see Anonymous Types (C# Programming Guide). Ordinary value types cannot have a value of null. However, you can create nullable value types by affixing a ? after the type. For example, int? is an int type that can also have the value null. In the CTS, nullable types are instances of the generic struct type System..::.Nullable<(Of <(T>)>). Nullable types are especially useful when you are passing data to and from databases in which numeric values might be null. For more information, see Nullable Types (C# Programming Guide). Related Sections For more information, see the following topics:
•
Casting and Type Conversions (C# Programming Guide)
•
Boxing and Unboxing (C# Programming Guide)
•
Value Types (C# Reference)
•
Reference Types (C# Reference)
•
Classes and Structs (C# Programming Guide)
•
Anonymous Types (C# Programming Guide)
•
Generics (C# Programming Guide)
C# Language Specification For more information about types, see the following sections in the C# Language Specification: •
1.3 Types and variables
•
3.8 Namespace and type names
•
4.1 Value types
•
4.2 Reference types
•
4.3 Boxing and unboxing
See Also Concepts C# Programming Guide Conversion of XML Data Types Reference Data Types Compared in Different Languages Integral Types Table (C# Reference) Other Resources C# Reference Change History Date History February 2009 July 2008
Fixed an error in the MaxValue example.
Reason
Customer feedback.
Added introductory Information enhancement. information and information about type declarations, the
common type system, value and reference types, literals, and generic types. Casting and Type Conversions (C# Programming Guide) Updated: July 2008 Because C# is statically-typed at compile time, after a variable is declared, it cannot be declared again or used to store values of another type unless that type is convertible to the variable's type. For example, there is no conversion from an integer to any arbitrary string. Therefore, after you declare i as an integer, you cannot assign the string "Hello" to it, as is shown in the following code. कोड कॉपी करें
int i; i = "Hello"; // Error: "Cannot implicitly convert type 'string' to 'int'" However, you might sometimes need to copy a value into a variable or method parameter of another type. For example, you might have an integer variable that you need to pass to a method whose parameter is typed as double. Or you might need to assign a class variable to a variable of an interface type. These kinds of operations are called type conversions. In C#, you can perform the following kinds of conversions: • Implicit conversions: No special syntax is required because the conversion is type safe and no data will be lost. Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes. •
Explicit conversions (casts): Explicit conversions require a cast operator. The source and destination variables are compatible, but there is a risk of data loss because the type of the destination variable is a smaller size than (or is a base class of) the source variable.
•
User-defined conversions: User-defined conversions are performed by special methods that you can define to enable explicit and implicit conversions between custom types that do
not have a base class–derived class relationship. For more information, see Conversion Operators (C# Programming Guide). •
Conversions with helper classes: To convert between noncompatible types, such as integers and System..::.DateTime objects, or hexadecimal strings and byte arrays, you can use the System..::.BitConverter class, the System..::.Convert class, and the Parse methods of the built-in numeric types, such as Int32..::.Parse. For more information, see How to: Convert a byte Array to an int (C# Programming Guide), How to: Convert a string to an int (C# Programming Guide), and How to: Convert Between Hexadecimal Strings and Numeric Types (C# Programming Guide).
Implicit Conversions For built-in numeric types, an implicit conversion can be made when the value to be stored can fit into the variable without being truncated or rounded off. For example, a variable of type long (8 byte integer) can store any value that an int (4 bytes on a 32-bit computer) can store. In the following example, the compiler implicitly converts the value on the right to a type long before assigning it to bigNum. C# कोड कॉपी करें
// Implicit conversion. num long can // hold any value an int can hold, and more! int num = 2147483647; long bigNum = num; For a complete list of all implicit numeric conversions, see Implicit Numeric Conversions Table (C# Reference). For reference types, an implicit conversion always exists from a class to any one of its direct or indirect base classes or interfaces. No special syntax is necessary because a derived class always contains all the members of a base class. कोड कॉपी करें
Derived d = new Derived(); Base b = d; // Always OK. Explicit Conversions
However, if a conversion cannot be made without a risk of losing information, the compiler requires that you perform an explicit conversion, which is called a cast. A cast is a way of explicitly informing the compiler that you intend to make the conversion and that you are aware that data loss might occur. To perform a cast, specify the type that you are casting to in parentheses in front of the value or variable to be converted. The following program casts a double to an int. The program will not compile without the cast. C# कोड कॉपी करें
class Test { static void Main() { double x = 1234.7; int a; // Cast double to int. a = (int)x; System.Console.WriteLine(a); } } // Output: 1234 For a list of the explicit numeric conversions that are allowed, see Explicit Numeric Conversions Table (C# Reference). For reference types, an explicit cast is required if you need to convert from a base type to a derived type: कोड कॉपी करें
// Create a new derived type. Giraffe g = new Giraffe(); // Implicit conversion to base type is safe. Animal a = g;
// Explicit conversion is required to cast // back to derived type. Note: This will compile but // throw an exception at run time if the right-side // object is not in fact a Giraffe. Giraffe g2 = (Giraffe) a; A cast operation between reference types does not change the runtime type of the underlying object; it only changes the type of the value that is being used as a reference to that object. For more information, see Polymorphism (C# Programming Guide). Type Conversion Exceptions at Run Time
In some reference type conversions, the compiler cannot determine whether a cast will be valid. It is possible for a cast operation that compiles correctly to fail at run time. As shown in the following example, a type cast that fails at run time will cause an InvalidCastException to be thrown. C# कोड कॉपी करें
class Animal { public void Eat() { Console.WriteLine("Eating."); } public override string ToString() { return "I am an animal."; } } class Reptile : Animal { } class Mammal : Animal { } class UnSafeCast { static void Main() { Test(new Mammal()); // Keep the console window open in debug mode. System.Console.WriteLine("Press any key to exit."); System.Console.ReadKey(); } static void Test(Animal a) { // Cause InvalidCastException at run time // because Mammal is not convertible to Reptile. Reptile r = (Reptile)a; } } C# provides the is and as operators to enable you to test for compatibility before actually performing a cast. For more information, see How to: Safely Cast by Using as and is Operators (C# Programming Guide). C# Language Specification For more information about casting and type conversions, see the following sections in the C# Language Specification:
•
7.6.6 Cast Expressions
•
6.1 Implicit Conversions
•
6.2 Explicit Conversions
Boxing and Unboxing (C# Programming Guide) Updated: July 2009 Boxing is the process of converting a value type to the type object or to any interface type implemented by this value type. When the CLR boxes a value type, it wraps the value inside a System.Object and stores it on the managed heap. Unboxing extracts the value type from the object. In the following example, the integer variable i is boxed and assigned to object o. C# कोड कॉपी करें
int i = 123; object o = (object)i; // boxing The object o can then be unboxed and assigned to integer variable i: C# कोड कॉपी करें
o = 123; i = (int)o; // unboxing Performance In relation to simple assignments, boxing and unboxing are computationally expensive processes. When a value type is boxed, a new object must be allocated and constructed. To a lesser degree, the cast required for unboxing is also expensive computationally. For more information, see Performance. Boxing Boxing is used to store value types in the garbage-collected heap. Boxing is an implicit conversion of a value type to the type object or to any interface type implemented by this value type. Boxing a value type allocates an object instance on the heap and copies the value into the new object. Consider the following declaration of a value-type variable: C# कोड कॉपी करें
int i = 123;
The following statement implicitly applies the boxing operation on the variable i: C# कोड कॉपी करें
object o = i; // Implicit boxing The result of this statement is creating an object reference o, on the stack, that references a value of the type int, on the heap. This value is a copy of the value-type value assigned to the variable i. The difference between the two variables, i and o, is illustrated in the following figure. Boxing Conversion
It also possible to perform the boxing explicitly as in the following example, but explicit boxing is never required: C# कोड कॉपी करें
int i = 123; object o = (object)i; // explicit boxing Description This example converts an integer variable i to an object o by using boxing. Then, the value stored in the variable i is changed from 123 to 456. The example shows that the original value type and the boxed object use separate memory locations, and therefore can store different values. Example C# कोड कॉपी करें
class TestBoxing { static void Main() { int i = 123;
object o = i; i = 456;
// Implicit boxing
// Change the contents of i
System.Console.WriteLine("The value-type value = {0}", i); System.Console.WriteLine("The object-type value = {0}", o); } } /* Output: The value-type value = 456 The object-type value = 123 */ The following example demonstrates a case of invalid unboxing and the resulting InvalidCastException. Using try and catch, an error message is displayed when the error occurs. C# कोड कॉपी करें
class TestUnboxing { static void Main() { int i = 123; object o = i; // implicit boxing try { int j = (short)o;
// attempt to unbox
System.Console.WriteLine("Unboxing OK."); } catch (System.InvalidCastException e) { System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message); } } } This program outputs: Specified cast is not valid. Error: Incorrect unboxing. If you change the statement: कोड कॉपी करें
int j = (short) o; to: कोड कॉपी करें
int j = (int) o; the conversion will be performed, and you will get the output: Unboxing OK. Unboxing Unboxing is an explicit conversion from the type object to a value type or from an interface type to a value type that implements the interface. An unboxing operation consists of: •
Checking the object instance to make sure that it is a boxed value of the given value type.
•
Copying the value from the instance into the value-type variable.
The following statements demonstrate both boxing and unboxing operations: C# कोड कॉपी करें
int i = 123; // a value type object o = i; // boxing int j = (int)o; // unboxing The following figure demonstrates the result of the previous statements. Unboxing Conversion
For the unboxing of value types to succeed at run time, the item being unboxed must be a reference to an object that was previously created by boxing an instance of that value type. Attempting to unbox null
causes a NullReferenceException. Attempting to unbox a reference to an incompatible value type causes an InvalidCastException. C# Language Specification For more information, see the following sections in the C# Language Specification: •
4.3.1 Boxing Conversions
Related Sections For more information: •
Reference Types
•
Value Types
C# Language Specification For more information, see the following section in the C# Language Specification: •
4.3 Boxing and Unboxing
See Also Concepts C# Programming Guide Change History Date
History
Reason
July 2009
Added information about exceptions to "Unboxing" section.
July 2008
Consolidated previously separate boxing Content bug fix. and unboxing topics into this topic.
Customer feedback.
How to: Convert a byte Array to an int (C# Programming Guide) This example shows you how to use the BitConverter class to convert an array of bytes to an int and back to an array of bytes. You may have to convert from bytes to a built-in data type after you read bytes off the network, for example. In addition to the ToInt32(array[]()[], Int32) method in the example, the following table lists methods in the BitConverter class that convert bytes (from an array of bytes) to other built-in types. Type returned bool
Method ToBoolean(array[]()[], Int32)
char
ToChar(array[]()[], Int32)
double
ToDouble(array[]()[], Int32)
short
ToInt16(array[]()[], Int32)
int
ToInt32(array[]()[], Int32)
long
ToInt64(array[]()[], Int32)
float
ToSingle(array[]()[], Int32)
ushort
ToUInt16(array[]()[], Int32)
uint
ToUInt32(array[]()[], Int32)
ulong
ToUInt64(array[]()[], Int32)
Example This example initializes an array of bytes, reverses the array if the computer architecture is little-endian (that is, the least significant byte is stored first), and then calls the ToInt32(array[]()[], Int32) method to convert four bytes in the array to an int. The second argument to ToInt32(array[]()[], Int32) specifies the start index of the array of bytes. Note: The output may differ depending on the endianess of your computer's architecture. C# कोड कॉपी करें
byte[] bytes = { 0, 0, 0, 25 }; // If the system architecture is little-endian (that is, little end first), // reverse the byte array. if (BitConverter.IsLittleEndian) Array.Reverse(bytes); int i = BitConverter.ToInt32(bytes, 0); Console.WriteLine("int: {0}", i); // Output: int: 25 In this example, the GetBytes(Int32) method of the BitConverter class is called to convert an int to an array of bytes. Note:
The output may differ depending on the endianess of your computer's architecture. C# कोड कॉपी करें
byte[] bytes = BitConverter.GetBytes(201805978); Console.WriteLine("byte array: " + BitConverter.ToString(bytes)); // Output: byte array: 9A-50-07-0C How to: Convert a string to an int (C# Programming Guide) These examples show some different ways you can convert a string to an int. Such a conversion can be useful when obtaining numerical input from a command line argument, for example. Similar methods exist for converting strings to other numeric types, such as float or long. The table below lists some of those methods. Numeric Type
Method
decimal
ToDecimal(String)
float
ToSingle(String)
double
ToDouble(String)
short
ToInt16(String)
long
ToInt64(String)
ushort
ToUInt16(String)
uint
ToUInt32(String)
ulong
ToUInt64(String)
Example This example calls the ToInt32(String) method to convert an input string to an int . The program catches the two most common exceptions that can be thrown by this method. If the number can be incremented without overflowing the integer storage location, the program adds 1 to the result and prints the output. C# कोड कॉपी करें
int numVal = -1; bool repeat = true; while (repeat == true)
{ Console.WriteLine("Enter a number between −2,147,483,648 and +2,147,483,647 (inclusive)."); string input = Console.ReadLine(); // ToInt32 can throw FormatException or OverflowException. try { numVal = Convert.ToInt32(input); } catch (FormatException e) { Console.WriteLine("Input string is not a sequence of digits."); } catch (OverflowException e) { Console.WriteLine("The number cannot fit in an Int32."); } finally { if (numVal < Int32.MaxValue) { Console.WriteLine("The new value is {0}", numVal + 1); } else { Console.WriteLine("numVal cannot be incremented beyond its current value"); } } Console.WriteLine("Go again? Y/N"); string go = Console.ReadLine(); if (go == "Y" || go == "y") { repeat = true; } else { repeat = false; } } // Keep the console open in debug mode.
Console.WriteLine("Press any key to exit."); Console.ReadKey(); Another way of converting a string to an int is through the Parse or TryParse methods of the System..::.Int32 struct. The ToUInt32 method uses Parse internally. If the string is not in a valid format, Parse throws an exception whereas TryParse does not throw an exception but returns false. The examples below demonstrate both successful and unsuccessful calls to Parse and TryParse. C# कोड कॉपी करें
int numVal = Int32.Parse("-105"); Console.WriteLine(numVal); // Output: -105 C# कोड कॉपी करें
// TryParse returns true if the conversion succeeded // and stores the result in the specified variable. int j; bool result = Int32.TryParse("-105", out j); if (true == result) Console.WriteLine(j); else Console.WriteLine("String could not be parsed."); // Output: -105 C# कोड कॉपी करें
try {
int m = Int32.Parse("abc"); } catch (FormatException e) { Console.WriteLine(e.Message); } // Output: Input string was not in a correct format. C# string inputString = "abc"; int numValue; bool parsed = Int32.TryParse(inputString, out numValue); if (!parsed) Console.WriteLine("Int32.TryParse could not parse '{0}' to an int.\n", inputString);
// Output: Int32.TryParse could not parse 'abc' to an int
ASP.NET Model View Controller (MVC) [Note: This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.] The Model-View-Controller (MVC) pattern is an architectural design principle that separates the components of a Web application. This separation gives you more control over the individual parts of the
application, which lets you more easily develop, modify, and test them. ASP.NET MVC is part of the ASP.NET framework. Developing an ASP.NET MVC application is an alternative to developing ASP.NET Web Forms pages; it does not replace the Web Forms model. You can also download and install the ASP.NET MVC 2 Preview 2 framework from the ASP.NET MVC 2 Beta page on the Microsoft Download Center. Note An earlier version of the MVC Framework (ASP.NET MVC 1.0) is also available. If you are working with an application that is specifically written to work with that version of the MVC framework, you can download ASP.NET MVC 1.0 from the ASP.NET MVC 1.0 page on the Microsoft Download Center. Content Map for ASP.NET MVC We suggest the following progression of documentation to help you learn about ASP.NET MVC. Scenario
Topics ASP.NET MVC Overview
Getting started with ASP.NET MVC
Walkthrough: Creating a Basic MVC Project with Unit Tests in Visual Studio Creating a Tasklist Application with ASP.NET MVC (video on the ASP.NET Web site) System.Web.Mvc namespace
Understanding models, views, Controllers and Action Methods in MVC and controllers Applications Views and UI Rendering in MVC Applications Models and Model Binders in MVC Applications Using an Asynchronous Controller in ASP.NET MVC
Understanding Models, Views, and Controllers (video on the ASP.NET Web site) Episode 1 with Paul Litwin - Creating a Data Driven MVC Application (video on the ASP.NET Web site) Episode 2 with Paul Litwin - Creating the Controller and View (video on the ASP.NET Web site) MVC Framework and Application Structure Understanding ASP.NET MVC project structure
Understanding the MVC Application Execution Process Walkthrough: Organizing an ASP.NET MVC Application using Functional Areas
Understanding URL routing in ASP.NET Routing ASP.NET MVC How to: Add a View to an MVC Application in Visual Studio Rendering a Form in ASP.NET MVC Using HTML Helpers
Working with views
Passing Data in an ASP.NET MVC Application Walkthrough: Using Templated Helpers to Display Data Creating Custom HTML Helpers (tutorial on the ASP.NET Web site) Creating Page Layouts with View Master Pages (video on the ASP.NET Web site)
Working with models
Validating Model Data in an MVC Application How to: Validate Model Data Using DataAnnotations Attributes Creating Model Classes with LINQ to SQL (tutorial on the ASP.NET Web site)
Displaying a Table of Database Data (tutorial on the ASP.NET Web site) Creating Model Classes with the Entity Framework (tutorial on the ASP.NET Web site) Using AJAX in ASP.NET MVC applications
Walkthrough: Adding ASP.NET AJAX Scripting to an MVC Project Action Filtering in MVC Applications
Filtering action methods
Creating Custom Action Filters How to: Create a Custom Action Filter
Handling errors in MVC applications
HandleErrorAttribute class AuthorizeAttribute class Preventing JavaScript Injection (XSS) Attacks (tutorial on the ASP.NET Web site) Preventing Cross-Site Request Forgery (CSRF) attacks (tutorial on the ASP.NET Web site)
Securing MVC applications
SQL Injection (SQL Server 2008 Books Online) How To: Protect From SQL Injection in ASP.NET (Patterns & practices) Authenticating Users with Forms Authentication (tutorial on the ASP.NET Web site) Authenticating Users with Windows Authentication (tutorial on the ASP.NET Web site)
Improving ASP.NET MVC application performance Testing MVC applications
OutputCacheAttribute class Adding Dynamic Content to a Cached Page (tutorial on the ASP.NET Web site) How to: Add a Custom MVC Test Framework in Visual Studio
Walkthrough: Creating a Basic MVC Project with Unit Tests in Visual Studio Creating Unit Tests for ASP.NET MVC Applications (tutorial on the ASP.NET Web site) How to: Deploy an ASP.NET MVC Application Deploying MVC applications
Using ASP.NET MVC with Different Versions of IIS (tutorial on the ASP.NET Web site) ASP.NET 1.0 (Scott Guthrie) ASP.NET MVC 2 Preview 1 Release (Scott Guthrie) VS10 Beta 2 from an ASP.NET MVC Perspective (Phil Haack) Default Templated Views (Phil Haack) JSON Hijacking (Phil Haack)
Using jQuery Grid with ASP.NET MVC Learning more about ASP.NET (Phil Haack) MVC from blog entries written Scripting ASP.NET MVC Views Stored in by ASP.NET MVC experts the Database (Phil Haack) Hanselminutes on 9 - ASP.NET MVC 2 Preview 1 Released (Video by Scott Hanselman) ASP.NET Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries (Scott Hanselman) Building Web Apps without Web Forms (Chris Tavares)
ASP.NET MVC Overview [Note: This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.] The Model-View-Controller (MVC) architectural pattern separates an application into three main components: the model, the view, and the
controller. The ASP.NET MVC framework provides an alternative to the ASP.NET Web Forms pattern for creating Web applications. The ASP.NET MVC framework is a lightweight, highly testable presentation framework that (as with Web Forms-based applications) is integrated with existing ASP.NET features, such as master pages and membership-based authentication. The MVC framework is defined in the System.Web.Mvc assembly. MVC design pattern
MVC is a standard design pattern that many developers are familiar with. Some types of Web applications will benefit from the MVC framework. Others will continue to use the traditional ASP.NET application pattern that is based on Web Forms and postbacks. Other types of Web applications will combine the two approaches; neither approach excludes the other. The MVC framework includes the following components: •
Models. Model objects are the parts of the application that implement the logic for the application's data domain. Often, model objects retrieve and store model state in a database. For example, a Product object might retrieve information from a database, operate on it, and then write updated information back to a Products table in a SQL Server database. In small applications, the model is often a conceptual separation instead of a physical one. For example, if the application only reads a dataset and sends it to the view, the application does not have a physical model layer and associated classes. In that case, the dataset takes on the role of a model object.
•
Views. Views are the components that display the application's user interface (UI). Typically, this UI is created from the model data. An example would be an edit view of a Products table that displays text boxes, drop-down lists, and check boxes based on the current state of a Product object.
•
Controllers. Controllers are the components that handle user interaction, work with the model, and ultimately select a view to render that displays UI. In an MVC application, the view only displays information; the controller handles and responds to user input and interaction. For example, the controller handles querystring values, and passes these values to the model, which in turn might use these values to query the database.
The MVC pattern helps you create applications that separate the different aspects of the application (input logic, business logic, and UI logic), while providing a loose coupling between these elements. The pattern specifies where each kind of logic should be located in the application. The UI logic belongs in the view. Input logic belongs in the controller. Business logic belongs in the model. This separation helps you manage complexity when you build an application, because it enables you to focus on one aspect of the implementation at a time. For example, you can focus on the view without depending on the business logic. The loose coupling between the three main components of an MVC application also promotes parallel development. For example, one developer can work on the view, a second developer can work on the controller logic, and a third developer can focus on the business logic in the model. Support for Test-Driven Development In addition to managing complexity, the MVC pattern makes it easier to test applications than it is to test a Web Forms-based ASP.NET Web application. For example, in a Web Forms-based ASP.NET Web application, a single class is used both to display output and to respond to user input. Writing automated tests for Web Forms-based ASP.NET applications can be complex, because to test an individual page, you must instantiate the page class, all its child controls, and additional dependent classes in the application. Because so many classes are instantiated to run the page, it can be hard to write tests
that focus exclusively on individual parts of the application. Tests for Web Forms-based ASP.NET applications can therefore be more difficult to implement than tests in an MVC application. Moreover, tests in a Web Forms-based ASP.NET application require a Web server. The MVC framework decouples the components and makes heavy use of interfaces, which makes it possible to test individual components in isolation from the rest of the framework. When to Create an MVC Application You must consider carefully whether to implement a Web application by using either the ASP.NET MVC framework or the ASP.NET Web Forms model. The MVC framework does not replace the Web Forms model; you can use either framework for Web applications. (If you have existing Web Forms-based applications, these continue to work exactly as they always have.) Before you decide to use the MVC framework or the Web Forms model for a specific Web site, weigh the advantages of each approach. Advantages of an MVC-Based Web Application The ASP.NET MVC framework offers the following advantages: •
It makes it easier to manage complexity by dividing an application into the model, the view, and the controller.
•
It does not use view state or server-based forms. This makes the MVC framework ideal for developers who want full control over the behavior of an application.
•
It uses a Front Controller pattern that processes Web application requests through a single controller. This enables you to design an application that supports a rich routing infrastructure. For more information, see Front Controller.
•
It provides better support for test-driven development (TDD).
•
It works well for Web applications that are supported by large teams of developers and for Web designers who need a high degree of control over the application behavior.
Advantages of a Web Forms-Based Web Application The Web Forms-based framework offers the following advantages:
•
It supports an event model that preserves state over HTTP, which benefits line-of-business Web application development. The Web Forms-based application provides dozens of events that are supported in hundreds of server controls.
•
It uses a Page Controller pattern that adds functionality to individual pages. For more information, see Page Controller.
•
It uses view state on server-based forms, which can make managing state information easier.
•
It works well for small teams of Web developers and designers who want to take advantage of the large number of components available for rapid application development.
•
In general, it is less complex for application development, because the components (the Page class, controls, and so on) are tightly integrated and usually require less code than the MVC model.
Features of the ASP.NET MVC Framework The ASP.NET MVC framework provides the following features: •
Separation of application tasks (input logic, business logic, and UI logic), testability, and test-driven development (TDD). All core contracts in the MVC framework are interface-based and can be tested by using mock objects, which are simulated objects that imitate the behavior of actual objects in the application. You can unit-test the application without having to run the controllers in an ASP.NET process, which makes unit testing fast and flexible. You can use any unit-testing framework that is compatible with the .NET Framework.
•
An extensible and pluggable framework. The components of the ASP.NET MVC framework are designed so that they can be easily replaced or customized. You can plug in your own view engine, URL routing policy, action-method parameter serialization, and
other components. The ASP.NET MVC framework also supports the use of Dependency Injection (DI) and Inversion of Control (IOC) container models. DI enables you to inject objects into a class, instead of relying on the class to create the object itself. IOC specifies that if an object requires another object, the first objects should get the second object from an outside source such as a configuration file. This makes testing easier. •
Extensive support for ASP.NET routing, which is a powerful URLmapping component that lets you build applications that have comprehensible and searchable URLs. URLs do not have to include file-name extensions, and are designed to support URL naming patterns that work well for search engine optimization (SEO) and representational state transfer (REST) addressing.
•
Support for using the markup in existing ASP.NET page (.aspx files), user control (.ascx files), and master page (.master files) markup files as view templates. You can use existing ASP.NET features with the ASP.NET MVC framework, such as nested master pages, in-line expressions (<%= %>), declarative server controls, templates, data-binding, localization, and so on.
•
Support for existing ASP.NET features. ASP.NET MVC lets you use features such as forms authentication and Windows authentication, URL authorization, membership and roles, output and data caching, session and profile state management, health monitoring, the configuration system, and the provider architecture.
MVC Framework and Application Structure [Note: This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.] In an ASP.NET Web site, URLs typically map to files that are stored on disk (usually .aspx files). These .aspx files include markup and code that is processed in order to respond to the request.
The ASP.NET MVC framework maps URLs to server code differently than an ASP.NET Web Forms page. Instead of mapping URLs to ASP.NET pages or handlers, the framework maps URLs to controller classes. Controller classes handle incoming requests, such as user input and interactions, and execute appropriate application and data logic, based on user input. A controller class typically calls a separate view component that generates HTML output as the response. The ASP.NET MVC framework separates the model, view, and controller components. The model represents the business/domain logic of the application, typically with data backed by a database. The view is selected by the controller and renders the appropriate UI. By default, the ASP.NET MVC framework uses the existing ASP.NET page (.aspx), master page (.master), and user control (.ascx) types for rendering to the browser. The controller locates the appropriate action method in the controller, gets values to use as the action method's arguments, and handles any errors that might occur when the action method runs. It then renders the requested view. By default, each set of components is in a separate folder of an MVC Web application project. URL Routing The ASP.NET MVC framework uses the ASP.NET routing engine, which provides flexibility for mapping URLs to controller classes. You can define routing rules that the ASP.NET MVC framework uses in order to evaluate incoming URLs and to select the appropriate controller. You can also have the routing engine automatically parse variables that are defined in the URL, and have the ASP.NET MVC framework pass the values to the controller as parameter arguments. For more information, see ASP.NET Routing. The MVC Framework and Postbacks ASP.NET MVC framework does not use the ASP.NET Web Forms postback model for interactions with the server. Instead, all end-user interactions are routed to a controller class. This maintains separation between UI logic and business logic and helps testability. As a result, ASP.NET view state and ASP.NET Web Forms page life-cycle events are not integrated with MVC-based views. The MVC Project Template The ASP.NET MVC framework includes a Visual Studio project template that helps you create Web applications that are structured to support the MVC pattern. This template creates a new MVC Web application that is configured to have the required folders, item templates, and configuration-file entries.
Note The ASP.NET MVC Web Application project templates are based on the ASP.NET Web Application project template. You select a new ASP.NET MVC project by selecting New Project from the File menu instead of by selecting New Web Site. When you create a new MVC Web application, Visual Studio gives you the option to create two projects at the same time. The first project is a Web project where you implement your application. The second project is a unit-test project where you can write unit tests for the MVC components in the first project. Note Microsoft Visual Studio Standard Edition and Microsoft Visual Web Developer Express do not support creating unit test projects. Therefore, they do not offer the option to create a test project when you create an MVC application. You can use any unit-testing framework that is compatible with the .NET Framework in order to test ASP.NET MVC applications. Visual Studio Professional Edition includes testing-project support for MSTest. For more information about MSTest, see MSTest.exe Command-Line Options. Web Application MVC Project Structure When you create an ASP.NET MVC Web application project, MVC components are separated based on the project folders shown in the following illustration:
By default, MVC projects include the following folders: •
App_Data, which is the physical store for data. This folder has the same role as it does in ASP.NET Web sites that use Web Forms pages.
•
Content, which is the recommended location to add content files such as cascading style sheet files, images, and so on. In general, the Content folder is for static files.
•
Controllers, which is the recommended location for controllers. The MVC framework requires the names of all controllers to end with "Controller", such as HomeController, LoginController, or ProductController.
•
Models, which is provided for classes that represent the application model for your MVC Web application. This folder usually includes code that defines objects and that defines the
logic for interaction with the data store. Typically, the actual model objects will be in separate class libraries. However, when you create a new application, you might put classes here and then move them into separate class libraries at a later point in the development cycle. •
Scripts, which is the recommended location for script files that support the application. By default, this folder contains ASP.NET AJAX foundation files and the jQuery library.
•
Views, which is the recommended location for views. Views use ViewPage (.aspx), ViewUserControl (.ascx), and ViewMasterPage (.master) files, in addition to any other files that are related to rendering views. The Views folder contains a folder for each controller; the folder is named with the controller-name prefix. For example, if you have a controller named HomeController, the Views folder contains a folder named Home. By default, when the ASP.NET MVC framework loads a view, it looks for a ViewPage (.aspx) file that has the requested view name in the Views\controllerName folder. By default, there is also a folder named Shared in the Views folder, which does not correspond to any controller. The Shared folder is used for views that are shared across multiple controllers. For example, you can put the Web application's master page in the Shared folder.
In addition to the folders listed previously, an MVC Web application uses code in the Global.asax file to set global URL routing defaults, and it uses the Web.config file to configure the application. Global URL Routing Defaults Routes are initialized in the Application_Start method of the Global.asax file. The following example shows a typical Global.asax file that includes default routing logic. Visual Basic कोड कॉपी करें
Public Class MvcApplication
Inherits System.Web.HttpApplication Shared Sub RegisterRoutes(ByVal routes As RouteCollection) routes.IgnoreRoute("{resource}.axd/{*pathInfo}") ' MapRoute takes the following parameters, in order: ' (1) Route name ' (2) URL with parameters ' (3) Parameter defaults routes.MapRoute( _ "Default", _ "{controller}/{action}/{id}", _ New With {.controller = "Home", .action = "Index", .id = ""} _ ) End Sub Sub Application_Start() RegisterRoutes(RouteTable.Routes) End Sub End Class C# कोड कॉपी करें
public class MvcApplication : System.Web.HttpApplication { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = "" } // Parameter defaults ); } protected void Application_Start() { RegisterRoutes(RouteTable.Routes);
} } Understanding the MVC Application Execution Process [Note: This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.] Requests to an ASP.NET MVC-based Web application first pass through the UrlRoutingModule object, which is an HTTP module. This module parses the request and performs route selection. The UrlRoutingModule object selects the first route object that matches the current request. (A route object is a class that implements RouteBase, and is typically an instance of the Route class.) If no routes match, the UrlRoutingModule object does nothing and lets the request fall back to the regular ASP.NET or IIS request processing. From the selected Route object, the UrlRoutingModule object obtains an object that implements the IRouteHandler interface and that is associated with the Route object. Typically, in an MVC application, this will be an instance of the MvcRouteHandler class. The MvcRouteHandler instance creates an MvcHandler object that implements the IHttpHandler interface. The MvcHandler object then selects the controller that will ultimately handle the request. For more information, see ASP.NET Routing. Note When an ASP.NET MVC Web application runs in IIS 7.0, no file name extension is required for MVC projects. However, in IIS 6.0, the handler requires that you map the .mvc file name extension to the ASP.NET ISAPI DLL. The UrlRoutingModule and MvcRouteHandler classes are the entry points to the ASP.NET MVC framework. They perform the following actions: •
Select the appropriate controller in an MVC Web application.
•
Obtain a specific controller instance.
•
Call the controller's Execute method.
The following table lists the stages of execution for an MVC Web project. Stage
Details
Receive first In the Global.asax file, Route objects are added to the request for the RouteTable object. application Perform routing
The UrlRoutingModule module uses the first matching Route object in the RouteTable collection to create the RouteData object, which it then uses to create a RequestContext object.
Create MVC request handler
The MvcRouteHandler object creates an instance of the MvcHandler class and passes the RequestContext instance to the handler.
Create controller
The MvcHandler object uses the RequestContext instance to identify the IControllerFactory object (typically an instance of the DefaultControllerFactory class) to create the controller instance with.
Execute controller
The MvcHandler instance calls the controller's Execute method.
For controllers that inherit from the ControllerBase class, the ControllerActionInvoker object that is Invoke action associated with the controller determines which action method of the controller class to call, and then calls that method. The action method receives user input, prepares the appropriate response data, and then executes the result by returning a result type. The built-in result types that Execute result can be executed include the following: ViewResult (which renders a view and is the most-often used result type), RedirectToRouteResult, RedirectResult, ContentResult, JsonResult, FileResult, and EmptyResult.
Compatibility of ASP.NET Web Forms and ASP.NET MVC [Note: This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.] If you are an experienced ASP.NET developer, much of your ASP.NET knowledge can be applied when you create ASP.NET MVC application. Because ASP.NET MVC is part of the ASP.NET framework, almost all ASP.NET namespaces, class, and interfaces can be used in MVC applications. This topic describes the strengths of both the ASP.NET Web Forms and ASP.NET MVC models. It then describes the ASP.NET
framework features that you can use in an MVC application and those that you should avoid. Strengths of ASP.NET Web Forms The following list describes the strengths of the ASP.NET Web Forms model for building Web applications. •
Event model. Web Forms supports an event-driven programming style that is like Windows applications. Many events are available, and they are supported by hundreds of server controls.
•
State management. Web Forms reduces the complexity of managing state by using view state and server-based controls.
•
Page-based architecture. Web Forms provides an architecture that combines a page with declarative markup (an .aspx file) with a code-behind file that adds functionality. This structure can make it easy to create pages that implement common tasks, such as responding to user gestures and rendering markup from server code.
•
Rich set of controls. The ASP.NET community has made available hundreds of server controls and components that reduce development time.
Strengths of ASP.NET MVC The following list describes the strengths of the ASP.NET MVC model for building Web applications. •
Separation of concerns. ASP.NET MVC enforces a "separation of concerns", in which the application is divided into discrete and loosely-bound parts—namely, the model, view, and controller parts of the application. This makes MVC applications easier to test and maintain.
•
More control of rendered HTML. MVC significantly increases your control over rendered HTML.
•
Test-driven development. MVC was designed to make test-driven development easier. You can create an MVC project and its test project at the same time. You can then create unit tests for each action method in your application, and run them without invoking the complete request cycle for a Web application.
ASP.NET Framework Features That Are Compatible with MVC It might appear that Web Forms and MVC are very different technologies. However, both of these technologies are built on the ASP.NET framework. Therefore, most ASP.NET framework features that you have used to create applications that are based on Web Forms are also available to you for developing MVC applications. This includes features such as membership, authentication, roles, and configuration, which work the same way in an MVC application as they do in a Web Forms application. Most ASP.NET namespaces, classes, and interfaces can be used in an ASP.NET MVC application. ASP.NET Framework Features That Are Incompatible with MVC Because ASP.NET MVC does not maintain state information by using view state, you must find other ways to manage state information, if you need it. In addition, server controls that rely on view state and postback will not work as designed in an ASP.NET MVC application. Therefore, you should not use controls such as the GridView, Repeater, and DataList controls. The life cycle of a Web Forms page is complex, during which many events occur. These events are not supported in an ASP.NET MVC application, because the interactions between the model, view, and controller use a different life-cycle model. For more information about the MVC life-cycle model, see Understanding the MVC Application Execution Process.
Walkthrough: Creating a Basic MVC Project with Unit Tests in Visual Studio [Note: This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.] This walkthrough shows you how to create an ASP.NET MVC application in Visual Studio. In this walkthrough, you will create and run the sample MVC application. Then you will customize the application by adding a controller and a view.
In addition, this walkthrough shows how to use test-driven development (TDD). In the walkthrough, you create a project that contains unit tests for the MVC application. A Visual Studio project with source code is available to accompany this topic: Download. Prerequisites In order to complete this walkthrough, you will need: •
Microsoft Visual Studio 2008 Service Pack 1 or later. Note Visual Studio Standard Edition and Visual Web Developer Express do not do not support unit-test projects. You can use these versions of Visual Studio to run the parts of this walkthrough that pertain to creating and running an ASP.NET MVC project. However, you will not be able to work with unit tests as described in this walkthrough.
•
ASP.NET MVC 2. You can download the framework from the ASP.NET MVC 2 page on the Microsoft Download Center.
Creating a New MVC Project To begin, you will create a new ASP.NET MVC project. To create a new MVC project 1. On the File menu, click New Project. The New Project dialog box is displayed.
2. In the upper-right corner, make sure that .NET Framework 3.5 is selected. 3. Under Project types, expand either Visual Basic or Visual C#, and then click Web. 4. Under Visual Studio installed templates, select ASP.NET MVC Web Application. 5. In the Name box, enter MvcBasicWalkthrough. 6. In the Location box, enter a name for the project folder. 7. If you want the name of the solution to differ from the project name, enter a name in the Solution Name box. 8. Select Create directory for solution.
9. Click OK. The Create Unit Test Project dialog box is displayed.
Note If you are using the Standard or Express editions of Visual Studio, the Create Unit Test Project dialog box is not displayed. Instead, the new MVC application project is generated without a test project. 10. Select Yes, create a unit test project. By default, the name of the test project is the application project name with "Tests" added. However, you can change the name of the test project. By default, the test project will use the Visual Studio Unit Test framework. For information about how to use a third-party test framework, see How to: Add a Custom MVC Test Framework in Visual Studio. 11. Click OK.
The new MVC application project and a test project are generated. (If you are using the Standard or Express editions of Visual Studio, the test project is not created.) Examining the MVC Project The following illustration shows the folder structure of a newly created MVC solution.
The folder structure of an MVC project differs from that of an ASP.NET Web site project. The MVC project contains the following folders: •
Content, which is for content support files. This folder contains the cascading style sheet (.css file) for the application.
•
Controllers, which is for controller files. This folder contains the application's sample controllers, which are named AccountController and HomeController. The AccountController class contains login logic for the application.
The HomeController class contains logic that is called by default when the application starts. •
Models, which is for data-model files such as LINQ-to-SQL .dbml files or data-entity files.
•
Scripts, which is for script files, such as those that support ASP.NET AJAX and jQuery.
•
Views, which is for view page files. This folder contains three subfolders: Account, Home, and Shared. The Account folder contains views that are used as UI for logging in and changing passwords. The Home folder contains an Index view (the default starting page for the application) and an About page view. The Shared folder contains the master-page view for the application.
If you are using an edition of Visual Studio other than Standard or Express, a test project was also generated. The test project has a Controllers folder that contains the HomeControllerTest class. This class has a unit test for each HomeController action method (Index and About). The newly generated MVC project is a complete application that you can compile and run without change. The following illustration shows what the application looks like when it runs in a browser.
The unit-test project is also ready to compile and run. For this walkthrough, you will add a controller with an action method and a view, and you will add a unit test for the action method. Adding a Controller You will now add a controller that contains logic for downloading city maps from the Microsoft Virtual Earth Web service. To add a controller to the MVC project 1. In Solution Explorer, right-click the Controllers folder, click Add, and then click Controller. The Add Controller dialog box is displayed.
2. In the Name box, type MapsController. The ASP.NET MVC framework requires controller names to end with "Controller", such as HomeController, GameController, or MapsController. 3. Clear the Add action methods for Create, Update, and Details scenarios check box. 4. Click Add. Visual Studio adds the MapsController class to the project and opens it in the editor. Creating an Action-Method Stub To apply test-driven development (TDD) techniques to this project, you should write the unit test for an action method before you write
the action method itself. However, if you want your unit test to compile, you must have a stub for the planned action method, which in this walkthrough is ViewMaps. To add an action-method stub 1. Open or switch to the MapsController class. 2. Replace the Index action method with the following code in order to create the ViewMaps action-method stub. Visual Basic
कोड कॉपी करें
Function ViewMaps() ' Add action logic here Throw New NotImplementedException() End Function C#
कोड कॉपी करें
public ActionResult ViewMaps() { // Add action logic here throw new NotImplementedException(); } Adding Unit Tests for Action Methods Next, you will add a controller test class to the tests project. In the class, you will add a unit test for the ViewMaps action method. The unit test will fail, because the ViewMaps action-method stub throws an exception. When you finish the action method later in this walkthrough, the test will pass. To add unit tests for the action methods
1. In the tests project, right-click the Controllers folder, click Add, and then click New Item. The Add New Item dialog box is displayed.
2. Under Templates, select Class. 3. In the Name text box, type MapsControllerTest. 4. Click Add. Visual Studio adds the MapsControllerTest class to the test project. 5. Open the MapsControllerTest class and enter the following code. Visual Basic
कोड कॉपी करें
Imports System Imports System.Collections.Generic Imports System.Text Imports System.Web.Mvc Imports Microsoft.VisualStudio.TestTools.UnitTesting Imports MvcBasicWalkthrough _ Public Class MapsControllerTest Private testContextInstance As TestContext '''<summary> '''Gets or sets the test context which provides '''information about and functionality for the current test run. ''' Public Property TestContext() As TestContext Get Return testContextInstance End Get Set(ByVal value As TestContext) testContextInstance = value End Set End Property _ Public Sub ViewMaps() ' Arrange Dim controller As MapsController = New MapsController() ' Act Dim result As ViewResult = controller.ViewMaps()
' Assert Assert.IsNotNull(result) End Sub End Class C#
कोड कॉपी करें
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Web.Mvc; using MvcBasicWalkthrough; using MvcBasicWalkthrough.Controllers; namespace MvcBasicWalkthrough.Tests.Controllers { [TestClass] public class MapsControllerTest { [TestMethod] public void ViewMaps() { // Arrange MapsController controller = new MapsController(); // Act
ViewResult result = controller.ViewMaps() as ViewResult; // Assert Assert.IsNotNull(result); } } } This code defines the unit tests for the action method that you will finish later. 6. In Solution Explorer, select the test project and then press CTRL+F5 to run the unit tests. The test fails, because the ViewMaps action method currently throws an exception. Adding Code to the Action Method You will now add code to the MapsController class for the ViewMaps action method in order to render the Maps view. To add code to the action method 1. Open the MapsController class and replace the ViewMaps action-method stub with the following code in order to render the Maps view: Visual Basic
कोड कॉपी करें
Function ViewMaps() As ActionResult Return View() End Function C#
कोड कॉपी करें
public ActionResult ViewMaps() { return View(); } 2. Save and close the file. Adding a View Next, you will add a Maps view. To keep the views organized, you will first add a Maps folder under the Views folder. To add a page-content view to the MVC project 1. Open the MapsController class, right-click inside the ViewMaps action method, and then click Add View. The Add View dialog box is displayed.
2. In the View name box, enter ViewMaps.aspx. 3. Clear the Create a partial view (.ascx) check box and the Create a strongly-typed view check box. 4. Select the Select master page check box and set the master page to ~/Views/Shared/Site.Master. 5. Set ContentPlaceHolder ID to "MainContent". 6. Click Add. The new view is added to the project in the Maps folder. Adding Content to the View Next, you will add content to the new view. To add content to the view
1. Open ViewMaps.aspx and add the following content inside the Content element: None
var map = null; var mapID = ''; function GetMap(mapID) { switch (mapID) { case 'Seattle': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(47.6, -122.33), 10 ,'i', true); break; case 'LasVegas': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(36.17, -115.14), 10 ,'i' ,true); break; case 'SaltLake': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(40.75, -111.89), 10 ,'i' ,true); break; case 'Dallas': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(32.78, -96.8), 10 ,'i' ,true); break; case 'Chicago': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(41.88, -87.62), 10 ,'i' ,true); break; case 'NewYork': map = new VEMap('earthMap');
map.LoadMap(new VELatLong(40.7, -74), 10 ,'i' ,true); break; case 'Rio': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(-22.91, -43.18), 10 ,'i' ,true); break; case 'Paris': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(48.87, 2.33), 10 ,'i' ,true); break; case 'Naples': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(40.83, 14.25), 10 ,'i' ,true); break; case 'Keta': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(5.92, 0.983), 10 ,'i' ,true); break; case 'Beijing': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(39.91, 116.39), 10 ,'i' ,true); break; case 'Sydney': map = new VEMap('earthMap'); map.LoadMap(new VELatLong(-33.86, 151.21), 10 ,'i' ,true); } }
This markup defines a drop-down list for selecting a map and the JavaScript logic for retrieving the selected map from the Microsoft Virtual Earth Web service. 2. Save and close the file. Adding a Tab to the Master-Page Menu You will now add an item to the master-page menu that calls the ViewMaps action method. To add a tab to the master-page menu 1. In the Shared folder, open the Site.master file and locate the unordered list (ul element) in the div element whose ID is "menucontainer". 2. Add the following code to the list between the Index and About Us tabs: None
कोड कॉपी करें
<%= Html.ActionLink("My City Maps", "ViewMaps", "Maps")%>
The ActionLink method is a helper method that links to an action method. It takes the following parameters: the text for the link, the name of the action method, and the name of the controller. 3. Save and close the file. Testing the MVC Application You can now test the application. To test the MVC application
1. On the Test menu, click Run, and then click All Tests in Solution. The results are displayed in the Test Results window. This time the tests pass. 2. In Solution Explorer, select the walkthrough project and press CTRL+F5 to run the application. The Index.aspx page is displayed, which includes the tabs that are defined in the master page. 3. Click the My City Maps tab. The My City Maps page is displayed. Select any map to see it displayed.
Next Steps This walkthrough gives you a first look at creating an MVC application and working with unit tests in ASP.NET MVC. From here, you might want to learn more about the ASP.NET MVC framework. The following list suggests topics for additional learning. •
For more information about MVC controllers, see Controllers and Action Methods in MVC Applications.
•
For more information about MVC views, see Views and UI Rendering in MVC Applications.
•
For more information about MVC models, see Models and Model Binders in MVC Applications.
•
For more information about URL routing, see ASP.NET Routing.
Controllers and Action Methods in MVC Applications [Note: This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.] The ASP.NET MVC framework maps URLs to classes that are referred to as controllers. Controllers process incoming requests, handle user input and interactions, and execute appropriate application logic. A controller class typically calls a separate view component to generate the HTML markup for the request. The base class for all controllers is the ControllerBase class, which provides general MVC handling. The Controller class inherits from ControllerBase and is the default implement of a controller. The Controller class is responsible for the following processing stages: •
Locating the appropriate action method to call and validating that it can be called.
•
Getting the values to use as the action method's arguments.
•
Handling all errors that might occur during the execution of the action method.
•
Providing the default WebFormViewEngine class for rendering ASP.NET page types (views). Note To help secure access to controllers and action methods, you can use the PrincipalPermissionAttribute class.
All controller classes must be named by using the "Controller" suffix. The following example shows the sample controller class, which is named HomeController. This controller class contains action methods that render view pages. Visual Basic कोड कॉपी करें
_ Public Class HomeController Inherits System.Web.Mvc.Controller Function Index() As ActionResult ViewData("Message") = "Welcome to ASP.NET MVC!" Return View()
End Function Function About() As ActionResult Return View() End Function End Class C# कोड कॉपी करें
[HandleError] public class HomeController : Controller { public ActionResult Index() { ViewData["Message"] = "Welcome to ASP.NET MVC!"; return View(); } public ActionResult About() { return View(); } } Action Methods In ASP.NET applications that do not use the MVC framework, user interaction is organized around pages, and around raising and handling events from the page and from controls on the page. In contrast, user interaction with ASP.NET MVC applications is organized around controllers and action methods. The controller defines action methods. Controllers can include as many action methods as needed. Action methods typically have a one-to-one mapping with user interactions. Examples of user interactions include entering a URL into the browser, clicking a link, and submitting a form. Each of these user interactions causes a request to be sent to the server. In each case, the URL of the request includes information that the MVC framework uses to invoke an action method. When a user enters a URL into the browser, the MVC application uses routing rules that are defined in the Global.asax file to parse the URL and to determine the path of the controller. The controller then determines the appropriate action method to handle the request. By default, the URL of a request is treated as a sub-path that includes the controller name followed by the action name. For example, if a user enters the URL http://contoso.com/MyWebSite/Products/Categories, the sub-path
is /Products/Categories. The default routing rule treats "Products" as the name of the controller and "Categories" as the name of the action. Therefore, the routing rule invokes the Categories method of the Products controller in order to process the request. If the URL ends with /Products/Detail/5, the default routing rule treats "Detail" as the name of the action, and the Detail method of the Products controller is invoked to process the request. By default, the value "5" in the URL will be passed to the Detail method as a parameter. The following example shows a controller class that has a Hello action method. Visual Basic कोड कॉपी करें
Public Class MyController Inherits System.Web.Mvc.Controller Function HelloWorld() As ActionResult ViewData("Message") = "Hello World!" Return View() End Function End Class C# कोड कॉपी करें
public class MyController : Controller { public ActionResult HelloWorld() { ViewData["Message"] = "Hello World!"; return View(); } } ActionResult Return Type Most action methods return an instance of a class that derives from ActionResult. The ActionResult class is the base for all action results. However, there are different action result types, depending on the task that the action method is performing. For example, the most common action is to call the View method. The View method returns an instance of the ViewResult class, which is derived from ActionResult. You can create action methods that return an object of any type, such as a string, an integer, or a Boolean value. These return types are wrapped in an appropriate ActionResult type before they are rendered to the response stream.
The following table shows the built-in action result types and the action helper methods that return them. Action Result
Helper Method
Description
View
Renders a view as a Web page.
PartialViewResult
PartialView
Renders a partial view, which defines a section of a view that can be rendered inside another view.
RedirectResult
Redirect
Redirects to another action method by using its URL.
RedirectToRouteResult
RedirectToAction Redirects to another action RedirectToRoute method.
ContentResult
Content
Returns a user-defined content type.
JsonResult
Json
Returns a serialized JSON object.
JavaScriptResult
JavaScript
Returns a script that can be executed on the client.
FileResult
File
Returns binary output to write to the response.
(None)
Represents a return value that is used if the action method must return a null result (void).
ViewResult
EmptyResult
Marking Public Methods as Non-Action Methods By default, the MVC framework treats all public methods of a controller class as action methods. If your controller class contains a public method and you do not want it to be an action method, you must mark that method with the NonActionAttribute attribute. The following example shows a method that is marked with the NonAction attribute. Visual Basic कोड कॉपी करें
_
Private Sub DoSomething() ' Method logic. End Sub C# कोड कॉपी करें
[NonAction] private void DoSomething() { // Method logic. } Action Method Parameters By default, the values for action method parameters are retrieved from the request's data collection. The data collection includes name/values pairs for form data, query string values, and cookie values. The controller class locates the action method and determines any parameter values for the action method, based on the RouteData instance and based on the form data. If the parameter value cannot be parsed, and if the type of the parameter is a reference type or a nullable value type, null is passed as the parameter value. Otherwise, an exception is thrown. There are several ways to access URL parameter values in the action methods of controller classes. The Controller class exposes Request and Response properties that can be accessed in an action method. These properties have the same semantics as the HttpRequest and HttpResponse objects that are already a part of ASP.NET. However, the Request and Response objects of the Controller class accept objects that implement the HttpRequestBase and HttpResponseBase abstract classes instead of being sealed classes. These base classes make it easy to create mock objects, which in turn makes it easy to create unit tests for controller classes. The following example shows how to use the Request object to retrieve a query-string value named id. Visual Basic कोड कॉपी करें
Public Sub Detail() Dim id As Integer = Convert.ToInt32(Request("id")) End Sub C# कोड कॉपी करें
public void Detail() {
int id = Convert.ToInt32(Request["id"]); } Automatically Mapping Action-Method Parameters The ASP.NET MVC framework can automatically map URL parameter values to parameter values for action methods. By default, if an action method takes a parameter, the MVC framework examines incoming request data and determines whether the request contains an HTTP request value with the same name. If so, the request value is automatically passed to the action method. The following example shows a variation of the previous example. In this variation, the id parameter is assumed to map to a request value that is also named id. Because of this automatic mapping, the action method does not have to include code to get a parameter value from the request, and the parameter value is therefore easier to use. Visual Basic कोड कॉपी करें
Public Function Detail(ByVal id As Integer) ViewData("DetailInfo") = id Return View() End Function C# कोड कॉपी करें
public ResultAction Detail(int id) { ViewData["DetailInfo"] = id; return View(); } You can also embed parameter values as part of the URL instead of as query-string values. For example, instead of using the URL with a query string such as /Products/Detail?id=3, you can use a URL like /Products/Detail/3. The default route-mapping rule has the format /{controller}/{action}/{id}. If there is a URL sub-path after the controller and action names in the URL, it is treated as a parameter named id, and is automatically passed to the action method as a parameter value. The MVC framework also supports optional arguments for action methods. Optional parameters in the MVC framework are handled by using nullable-type arguments for controller action methods. For example, if a method can take a date as part of the query string but you want to the default to be today's date if the query string
parameter is missing, you can use code like that in the following example: Visual Basic कोड कॉपी करें
Public Function ShowArticles(ByVal date As DateTime?) If Not date.HasValue Then date = DateTime.Now End If ' ... End Function C# कोड कॉपी करें
public ActionResult ShowArticles(DateTime? date) { if(!date.HasValue) { date = DateTime.Now; } // ... } If the request includes a value for the date parameter, that value is passed to the ShowArticles method. If the request does not include a value for this parameter, the argument is null, and the controller can take whatever actions are required in order to handle the missing parameter. Rendering a Form in ASP.NET MVC Using HTML Helpers [Note: This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.] The ASP.NET MVC framework includes helper methods that provide an easy way to render HTML in a view. This topic explains how to work with the most frequently used HTML helpers. The last section shows an example that incorporates the HTML helpers described in this topic. Available HTML Helpers The following list shows some of the currently available HTML helpers. The helpers listed with an asterisk (*) are demonstrated in this topic. •
ActionLink — Links to an action method.
•
BeginForm * — Marks the start of a form and links to the action method that renders the form.
•
CheckBox * — Renders a check box.
•
DropDownList * — Renders a drop-down list.
•
Hidden — Embeds information in the form that is not rendered for the user to see.
•
ListBox — Renders a list box.
•
Password — Renders a text box for entering a password.
•
RadioButton * — Renders a radio button.
•
TextArea — Renders a text area (multi-line text box).
•
TextBox * — Renders a text box.
Using the BeginForm Helper The BeginForm helper marks the start of an HTML form and renders as an HTML form element. The BeginForm helper method has several overrides. The version of the BeginForm helper shown in the following example takes two parameters, the names of the action method and the controller to submit the form. The BeginForm helper implements the IDisposable interface, which enables you to use the using keyword (Using in Visual Basic), similar to ASP.NET AJAX usage. The following example shows how to use the BeginForm helper in a using pattern. Visual Basic कोड कॉपी करें
<% Using Html.BeginForm("HandleForm", "Home") %> <% End Using %> C# कोड कॉपी करें
<% using(Html.BeginForm("HandleForm", "Home")) %> <% { %> <% } %> You can also use the BeginForm helper declaratively. The difference between using BeginForm declaratively and using an HTML form tag is that BeginForm assigns default value for the action method and
action attributes, which simplifies the markup. The following example uses declarative markup to mark the start and ending of a form. Visual Basic कोड कॉपी करें
<% Html.BeginForm() %> <% Html.EndForm() %> C# कोड कॉपी करें
<% Html.BeginForm(); %> <% Html.EndForm(); %> Using the CheckBox Helper The CheckBox helper method renders a check box that has the name that you specify. The rendered control returns a Boolean value (true or false). The following example shows markup for the CheckBox helper method. कोड कॉपी करें
<%= Html.CheckBox("bookType") %> Using the DropDownList Helper The DropDownList helper renders a drop-down list. In its simplest form, DropDownList takes one parameter, the name of the ViewData key whose value is of type SelectList and that contains the option values for the drop-down list. The MVC framework uses the ModelState property of ViewData to determine the selected value. If the ModelState property is empty, the framework looks for an item whose Selected property is set. The following example shows markup for the DropDownList helper method. कोड कॉपी करें
<%= Html.DropDownList("pets") %> Note Both the DropDownList and ListBox helpers accept either a SelectList or MultiSelectList object. The following code is a part of an Index action method in which values are added to a List object. The List object is passed to an instance of SelectList, which is then added to the ViewData object. Visual Basic
कोड कॉपी करें
Dim petList As List(Of String) = New List(Of String) petList.Add("Dog") petList.Add("Cat") petList.Add("Hamster") petList.Add("Parrot") petList.Add("Gold fish") petList.Add("Mountain lion") petList.Add("Elephant") ViewData("pets") = New SelectList(petList) C# कोड कॉपी करें
List<string> petList = new List<string>(); petList.Add("Dog"); petList.Add("Cat"); petList.Add("Hamster"); petList.Add("Parrot"); petList.Add("Gold fish"); petList.Add("Mountain lion"); petList.Add("Elephant"); ViewData["Pets"] = new SelectList(petList); Using the RadioButton Helper The RadioButton helper method renders a radio button. In its simplest form, the method takes three parameters: the name of the control group, the option value, and a Boolean value that determines whether the radio button is selected initially. The following markup shows markup for the RadioButton helper method. कोड कॉपी करें
Select your favorite color: <%= Html.RadioButton("favColor", "Blue", true) %> Blue <%= Html.RadioButton("favColor", "Purple", false)%> Purple <%= Html.RadioButton("favColor", "Red", false)%> Red <%= Html.RadioButton("favColor", "Orange", false)%> Orange <%= Html.RadioButton("favColor", "Yellow", false)%> Yellow <%= Html.RadioButton("favColor", "Brown", false)%> Brown <%= Html.RadioButton("favColor", "Green", false)%> Green Using the TextBox Helper
The TextBox helper method renders a text box that has the specified name. The following markup shows markup for the TextBox helper method. कोड कॉपी करें
Enter your name: <%= Html.TextBox("name") %> Example Application The following example is a complete example from which the previous examples where taken. The Index page displays a form that implements HTML helper methods. When the user submits the form, the form is handled by the HandleForm action method, which generates a view that displays the information that the user submitted. The following example shows the HomeController class. Visual Basic कोड कॉपी करें
_ Public Class HomeController Inherits System.Web.Mvc.Controller Function Index() As ActionResult ViewData("Message") = "Welcome to ASP.NET MVC!" Dim petList As List(Of String) = New List(Of String) petList.Add("Dog") petList.Add("Cat") petList.Add("Hamster") petList.Add("Parrot") petList.Add("Gold fish") petList.Add("Mountain lion") petList.Add("Elephant") ViewData("pets") = New SelectList(petList) Return View() End Function Function About() As ActionResult Return View() End Function Public Function HandleForm(ByVal name As String, ByVal favColor As String, ByVal bookType As Boolean, ByVal pets As String) As ActionResult
ViewData("name") = name ViewData("favColor") = favColor ViewData("bookType") = bookType ViewData("pet") = pets Return View("FormResults") End Function End Class C# कोड कॉपी करें
namespace MvcHtmlHelpers.Controllers { [HandleError] public class HomeController : Controller { public ActionResult Index() { ViewData["Message"] = "Welcome to ASP.NET MVC!"; List<string> petList = new List<string>(); petList.Add("Dog"); petList.Add("Cat"); petList.Add("Hamster"); petList.Add("Parrot"); petList.Add("Gold fish"); petList.Add("Mountain lion"); petList.Add("Elephant"); ViewData["Pets"] = new SelectList(petList); return View(); } public ActionResult About() { return View(); } public ActionResult HandleForm(string name, string favColor, Boolean bookType, string pets)
{ ViewData["name"] = name; ViewData["favColor"] = favColor; ViewData["bookType"] = bookType; ViewData["pet"] = pets; return View("FormResults"); } } } The following example shows the Index view. Visual Basic कोड कॉपी करें
<%= Html.Encode(ViewData("Message")) %>
<% Using Html.BeginForm("HandleForm", "Home")%> Enter your name: <%= Html.TextBox("name") %>
Select your favorite color: <%= Html.RadioButton("favColor", "Blue", true) %> Blue <%= Html.RadioButton("favColor", "Purple", false)%> Purple <%= Html.RadioButton("favColor", "Red", false)%> Red <%= Html.RadioButton("favColor", "Orange", false)%> Orange <%= Html.RadioButton("favColor", "Yellow", false)%> Yellow <%= Html.RadioButton("favColor", "Brown", false)%> Brown <%= Html.RadioButton("favColor", "Green", false)%> Green
<%=Html.CheckBox("bookType")%> I read more fiction than non-fiction.
My favorite pet: <%=Html.DropDownList("pets")%>
<% End Using%> C# कोड कॉपी करें
<%= Html.Encode(ViewData["Message"]) %>
<% using(Html.BeginForm("HandleForm", "Home")) %> <% { %> Enter your name: <%= Html.TextBox("name") %>
Select your favorite color: <%= Html.RadioButton("favColor", "Blue", true) %> Blue <%= Html.RadioButton("favColor", "Purple", false)%> Purple <%= Html.RadioButton("favColor", "Red", false)%> Red <%= Html.RadioButton("favColor", "Orange", false)%> Orange <%= Html.RadioButton("favColor", "Yellow", false)%> Yellow <%= Html.RadioButton("favColor", "Brown", false)%> Brown <%= Html.RadioButton("favColor", "Green", false)%> Green
<%= Html.CheckBox("bookType") %> I read more fiction than non-fiction.
My favorite pet: <%= Html.DropDownList("pets") %>
<% } %> The following example shows the FormResults view. Visual Basic कोड कॉपी करें
FormResults
Your name: <%=Html.Encode(ViewData("name"))%>
Your favorite color: < %=Html.Encode(ViewData("favColor"))%>
<% If (ViewData("bookType").Equals(True)) Then%>
You read more fiction than non-fiction.
<% Else%>
You read more non-fiction than fiction.
<% End If%> Your favorite pet: <%=Html.Encode(ViewData("pet"))%> C#
कोड कॉपी करें
FormResults
Your name: <%= Html.Encode(ViewData["name"])%>
Your favorite color: <%= Html.Encode(ViewData["favColor"]) %>
<% if (ViewData["bookType"].Equals(true)) { %>
You read more fiction than non-fiction.
<% } else { %>
You read more non-fiction than fiction.
<% } %> Your favorite pet: <%= Html.Encode(ViewData["pet"]) %> Passing Data in an ASP.NET MVC Application [Note: This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.] The ASP.NET MVC framework provides page-level containers for passing data between controllers and views. This topic explains how to pass both weakly typed and strongly typed data in an MVC application. It also explains how to pass temporary state data between action methods. Passing Data Between a Controller and a View To render a view, you call the View method of the controller. To pass data to the view, you use the ViewData property of the ViewPage class. This property returns a ViewDataDictionary object that has caseinsensitive string keys. To pass data to the view, you can assign values to the dictionary, as shown in the following example: Visual Basic कोड कॉपी करें
Dim petList As List(Of String) = New List(Of String) petList.Add("Dog") petList.Add("Cat") petList.Add("Hamster") petList.Add("Parrot") petList.Add("Gold fish")
petList.Add("Mountain lion") petList.Add("Elephant") ViewData("pets") = New SelectList(petList) C# कोड कॉपी करें
List<string> petList = new List<string>(); petList.Add("Dog"); petList.Add("Cat"); petList.Add("Hamster"); petList.Add("Parrot"); petList.Add("Gold fish"); petList.Add("Mountain lion"); petList.Add("Elephant"); ViewData["Pets"] = new SelectList(petList); If you call the View method without parameters (as shown in the previous example), the controller object's ViewData property is passed to the view that has the same name as the action method. In the view page, you can access the ViewData property to obtain data that was passed to the view. The ViewData property is a dictionary that supports an indexer that accepts dictionary keys. The following example shows the markup for a view that displays the data in an HTML form and enables the user to modify values and make selections. Visual Basic कोड कॉपी करें
<%= Html.Encode(ViewData("Message")) %>
<% Using Html.BeginForm("HandleForm", "Home")%> Enter your name: <%= Html.TextBox("name") %>
Select your favorite color: <%= Html.RadioButton("favColor", "Blue", true) %> Blue <%= Html.RadioButton("favColor", "Purple", false)%> Purple <%= Html.RadioButton("favColor", "Red", false)%> Red <%= Html.RadioButton("favColor", "Orange", false)%> Orange <%= Html.RadioButton("favColor", "Yellow", false)%> Yellow
<%= Html.RadioButton("favColor", "Brown", false)%> Brown <%= Html.RadioButton("favColor", "Green", false)%> Green
<%=Html.CheckBox("bookType")%> I read more fiction than non-fiction.
My favorite pet: <%=Html.DropDownList("pets")%>
<% End Using%> C# कोड कॉपी करें
<%= Html.Encode(ViewData["Message"]) %>
<% using(Html.BeginForm("HandleForm", "Home")) %> <% { %> Enter your name: <%= Html.TextBox("name") %>
Select your favorite color: <%= Html.RadioButton("favColor", "Blue", true) %> Blue <%= Html.RadioButton("favColor", "Purple", false)%> Purple <%= Html.RadioButton("favColor", "Red", false)%> Red <%= Html.RadioButton("favColor", "Orange", false)%> Orange <%= Html.RadioButton("favColor", "Yellow", false)%> Yellow <%= Html.RadioButton("favColor", "Brown", false)%> Brown <%= Html.RadioButton("favColor", "Green", false)%> Green
<%= Html.CheckBox("bookType") %> I read more fiction than non-fiction.
My favorite pet: <%= Html.DropDownList("pets") %>
<% } %> Passing Strongly-Typed Data Between a Controller and a View When you pass data between a view and a controller by using the ViewData property of the ViewPage class, the data is not strongly
typed. If you want to pass strongly typed data, change the @ Page declaration of the view so that the view inherits from ViewPage<(Of <(TModel>)>) instead of from ViewPage, as shown in the following example: कोड कॉपी करें
<%@ Page Inherits="ViewPage" %> ViewPage<(Of <(TModel>)>) is the strongly-typed version of ViewPage. The ViewData property of ViewPage<(Of <(TModel>)>) returns a ViewDataDictionary<(Of <(TModel>)>) object, which contains strongly typed data for the view based on a model. The model is a class that contains properties for each data item that you want to pass. The following example shows the definition of a typical data model class named Person. Visual Basic कोड कॉपी करें
Public Class Person Private _Id As Integer Public Property Id() As Integer Get Return _Id End Get Set(ByVal value As Integer) _Id = value End Set End Property Private _Name As String Public Property Name() As String Get Return _Name End Get Set(ByVal value As String) _Name = value End Set End Property Private _Age As Integer Public Property Age() As Integer Get Return _Age End Get Set(ByVal value As Integer)
_Age = value End Set End Property End Class C# कोड कॉपी करें
public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } The following example shows a view that enables the user to modify the values of a Person object and to submit the changes for update. Visual Basic कोड कॉपी करें
Edit
<%=Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.")%> <% Using Html.BeginForm() %>
<% End Using %>
<%=Html.ActionLink("Back to List", "Index") %>
C# कोड कॉपी करें
Edit
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %> <% using (Html.BeginForm()) {%> <% } %>
<%=Html.ActionLink("Back to List", "Index") %>
The following example shows the action method that receives a Person object from the Edit view, checks its validity against the model, updates a list of Person objects, and then redirects to the Index action.
Visual Basic कोड कॉपी करें
_ Function Edit(ByVal p As Person) As ActionResult If Not ModelState.IsValid Then Return View("Edit", p) End If For Each pn As Person In people If pn.Id = p.Id Then pn.Name = p.Name pn.Age = p.Age pn.Id = p.Id End If Next Return RedirectToAction("Index") End Function C# कोड कॉपी करें
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(Person p) { if (!ModelState.IsValid) { return View("Edit", p); } foreach (Person pn in people) { if (pn.Id == p.Id) { pn.Name = p.Name; pn.Age = p.Age; pn.Id = p.Id; } } return RedirectToAction("Index"); } Passing State Between Action Methods Action methods might have to pass data to the next action, such as if an error occurs when a form is being posted. In that case, the user might be redirected to another view that displays error information.
An action method can store data in the controller's TempDataDictionary object before it calls the controller's RedirectToAction method to invoke the next action. The TempData property value is stored in session state. The next action method can get values from the TempDataDictionary object to process or to display in its own view. The value of TempData persists only from one request to the next. The following example shows a data class that is used to trap an error and to transfer data between actions. Visual Basic कोड कॉपी करें
Public Class InsertError Public Property ErrorMessage() As String End Property Public Property OriginalFirstName() As String End Property Public Property OriginalLastName() As String End Property End Class ' CustomersController Public Function InsertCustomer(ByVal firstName As String, _ ByVal lastName As String) As ActionResult ' Check for input errors. If String.IsNullOrEmpty(firstName) Or _ String.IsNullOrEmpty(lastName) Then Dim err As InsertError = New InsertError() err.ErrorMessage = "Both names are required." err.OriginalFirstName = firstName err.OriginalLastName = lastName TempData("error") = err Return RedirectToAction("NewCustomer") End If ' No errors ' ... Return View() End Function Public Function NewCustomer() As ActionResult Dim err As InsertError = CType(TempData("error"), InsertError) If Not err Is Nothing Then
' If there is error data from the previous action, display it. ViewData("FirstName") = err.OriginalFirstName ViewData("LastName") = err.OriginalLastName ViewData("ErrorMessage") = err.ErrorMessage End If ' ... Return View() End Function C# कोड कॉपी करें
public class InsertError { public string ErrorMessage { get; set; } public string OriginalFirstName { get; set; } public string OriginalLastName { get; set; } } // CustomersController public ActionResult InsertCustomer(string firstName, string lastName) { // Check for input errors. if (String.IsNullOrEmpty(firstName) || String.IsNullOrEmpty(lastName)) { InsertError error = new InsertError(); error.ErrorMessage = "Both names are required."; error.OriginalFirstName = firstName; error.OriginalLastName = lastName; TempData["error"] = error; return RedirectToAction("NewCustomer"); } // No errors // ... return View(); } public ActionResult NewCustomer() { InsertError err = TempData["error"] as InsertError; if (err != null) {
// If there is error data from the previous action, display it. ViewData["FirstName"] = err.OriginalFirstName; ViewData["LastName"] = err.OriginalLastName; ViewData["ErrorMessage"] = err.ErrorMessage; } // ... return View(); } The following example shows the markup for a view that accepts user input and displays the error if one occurs. कोड कॉपी करें
After ASP.NET MVC is installed, the following assemblies are located in the global assembly cache (GAC) on your computer: •
System.Web.Mvc (the ASP.NET MVC assembly)
•
System.Web.Routing (a .NET Framework assembly that is required by ASP.NET MVC)
•
System.Web.Abstractions (a .NET Framework assembly that is required by ASP.NET MVC)
If your hosting provider has ASP.NET version 3.5 Server Pack 1 installed, you have to upload only the System.Web.Mvc assembly. If your hosting provider is using ASP.NET version 3.5 or an earlier version, you must deploy all the listed assemblies. ASP.NET MVC runs in medium trust. Therefore, it should work with the medium-trust policies of most hosting providers. However, check with your hosting provider about trust policies. We recommend that you use the Publish feature of Visual Studio to publish to a local folder and then upload the files to your hosting provider. You can then test exported files before you copy them to the hosting provider. If the hosting provider supports FTP, you can often skip this intermediate step and publish directly to the hoster's FTP server. For more information, see Walkthrough: Deploying a Web Site Project by Using XCOPY. Deploying an MVC Application To deploy an ASP.NET MVC application 1. In Visual Studio, open the project that you want to deploy. 2. In Solution Explorer, expand the References node. 3. Select the following assemblies: •
System.Web.Mvc
•
System.Web.Routing
•
System.Web.Abstractions
4. In the Properties window, set Copy Local to True.
5. In Solution Explorer, right-click the project and click Publish. The Publish Web dialog box is displayed. 6. In Target location (http:, ftp:, or disk path), browse to a local folder and click Open. 7. Select either Replace matching files with local copies or Delete all existing files prior to publish. 8. Under Copy, select one of the following, depending on your needs: Only files needed to run this application, All project files, or All files in the source project folder. 9. If your application contains files in the App_Data folder such as database files, select Include files from the App_Data folder. 10. Click Publish. All the files that are required in order to deploy the application are copied to the target folder. 11.
Test your application by deploying the files to a staging
server or virtual machine that does not have MVC installed. If you do not have access to a staging server or a virtual machine, you can uninstall MVC and then test the application locally. 12.
Upload the application to the hosting provider.
Silverlight .NET Framework Class Library for Silverlight The .NET Framework class library consists of classes, interfaces, and value types that are included with the .NET Framework for Silverlight. The class library provides a reusable set of classes, components, controls, and user interface elements that can be incorporated into Silverlight-based applications. In This Section The .NET Framework for Silverlight class library provides the following namespaces, which are documented in detail in this reference.
Microsoft.Internal Supports the .NET Framework for Silverlight infrastructure. This namespace is not intended to be used directly from your code. Microsoft.VisualBasic Contains classes that support the Visual Basic runtime in Visual Basic. Microsoft.VisualBasic.CompilerServices Contains internal-use only types that support the Visual Basic compiler. Microsoft.Win32.SafeHandles Contains classes that are abstract derivations of safe handle classes that provide common functionality supporting file and operating system handles. System Contains fundamental classes and base classes that define commonly used value and reference data types, events and event handlers, interfaces, attributes, and processing exceptions. Other classes provide services that support data type conversion, method parameter manipulation, mathematics, remote and local program invocation, application environment management, and supervision of managed and unmanaged applications. System.CodeDom.Compiler Contains a class that identifies code that is generated by a tool. System.Collections Contains the BitArray class, interfaces that are implemented by various collection objects, and interfaces and a structure that let you extract, enumerate, and compare objects in collections. System.Collections.Generic Contains interfaces and classes that define generic collections. System.Collections.ObjectModel Contains classes that can be used as collections in the object model of a reusable library. Use these classes when properties or methods return collections. System.Collections.Specialized Contains specialized and strongly typed collections. System.ComponentModel Provides classes that are used to implement the run-time and design-time behavior of components and controls.
System.ComponentModel.DataAnnotations Provides attribute classes that are used to define metadata for entity classes. System.Configuration.Assemblies Contains classes that are used to configure an assembly. System.Data.Services.Client Represents the classes and members that applications can use to interact with ADO.NET Data Services. System.Data.Services.Common Contains a class that indicates the key property or properties of an entity. System.Diagnostics Provides classes that enable you to debug your applications and to trace the execution of your code. System.Diagnostics.CodeAnalysis Contains classes for interaction with tools that analyze code for conformance to coding conventions such as naming or security rules. System.Diagnostics.SymbolStore Provides an interface that gives you access to debug symbol information, such as source-line-to-MSIL (Microsoft intermediate language) maps. Compilers that target the .NET Framework for Silverlight can store the debug symbol information into programmer's database (PDB) files. Debuggers and code profiler tools can read the debug symbol information at run time. System.Globalization Contains classes that define culture-related information, including the language, the country/region, the calendars in use, the format patterns for dates, currency, and numbers, and the sort order for strings. These classes are useful for writing globalized (internationalized) applications. System.IO Contains types that enable reading and writing to data streams. System.IO.IsolatedStorage Contains types for creating and using a virtual file system. Isolated storage provides safe client-side storage for partial trust applications. In Silverlight, all I/O operations are restricted to isolated storage and do not use the file system of the operating system.
System.Json Provides standards-based support for the serialization of JavaScript Object Notation (JSON). System.Linq Contains classes and interfaces that support queries that use Language-Integrated Query (LINQ). System.Linq.Expressions Contains types that enable language-level code expressions to be represented as objects in the form of expression trees. System.Net Provides a simple programming interface for many of the protocols used on networks today. The WebRequest and WebResponse classes form the basis of pluggable protocols, which enable you to develop applications that use Internet resources without worrying about the specific details of the individual protocols. System.Net.Browser Contains a class that represents the source of a Web request. System.Net.NetworkInformation Provides access to information on network availability and notification of address changes for the local computer. System.Net.Sockets Provides a managed implementation of the sockets networking interface for developers who need to tightly control access to the network. On Windows, this namespace provides a managed implementation of the Windows Sockets (Winsock) interface. On Apple Macintosh OS X, this namespace provides a managed implementation of the sockets interface based on Berkeley Software Distribution (BSD) UNIX. System.Reflection Contains types that retrieve information about assemblies, modules, members, parameters, and other entities in managed code by examining their metadata. These types also can be used to manipulate instances of loaded types, for example, to hook up events or to invoke methods. System.Reflection.Emit Contains classes that enable a compiler or tool to emit metadata and Microsoft intermediate language (MSIL) and optionally to generate a PE file on disk. The primary clients of these classes are script engines and compilers.
System.Resources Provides classes and interfaces that enable developers to create, store, and manage various culture-specific resources used in an application. System.Runtime.CompilerServices Provides functionality for compiler writers who use managed code to specify attributes in metadata that affect the run-time behavior of the common language runtime. System.Runtime.ConstrainedExecution Defines a type that ensures that finalization code is marked as critical. The type is intended for use in constrained execution regions (CERs). System.Runtime.InteropServices Provides a wide variety of members that support COM interop and platform invoke services. System.Runtime.Serialization Contains classes that can be used for serializing and deserializing objects. Serialization is the process of converting an object or a graph of objects into a linear sequence of bytes for either storage or transmission to another location. Deserialization is the process of taking in stored information and recreating objects from it. System.Runtime.Serialization.Json Contains types for serializing objects to JavaScript Object Notation (JSON) and deserializing objects from JSON. System.Runtime.Versioning Contains advanced types that support versioning in side-by-side implementations of the .NET Framework for Silverlight. System.Security Provides the underlying structure of the .NET Framework for Silverlight security system. System.Security.Cryptography Provides cryptographic services, including secure encoding and decoding of data, as well as many other operations, such as hashing, random number generation, and message authentication. System.Security.Cryptography.X509Certificates Contains the common language runtime implementation of the Authenticode X.509 v.3 certificate. This certificate is signed with
a private key that uniquely and positively identifies the holder of the certificate. System.Security.Permissions Defines classes that control access to operations and resources based on policy. This namespace supports the .NET Framework for Silverlight infrastructure; none of its types are accessible to application code. System.Security.Principal Defines a principal object that represents the security context under which code is running. System.ServiceModel Contains the types necessary to build Silverlight-based client applications that can be used to access distributed applications. System.ServiceModel.Channels Contains the types required to construct and modify the messages used by clients to communicate with services, the types of channels used to exchange messages, the channel factories used to construct those channels, and the binding elements used to configure them. System.ServiceModel.Description Contains the types required to construct and modify descriptions of services, contracts, and endpoints that are used to build service runtimes and to export metadata. System.ServiceModel.Dispatcher Contains the types necessary to modify the run-time execution behavior of client applications. System.ServiceModel.Security Contains types related to security. System.ServiceModel.Syndication Contains the types that make up the Silverlight syndication object model. System.Text Contains classes that represent Unicode and UTF-8 character encodings; abstract base classes for converting blocks of characters to and from blocks of bytes; and a helper class that manipulates and formats String objects without creating intermediate instances of String. System.Text.RegularExpressions
Contains classes that provide access to the .NET Framework regular expression engine. The namespace provides regular expression functionality that can be used from any platform or language that runs within the .NET Framework. System.Threading Provides classes and interfaces that enable multithreaded programming. System.Windows Provides general presentation classes for Silverlight applications, as well as the Silverlight base classes. These presentation classes are often similar to classes that exist in the Windows Presentation Foundation (WPF). System.Windows.Automation Contains classes that provide support for Silverlight UI Automation clients. System.Windows.Automation.Peers Defines the AutomationPeer base class and a set of types that derive from it and that correspond to Silverlight controls. Each AutomationPeer exposes the corresponding Silverlight control to UI Automation. System.Windows.Automation.Provider Contains interfaces for creating UI Automation providers. System.Windows.Browser Contains classes that enable the interaction between managed code and JavaScript in Silverlight-based applications. This functionality is referred to as the HTML Bridge feature. System.Windows.Controls Contains classes to create controls that enable a user to interact with an application. System.Windows.Controls.Primitives Contains base classes and controls that are intended to be used as part of other, more complex controls. System.Windows.Data Contains classes used for binding properties to data sources. System.Windows.Documents Contains classes that support basic document concepts in Silverlight. System.Windows.Ink
Provides classes to interact with and manipulate ink in Silverlight. System.Windows.Input Contains classes that support input in a Silverlight-based application. System.Windows.Interop Contains classes that provide managed code exposure for properties of the Silverlight plug-in, which otherwise exist in the HTML DOM of the hosting browser. System.Windows.Markup Contains classes that support Extensible Application Markup Language (XAML) processing in Silverlight. System.Windows.Media Contains classes that enable integration of rich media, including drawings, text, and audio/video content, in Silverlight-based applications. System.Windows.Media.Animation Contains classes that support property animation functionality, including timelines, storyboards, and key frames. System.Windows.Media.Effects Provides types that can be used to apply visual effects to bitmap images. System.Windows.Media.Imaging Contains classes used to encode and decode bitmap images. System.Windows.Messaging Provides types that support messaging. System.Windows.Navigation Provides types that support navigation. System.Windows.Resources Contains a class that provides resource stream information for application resources or other packages obtained through Application..::.GetResourceStream. System.Windows.Shapes Contains a library of basic shapes that can be used in Extensible Application Markup Language (XAML) or code. Also includes the Path class, which can load path data to describe a compound geometry either through an object model or an inline format. System.Windows.Threading
Contains classes that support the Silverlight threading system. System.Xml Provides standards-based support for processing XML. System.Xml.Linq Contains the types for LINQ to XML, which is an in-memory XML programming interface that enables you to modify XML documents efficiently and easily. System.Xml.Resolvers Contains classes that provide support for prepopulating the cache with DTDs or XML streams. System.Xml.Schema Contains the XML classes that provide standards-based support for XML Schema definition language (XSD) schemas. System.Xml.Serialization Contains classes that are used to serialize objects into XML format documents or streams.