I have made a password reset controller that takes in a GUID querystring. As you can see in the below code, my controller checks if the GUID value exists in my db, whereafter it returns user to the view with the attributes name and userId.
[HttpGet]
public ActionResult RetreivePass(string ac)
{
MySqlContext db = new MySqlContext();
PwRetreival PwRetreival = new PwRetreival();
Users user = new Users();
if (db.PwRetreival.FirstOrDefault(u => u.Token == ac) != null)
{
PwRetreival.uId = db.PwRetreival.Where(u => u.Token == ac).Select(u => u.uId).First();
var Attributes = db.Users.Where(u => u.UserId == PwRetreival.uId).Select(u => new { u.Name, u.UserId }).FirstOrDefault();
user.Name = Attributes.Name;
user.UserId = Attributes.UserId;
return View(user);
}
return RedirectToAction("Index", "Home");
}
In my view, it looks like this:
<p>Hello #Model.Name</p>
#using (Html.BeginForm(FormMethod.Post))
{
<p>Change password</p>
#Html.TextBoxFor(u => u.Password)
<p>
<button type="submit">Register</button>
</p>
}
And finally, upon submit, i call this controller:
[HttpPost]
public string RetreivePass(Users model)
{
//Some code here
}
Unfortunately, my issue is, that the parameters (Name & UserId) are not returned with the model to the controller on submit. Therefore i only have the password, which i can't use for anything, because i cant tell my controller where to put the updated password.
Am i missing something??
For convenience, my models are as follows:
public class Users
{
[Key]
public int UserId { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string Name { get; set; }
public short EmailConfirmed { get; set; }
}
public class PwRetreival
{
[Key]
public int Id { get; set; }
public int uId { get; set; } //FK to Users.UserId
public string Token { get; set; }
}
Make sure you include the name into the form as some input parameter (hidden if the user is not supposed to modify it):
#using (Html.BeginForm(FormMethod.Post))
{
<p>Change password</p>
#Html.HiddenFor(u => u.UserId)
#Html.TextBoxFor(u => u.Password)
<p>
<button type="submit">Register</button>
</p>
}
So basically all parameters that you hope to retrieve when you postback must be included either as input fields inside your form or as query string parameters.
Of course you realize that a hidden field or a query string parameter can be modified from the outside making it quite insecure. Anyone knowing the UserId of another user could trigger a password reset for him. In order to make a secure password reset functionality you might need some cryptography involved. For example you could use a symmetric cryptographic algorithm to encrypt the UserId and send the encrypted value to the client in the password reset email. Then when the form is POSTed back the encrypted value could be decrypted on the server to extract the original client id and the new password. If the encrypted value has been tampered with you will know that immediately.
Another approach would be to generate some token on the server which will be associated with your user and stored in your backend. Then send this token to the client in the password reset email and when POSTed back you will know who the original user was by looking at your backend. It is also a good idea to sign this token using a server secret to ensure that it hasn't been tampered with.
Related
I have only taken a small draft from the side,
it is such that I must have sent some data in my database,
what I've read me to is that such textbox must have the same name throughout from the controller has and model,
index.cshtml
#Html.TextBox("Email", null, new
{
#class = "form-control input-lg",
placeholder = "Skriv email her",
type = "email"
})
Kontocontroller.cs
[HttpPost]
public ActionResult CreateUsers(OpretBrugere brugere)
{
if (ModelState.IsValid)
{
//Is that the right way that I must find out something with database or should I do it differently?
var email = Request["Email"].ToString();
var CreateAnAccount = db.Users.FirstOrDefault(b => b.Email == email);
if(CreateAnAccount != null)
{
brugere.Email = email;
}
}
}
on my model have i opretbrugere.cs
public class OpretBrugere
{
public int UserId { get; set; }
public string Email { get; set; }
}
What do I wrong såden that it will not go into the database, as I said, I have much more to model and cshtml ago to be entered into the database, but I will make a brief description of the task that make it easy for you.
It could be better if you use MVC's model binder. Do something like this:
In your view add your model OpretBrugere as view model
#model Mynamespace.OpretBrugere
and then use html helper to generate proper input like this:
#html.EditorFor(m=>m.Email)
then in your controller you could read data from action's parameter:
[HttpPost]
public ActionResult CreateUsers(OpretBrugere brugere)
{
if (ModelState.IsValid)
{
var email = brugere.Email; // user's submitted data is here
// save to db or whatover you want
}
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
It appears that these two features have a set of helper functions and schema in the WebMatrix code to get going. However, there are no controller methods or views to get it done, so you have to implement yourself.
Is there any samples anywhere where I can just copy this code into my app? I'm looking for something to:
Generate Forgot Password Email
Generate Confirmation Email
Forgot Password view + Controller method
Resend confirmation email view + Controller method
FORGOT PASSWORD FUNCTIONALITY
The other day I was trying to create a “forgot password functionality” in asp.net MVC 4. I googled in and out but couldn't get the best solution. I have finally found the way out.
15 simple steps
Part 1
Sending Password Reset Information via Email
Step 1
• Create Mvc 4 c# Internet application template :)
(Account and home controllers will automatically be generated)
• Build and run your project. Register and login.
(Simple membership tables will be generated)
Everything working fine?
Step 2
• Oops!! They don’t ask our email id while registration! In order to send password token to users we need their email id!! So let’s make a few changes in database go to server explorer! ( If u can’t find it u can press Ctrl + alt + S )
• Expand "data connections" and u will see a couple of tables. Open User Profile table.
Add the following columns:
EmailId nvarchar(max)
2.Details nvarchar(max)
Step 3
• Now go to Solution Explorer...Models ... Account model ... Register model
• Add these two properties for Email Id and Details
//new properties
[Required]
[Display(Name="Email ID")]
public string EmailId { get; set; }
[Required]
[Display(Name = "About Yourself")]
public string Details { get; set; }
Step 4
• Now go to Solution Explorer…Views ... Account Views ... Register.cshtml view
• Add these two properties for allowing users to enter email id and other details.
#Html.LabelFor(m => m.EmailId)
#Html.TextBoxFor(m => m.EmailId)
#Html.LabelFor(m => m.Details)
#Html.TextBoxFor(m => m.Details)
Step 5
• Now go to Solution Explorer…Controllers ... Account Controller ... Post version of Register controller action method
• Add these properties for allowing users to enter email id and other details.The changes are highlighted.
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { EmailId = model.EmailId, Details = model.Details});
WebSecurity.Login(model.UserName, model.Password);
return RedirectToAction("Index", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Why don’t we again build and run our project? Register and fill in the details .Now you will be asked to specify email address also .Add these properties for allowing users to enter email id and other details.
Go to server explorer and right click on User Profile table and Select “Show Table Data” U can view the details you entered for verification.
Step 6
• Now lets implement the password reset functionality Go to account controller and create the following controller action method (GET )
[AllowAnonymous]
public ActionResult ForgotPassword()
{
return View();
}
• (POST)
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ForgotPassword(string UserName)
{
//check user existance
var user = Membership.GetUser(UserName);
if (user == null)
{
TempData["Message"] = "User Not exist.";
}
else
{
//generate password token
var token = WebSecurity.GeneratePasswordResetToken(UserName);
//create url with above token
var resetLink = "<a href='" + Url.Action("ResetPassword", "Account", new { un = UserName, rt = token }, "http") + "'>Reset Password</a>";
//get user emailid
UsersContext db = new UsersContext();
var emailid = (from i in db.UserProfiles
where i.UserName == UserName
select i.EmailId).FirstOrDefault();
//send mail
string subject = "Password Reset Token";
string body = "<b>Please find the Password Reset Token</b><br/>" + resetLink; //edit it
try
{
SendEMail(emailid, subject, body);
TempData["Message"] = "Mail Sent.";
}
catch (Exception ex)
{
TempData["Message"] = "Error occured while sending email." + ex.Message;
}
//only for testing
TempData["Message"] = resetLink;
}
return View();
}
• The GET controller action just returns the view.
• The POST controller action :
Receives the username
Verifies its existence
Generates Password reset token
Builds URL to be emailed.
Step 7
• Right click on the forgot password action method and add view The code for the view page will be as below
#{
ViewBag.Title = "Forgot Password";
}
<h2>Forgot Password</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<fieldset>
<legend>Forgot Password Form</legend>
<ol>
<li>
#Html.Label("User Name", new { #for = "UserName" })
#Html.TextBox("UserName")
<span style="color:red;">#TempData["Message"]</span>
</li>
</ol>
<input type="submit" value="Recover" />
</fieldset>
}
• The view page will display a textbox where in user can enter the user name.
Step 8
• Now go to Solution Explorer...Models ... Account model … User Profile View Model. Changes have been highlighted
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
//new properties
public string EmailId { get; set; }
public string Details { get; set; }
}
Step 9
• Now go to Solution Explorer...Views ... Account … Login View.
Now we can see an option to recover his password in case he has forgotten it.
<ul>
<li>
#Html.ActionLink("Register", "Register") if you don't have an account.
</li>
<li>
#Html.ActionLink("Forgot Password", "ForgotPassword") if you want to recover your password.
</li>
</ul>
Part 2
Receiving Password Reset Information from URL
Step 1
• Go to Solution Explorer...Controller ... Account Controller …
Create new Reset Password Action Method
• This method is accepting ‘un’ (which is username) and ‘rt’ (which is password reset token) from the URL.
[AllowAnonymous]
public ActionResult ResetPassword(string un, string rt)
{
UsersContext db = new UsersContext();
//TODO: Check the un and rt matching and then perform following
//get userid of received username
var userid = (from i in db.UserProfiles
where i.UserName == un
select i.UserId).FirstOrDefault();
//check userid and token matches
bool any = (from j in db.webpages_Memberships
where (j.UserId == userid)
&& (j.PasswordVerificationToken == rt)
//&& (j.PasswordVerificationTokenExpirationDate < DateTime.Now)
select j).Any();
if (any == true)
{
//generate random password
string newpassword = GenerateRandomPassword(6);
//reset password
bool response = WebSecurity.ResetPassword(rt, newpassword);
if (response == true)
{
//get user emailid to send password
var emailid = (from i in db.UserProfiles
where i.UserName == un
select i.EmailId).FirstOrDefault();
//send email
string subject = "New Password";
string body = "<b>Please find the New Password</b><br/>" + newpassword; //edit it
try
{
SendEMail(emailid, subject, body);
TempData["Message"] = "Mail Sent.";
}
catch (Exception ex)
{
TempData["Message"] = "Error occured while sending email." + ex.Message;
}
//display message
TempData["Message"] = "Success! Check email we sent. Your New Password Is " + newpassword;
}
else
{
TempData["Message"] = "Hey, avoid random request on this page.";
}
}
else
{
TempData["Message"] = "Username and token not maching.";
}
return View();
}
Step 2
• Right click on the reset password action method and add view The code for the view page will be as below
#{
ViewBag.Title = "ResetPassword";
}
<h2>Password Mailed :) </h2>
Step 3
• Go to Solution Explorer...Models... Account Models …
Make the following changes.
• We create an instance of UserProfile DB Model and implement db.webpages_Memberships’ as DbSet.Use ‘webpages_Memberships’ as a model.
public class UsersContext : DbContext
{
public UsersContext()
: base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<webpages_Membership> webpages_Memberships { get; set; }
}
[Table("webpages_Membership")]
public class webpages_Membership
{
[Key]
public int UserId { get; set; }
public DateTime CreateDate { get; set; }
public string ConfirmationToken { get; set; }
public bool IsConfirmed { get; set; }
public DateTime LastPasswordFailureDate { get; set; }
public int PasswordFailuresSinceLastSuccess { get; set; }
public string Password { get; set; }
public DateTime PasswordChangeDate { get; set; }
public string PasswordSalt { get; set; }
public string PasswordVerificationToken { get; set; }
public DateTime PasswordVerificationTokenExpirationDate { get; set; }
}
Step 4
• Add the Random Password Generation Function to the account controller
• This method when called will generate a random password for the user
private string GenerateRandomPassword(int length)
{
string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789!#$?_-*&#+";
char[] chars = new char[length];
Random rd = new Random();
for (int i = 0; i < length; i++)
{
chars[i] = allowedChars[rd.Next(0, allowedChars.Length)];
}
return new string(chars);
}
Step 5
• Add the Send Email Function in account controller.
• This function will send first mail to user when user clicks on recover button on forgot password form. The first mail contains the reset password link. When user clicks on the link. User will be redirected to the reset password page. Again the new password will be mailed to the user.
• You need to put in your email address in place of XXXXX#gmail.com and write your password.
private void SendEMail(string emailid, string subject, string body)
{
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
client.EnableSsl = true;
client.Host = "smtp.gmail.com";
client.Port = 587;
System.Net.NetworkCredential credentials = new System.Net.NetworkCredential("xxxxx#gmail.com", "password");
client.UseDefaultCredentials = false;
client.Credentials = credentials;
System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
msg.From = new MailAddress("xxxxx#gmail.com");
msg.To.Add(new MailAddress(emailid));
msg.Subject = subject;
msg.IsBodyHtml = true;
msg.Body = body;
client.Send(msg);
}
Questions:
How do you set default values on a Model when that default value
is based on the User.Identity.Name?
How do you make a field
read-only on a View but still have it work as intended at the Model
level
Below is my attempt at both of those issues.
Background:
Each Account can create a bunch of Users. I want the Account holders to be able to create Users, but I want the Account value to default to their AccountName (unchangeable). The model will also be used by Admin Accounts, who is able to set the AccountName, so I want to keep that variable on the Model and Views.
Right now my model takes in an optional AccountName param so that I can set it to the User.Identity.Name:
public partial class User
{
public User()
{
this.Games = new HashSet<Game>();
}
public User(string AccountName)
{
this.AccountName = AccountName;
this.Games = new HashSet<Game>();
}
[Required]
public string Name { get; set; }
[Required]
[Display(Name = "Account Name")]
public string AccountName { get; set; }
public string Rank { get; set; }
public virtual ICollection<Game> Games { get; set; }
}
The controller then sets the default value for the new user on Create:
// GET: /User/Create
public ActionResult Create()
{
User user = new User(User.Identity.Name);
return View(user);
}
On the View, I changed the #Html.EditorFor to #Html.DisplayFor since I don't want the users to edit that field:
<div class="editor-label">
#Html.LabelFor(model => model.AccountName)
</div>
<div class="editor-field">
#Html.DisplayFor(model => model.AccountName)
#Html.ValidationMessageFor(model => model.AccountName)
</div>
The problem is AccountName is a required field, so when I try to save, it will throw a validation error telling me it's required. I can easily keep that field as an EditorFor field and make that field readonly through javascript, but I wanted to know how this is suppose to be done.
Here are a couple thoughts:
Is AccountName really required by the user? I would say it is not since you are setting it in your controller. Thus remove the [Required] attribute and add the User user = new User(User.Identity.Name); to the action method that is handling the POST and that solves that problem. Alternatively you could use #Html.HiddenFor(x => x.AccountName) but that leaves you vulnerable to someone changing the value using firebug or some other tool. In that case you could encrypt/decrypt the value, but seems easier to just manually set it in the post method and you don't have to worry as much about the security of someone maliciously changing the value.
To display the value you could just use #Model.AccountName rather than the lambda
[HttpPost]
public ActionResult Create(User model)
{
if(!ModeState.IsValid)
return View(model);
model.AccountName = User.Identity.Name; //Probably want to do some check to make sure this isn't null;
// Create User in the system here...
return View(); // Send them to another page
}
I can't figure out how to do this very simple thing: My page contains a set of textboxes that a user can fill out to add an item to a list. Then the item shows up in a dropdown list.
At that point, I want the "add" textboxes to be cleared. This is the behavior expected by most users, I think. The item has been added; now the textboxes should be empty, ready for the next item to be entered.
However, I can't seem to clear them when I am using Html helpers, e.g., Html.Textbox(...). I like these controls because of the way they "remember" the input in case of input error. However, unlike webforms controls, you can't set them programmatically. They continue to retain the values until the user enters something else.
Is there any way around this behavior? I thought of clearing them in javascript, but I don't want to do that if there are any errors.
UPDATE some of the code;
One of my textboxes in the view:
<h6 style="margin-top: 0px">Add custom email template:</h6>
<div style="margin-top: 10px">
<div class="label">Name:</div>
<%= Html.TextBox("addName", "", new { #class="formtext", style="width: 400px" }) %>
<div class="alerttext"><%= Html.ValidationMessage("addName") %></div>
</div>
The class I am using for model binding:
public class ManageEmailTemplatesSubmittedData
{
[RegularExpression(RegExpressions.templateNameRestrict, ErrorMessage="Names should begin with a character and consist of only characters and numbers")]
public string addName { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
public string addDescription { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
public string addSubject { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
public string addTemplate { get; set; }
public string templates { get; set; }
[RegularExpression(RegExpressions.templateNameRestrict, ErrorMessage = "Names should begin with a character and consist of only characters and numbers")]
public string editName { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage="Invalid entry; please omit unusual characters")]
public string editDescription { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
public string editSubject { get; set; }
[RegularExpression(RegExpressions.freeTextRestrict, ErrorMessage = "Invalid entry; please omit unusual characters")]
public string editTemplate { get; set; }
}
My action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CustomEmails(SubmitButtons buttons, ManageEmailTemplatesSubmittedData data)
{
bool saved = false;
string selectedTemplate = data.templates;
if (ModelState.IsValid)
{
ButtonStyles buttonStyles = ButtonStylesCreator.GetSelectListButtonStyles(rc.persistedData.loggedInUser.userType);
Notification notification = new Notification(rc);
if (buttons.addTemplate == buttonStyles.addEmailTemplateButtonValue)
{
// add an email template
notification.SaveCustomTemplate(data.addName, data.addName, data.addTemplate, data.addSubject, data.addDescription);
saved = true;
}
else if (buttons.saveTemplate == buttonStyles.saveTemplateValue)
{
// update an email template
notification.SaveCustomTemplate(data.templates, data.editName, data.editTemplate, data.editSubject, data.editDescription);
selectedTemplate = "";
saved = true;
}
}
ConfigureEmailsModelBuilder builder = new ConfigureEmailsModelBuilder(rc, rc.persistedData.loggedInUser.userID, selectedTemplate, true, saved);
return View(builder.Build());
}
ConfigureEmailsModelBuilder constructs the view model, which includes a SelectList that is the dropdown list of the items that have been added. (The view is strongly typed to the type generated by builder.Build).
The HTMLHelper's first look at the ModelState and ViewData to see if any values match their key and then finally use whatever value you provide them.
If you need to reset the textboxe's value you also need to clear the ModelState entry with the matching key. Another alternative is redirecting to the same page instead of simply rendering a view via javascript or with MVC.
This is working for me on an MVC3 site log on page.
ModelState.Clear();
model.UserName = string.Empty;
model.Password = string.Empty;
ModelState.AddModelError("", "The user name or password provided is incorrect.");
This will clear the login textboxes used for password and username, and keep any model errors.
On the assumption that I have Entity with couple of fields. Some fields are required at some specific state but others only on further/other state.
public class Entity
{
//Required always
public SomeReference {}
//Required in specific situation/scenario
public OtherReference {}
}
How to achieve that scenario with some known validation framework or how to do it by my self?
For help:
Udi Dahan has some thoughts on this.
http://www.udidahan.com/2007/04/30/generic-validation/
I have a solution that I am using at the moment. I use Fluent validation and am still getting used to it. I can give you an example of a simple scenario I have. maybe it helps. I have a user class, with a address Object property. At some point, I want to only validate the User details(name, email, password, etc) and at another state I want to validate the user address(first line, postcode, etc).
Classes look like this:
public class User {
public virtual string Name { get; set; }
public virtual string Email { get; set; }
public virtual string Password { get; set; }
public virtual Address Address { get; set; }
}
public class Address {
public virtual string Address1 { get; set; }
public virtual string PostCode { get; set; }
}
I then have two (simplfied) validators, one for an address and one for a user:
public AddressValidator() {
RuleFor(address => address.Address1)
.NotNull()
.WithMessage("Please enter the first line of your address");
RuleFor(address => address.PostCode)
.NotNull()
.WithMessage("Please enter your postcode")
.Matches(UK_POSTCODE_REGEX)
.WithMessage("Please enter a valid post code!");
}
public UserValidator() {
RuleFor(user => user.FirstName)
.NotNull()
.WithMessage("Please provide a first name")
.Length(3, 50)
.WithMessage("First name too short");
RuleFor(user=> user.Password)
.Length(8, 50)
.WithMessage("Password is too short");
}
I then create a Model Validator, so for example, say we have a form where the user enters an address, we create a AddressModelValidator, and can re-use the validators we have written:
public AddressModelValidator() {
RuleFor(user => user.id)
.NotNull()
.WithMessage("An error has occured, please go back and try again");
RuleFor(user => user.Address).SetValidator(new AddressValidator());
}
So, with some thought, you can really create some nice models, and reduce your validation code duplication!
My preferernce is to localize common validation functions such as email and date validations into a ValidationService class that I can pass my object into. For the rest though I tend to put the validation into the class itself. If I am using LINQ to SQL then I can create a Validate() method on my object which LINQ to SQL will call prior to saving the object to the db like this:
public void Validate()
{
if(!IsValid)
throw new ValidationException("Rule violations prevent saving");
}
public bool IsValid
{
get { return GetRuleViolations().Count() == 0;}
}
public IEnumerable<RuleViolation> GetRuleViolations()
{
if(this.TermID == 0)
yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(1), "agreeWithTerms");
if(ValidationService.ValidateDate(this.Birthdate.ToString()))
yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(2), "birthDate");
if (!(Username.Length >= ConfigurationService.GetMinimumUsernameLength()) ||
!(Username.Length <= ConfigurationService.GetMaximumUsernameLength()))
yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(5), "username");
if(ValidationService.ValidateUsernameComplexity(Username))
yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(6), "username");
if (AccountID == 0 && ObjectFactory.GetInstance<IAccountRepository>().UsernameExists(this.Username))
yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(7), "username");
if (!ValidationService.ValidateEmail(Email))
yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(8), "email");
if (AccountID == 0 && ObjectFactory.GetInstance<IAccountRepository>().EmailExists(this.Email))
yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(9), "email");
yield break;
}
Read here for a full understanding of this: http://nerddinnerbook.s3.amazonaws.com/Part3.htm