Late last week a training kit for the ASP.NET MVC framework was published against the final version of the product. As with other training kits, this is a collection of presentations, labs, demos and the like that explain how to use the product. If you're not interested in resource material, then you don't have to get the training kit to use ASP.NET MVC. Conversely, if you just want to learn about the product, then there's a lot that you can look through here without having anything installed.
The latest information about ASP.NET MVC can be found in the list of supporting technologies.
Aaron Skonnard has an article in the April edition of MSDN Magazine on building applications with .Net Services. .Net Services are a service implementation for the Azure cloud platform that will be the most familiar to programmers who have built WCF services, workflow services, or BizTalk services in the past. This includes features such as cloud-hosted workflows, relayed messaging, and federated authentication.
Here are a few resources you'll need to get started to try out the services that Aaron talks about.
How do I configure a client to sign or encrypt message headers that are generated dynamically at runtime?
The client uses the same ChannelProtectionRequirements mechanism to specify the protection of message headers as the service does. Your intuition may be flipped though as Incoming message parts are always message parts being sent from client to server while Outgoing message parts are always message parts being sent from server to client. Therefore, IncomingSignatureParts are message parts that are signed for transmission from client to server. If this still isn’t clear, try out OutgoingSignatureParts on the client and look at the resulting messages to see if it does what you expect. Then, repeat with IncomingSignatureParts.
A simple behavior that you can use to experiment with is here.
public class SignMessageHeaderBehavior : IContractBehavior { string header; string ns; public SignMessageHeaderBehavior(string header, string ns) { this.header = header; this.ns = ns; } public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { ChannelProtectionRequirements requirements = bindingParameters.Find<ChannelProtectionRequirements>(); XmlQualifiedName qName = new XmlQualifiedName(header, ns); requirements.OutgoingSignatureParts.ChannelParts.HeaderTypes.Add(qName); } public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) { } public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) { } public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) { } }
The Dublin team is doing a user research study next week and has extra slots available for additional participants. You'll show up at the user research lab for a few hours and in return receive some Microsoft products for your time. Participants are likely to survive the process.
Required qualifications:
To sign up, send mail to mailto:itusable@microsoft.com?subject=IIS%20study%20signup including your name and a phone number you can be reached at.
For those interested in a more technical look, Dominick Baier has a separate pair of articles on how Geneva is integrated into WCF and ASP.NET.
Can I have two operations with the same name but different calling conventions use the same action?
No, the point of the action property on a message is to guarantee that the message contains sufficient information to distinguish which operation it should be associated with. It would be of no benefit to provide an action property if it did not actually uniquely define an operation.
That doesn't mean an action property is always required. Even if the contract defines a value for the action property, that value may not be literally represented unless an appropriate addressing protocol is used to transmit the message. However, not every feature works when the action property is not defined.
A default value for the action property exists for the WSDL contract even if one is not explicitly defined. This default value for an operation looks like the following.
[namespace]/[WSDL port name]/[message name]
The namespace is the target namespace defined by the contract. If the namespace uses the urn scheme, then all of the forward slash delimiters in the default value are replaced by colons.
The port name comes directly from the WSDL definition of the contract.
The message name either comes directly from the WSDL definition if provided or is created by taking
the operation name and appending either Request or Response depending on whether the message corresponds to the operation input or output. A one-way message would have nothing appended.
The default value for an operation fault follows roughly the same pattern.
[namespace]/[WSDL port name]/[operation name]/Fault/[fault name]
The final release of ASP.NET MVC 1.0 debuted at MIX and it's available for you to grab now.
The release notes describe a way to do a server install on machines where Visual Studio is not available. However, I've got a few corrections after trying it out. First, the documentation says that it will execute a quiet install but leaves the quiet install switch out of the command example. The actual command you want is:
msiexec /i AspNetMVC1.msi /q /l*v mvc.log MVC_SERVER_INSTALL="YES"
Second, although it's not mentioned you do need to run the installer from an elevated command prompt rather than a normal command prompt. Otherwise, the installer will fail without an elevation prompt on account of being in quiet mode.
Today is the third and final day of MIX and the content from earlier in the show is starting to appear online. Here's what I've found so far.
Download some of the tools and CTPs announced at MIX.
Watch the recorded sessions that are available 1-2 days after the session is over. I've found two ways to do this.
First approach:
Second approach:
The session video pages also have the slides available without the videos.
Joel Reyes is an evangelist on the public sector team that writes occasional articles covering different Microsoft services technologies. Here's a sample of some of them that you might enjoy.
When extending ServiceAuthorizationManager, what does the base implementation provide?
The entry point for ServiceAuthorizationManager comes from the authorization behavior of the service and goes first to CheckAccess(OperationContext, Message). This first version of CheckAccess does nothing but forward to CheckAccess(OperationContext). It's this second version of CheckAccess that does all of the work.
The base implementation of CheckAccess does two things for you.
First, CheckAccess uses GetAuthorizationPolicies to compute the set of authorization policies for the ServiceSecurityContext. This method takes the authorization policies from the inner ServiceSecurityContext on the SecurityMessageProperty and folds in the external authorization policies from the property. The combined set of policies becomes the set of authorization policies used for the ServiceSecurityContext of the operation.
Second, CheckAccess calls CheckAccessCore for people that want to use this lighter-weight extensibility point. The base implementation of CheckAccessCore simply allows all access so it's not a very interesting implementation.
When I look at the performance counters in my service for the execution time of an operation, the value is always zero. Why?
There's a variety of reasons I can think of for why call data may not be collected and all are relatively easy to check.
First, you need to have performance counters enabled. The simplest way to do this is through configuration by setting the performanceCounters attribute to All in the diagnostics section. There are a few other performance counter scopes, some of which don't include the data you may be looking for.
Second, you need to have your application run long enough to collect data. During shutdown you may encounter races between the performance counters being freed and the remaining work being processed. Data isn't collected if the performance counters are not available.
Third, you need to have infrastructure support for collecting performance counter data. In a partially trusted environment you may not have sufficient permissions to perform management, logging, or performance counter operations.
Fourth, you need to have an operation that takes long enough to measure. You can't rely on getting high-precision timing measurements. Performance counters use cheap sampling methods to avoid interfering with application execution. If your application requires better than millisecond accuracy to collect data, then performance counters may be the wrong mechanism for measuring performance.
Scott Guthrie has been working overtime to create the last ASP.NET MVC tutorial you'll ever need. It's a 185 page application building tour going from the very first bit of getting starting and continuing through all of the important concepts and features that you'll need to know about. This tutorial is actually the first part of his upcoming Professional ASP.NET MVC 1.0 book together with Rob Conery, Scott Hanselman, and Phil Haack.
How do I apply behaviors to the callback portion of a callback contract?
If you were going to apply a behavior to the non-callback portion of the callback contract, you'd do so through an IContractBehavior attached to the relevant part of the service description. On the IContractBehavior you'd implement two methods, ApplyClientBehavior and ApplyDispatchBehavior, for modifying or extending the behavior of the contract. Let's take a look at those two methods.
void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime); void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime);
With each of the methods you get a copy of the contract, the endpoint that supports the contract, and the runtime behind the endpoint. These objects that support the forward contract are also linked to the objects that support the backwards contract.
On the contract description there is a CallbackContractType that you can use to get the description of the callback contract.
On the client runtime there is a CallbackDispatchRuntime that gives you the dispatch runtime for the callback from the service.
On the dispatch runtime there is a CallbackClientRuntime that gives you the client runtime for the callback to the client.
After talking about Kerberos kernel authentication earlier I noticed that there was a hotfix available for a crash related to the feature. Kernel mode authentication is a new feature in IIS7 that optimizes the authentication of connections. This particular crash occurs when using a custom domain account for the application pool credentials. I don't know of anyone who has seen this crash in connection with a WCF service but the symptoms are a stop code of 7E and a call stack that includes HTTP!UlpThreadPoolWorker. Similar to the other article, you've got a choice between using the classic user mode authentication or applying the fix to continue using kernel mode authentication.
Silverlight Spy is a development tool that allows you to poke around inside a running Silverlight 2 application. The interface is basically a browser view together with property inspectors for UI controls, events, XAML, and the like. Launching the application is run through a ClickOnce installer.
There are some rough spots, most noticeably having to do with interface responsiveness. Expanding part of the definition of a large application tends to freeze the interface for a while as the tree is enumerated. There's also currently only support for Silverlight 2. You won't be able to inspect into an existing Silverlight 1 application.
Why doesn't WCF recognize a request without a Content-Type header?
An HTTP message that contains a body is supposed to include a Content-Type header that describes the body format. An indication of the body format is crucial to processing the message because the message might mean very different things depending on what the body tells the recipient. If the Content-Type header is not included, then the recipient is allowed to guess what the body format was supposed to be. Guessing is typically practiced by applications that just display the message, such as web browsers, where the consequences of guessing wrong aren't too bad. If the recipient isn't able to guess the body format, then they're allowed to apply a default format to the messages that remain unknown.
WCF won't try to guess what you meant to send it and doesn't process messages without a Content-Type header. In 4.0 we still won't try to guess what you mean, but we will at least give your message a default body format of application/octet-stream if you don't specify one.
ASP.NET MVC has an updated release candidate that is built on Orcas SP1. There are minimal other changes to the release candidate besides this dependency.
ASP.NET MVC Release Candidate 2
ASP.NET MVC Release Candidate 2 Release Notes
You can also get access to four more preview chapters for Stephen Walther's MVC book. These preview chapters are a draft version of the book that will be up until the book is published.
Chapter 3: Understanding Controllers
Chapter 4: Understanding Views
Chapter 5: Understanding Models
Chapter 6: Understanding HTML Helpers
Will setting the receive quotas to large values cause my service to run out of memory?
It depends on the messages that people send you.
Assigning large values to quotas does not cause WCF to immediately allocate the amount of memory that you specify as the quota value. Therefore, you can change the quota values and not have any problems starting up your service or receiving the same messages that you could receive before. However, if someone decides to send you a really big message, then that message will be processed up to the quota size that you specified. If both the quota value and the message size are large enough, then your service may possibly run out of memory trying to process the message.
The quota value is supposed to be the maximum amount that you think that you can afford. If the quota value is larger than the amount that will break your service, then having such a large quota value does not provide protection against messages within that size range.
What is the string "--uuid:…" doing embedded in MTOM messages?
That string is a boundary marker that separates one part of the message from another. This scheme of separating message parts using a unique string is common to many types of multipart messages and is sometimes referred to as the MIME boundary. Since the string has to be unique, it is actually specified for the first time at a fixed place in the message so that the boundary marker can be different in each message. The location where the boundary string is specified in an MTOM message transmitted over HTTP is the HTTP Content-Type header. The boundary string is one of the parameters to the Content-Type header and is called boundary.
In WCF, the boundary string is generated internally as part of the HTTP transport when an MTOM message is sent. The boundary string starts with "uuid:", followed by a random guid, followed by "+id=", and followed by a number that increments each time the generator is used in the application domain. The "--" at the beginning or end of the boundary marker is part of the multipart format and not technically a part of the boundary string so you won't see it included in the Content-Type header.