textarea with writing code - c#

I suffer from the following there
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Posts</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
<h4>Теги:</h4>
</div>
<div class="editor-field">
<input type="text" name="tags" value="#ViewBag.Tags"/><br />
</div>
#Html.HiddenFor(model => model.DateTime, new { #Value = System.DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss") })
#Html.ValidationMessageFor(model => model.DateTime)
<h5>body:</h5><textarea name="body" rows="10" cols="80" required >
</textarea><br />
<div class="editor-label">
#Html.LabelFor(model => model.Avtor)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Avtor)
#Html.ValidationMessageFor(model => model.Avtor)
</div>
<p>
<input type="submit" value="save" />
</p>
</fieldset>
}
in
public ActionResult Create([Bind(Include = "Id,Title,DateTime,Body,Avtor")] Posts post, string tags, string body)
{
if (ModelState.IsValid)
{
tags = tags ?? string.Empty;
string[] tagNames = tags.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string tagName in tagNames)
{
post.Tags.Add(GetTag(tagName));
}
post.Body = body;
db.Posts.Add(post);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(post);
}
public partial class Posts
{
public Posts()
{
this.Comments = new HashSet<Comments>();
this.Tags = new HashSet<Tags>();
}
public int Id { get; set; }
[Required]
[StringLength(64, MinimumLength = 1)]
public string Title { get; set; }
public System.DateTime DateTime { get; set; }
[Required]
[AllowHtml]
public string Body { get; set; }
[Required]
[StringLength(64, MinimumLength = 1)]
public string Avtor { get; set; }
public virtual ICollection<Comments> Comments { get; set; }
public virtual ICollection<Tags> Tags { get; set; }
}
if the user dials in plain text in textarea, it's okay, but there is a need to add the code text. It makes <pre> and <code>but it can only do I have in the program, not the user in textarea. Strictly speaking how to do so in tehtarea could write code and save it in the database and not get an error using <a> <script> and that they could be seen in the text. so the spacecraft itself is implemented on this site. Thanks in advance.

Create a strongly typed model to accept the data posted to the server, use the data annotation AllowHtml to accept HTML as input:
public class SomeViewModel
{
Posts Post { get; set; }
[AllowHtml]
public string Body { get; set; }
}
Then change the controller to
public ActionResult Create(SomeViewModel model)
{
if (ModelState.IsValid)
{
model.Post.Body = model.Body;
db.Posts.Add(model.Post);
db.SaveChanges();
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}
Also try adding this to the following location in your web.config file just above the pages section:
<system.web>
...
<httpRuntime requestValidationMode="2.0" enableVersionHeader="false" />
<pages...
...
</system.web>
Changing the request validation mode will essentially only validation pages rather than every http request. You can read more about it here on MSDN HttpRuntimeSection.RequestValidationMode

Use AllowHTMLAttribute
see this MSDN
This will only allow html for that specific field in your viewmodel but not the whole thing.
or alternatively you can do:
[ValidateInput(false)]
public ActionResult someAction(SomeViewModel model)
{
//Your code to handle the control
}
EDIT: Notice that your textarea is not part of the model in your HTML, can you change that <textarea name="body".... line to:
#Html.TextArea("body", new { rows=10, columns=80 })
After that your body textarea element should be able to capture HTML elements to your controller.

Related

not displaying validation messages while click on button in mvc4

i have created a login page i want it to display validation messages if user doesnt enter username and password on click of button,i have written code as below
Homecontroller.cs
public ActionResult Login()
{
// ViewBag.Message = "Your contact page.";
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(logintable p)
{
abEntities db = new abEntities();
List<sp_logindata_Result> data = db.sp_logindata(p.Username, p.Password).ToList();
Session["LogedUserID"] = data.First().UserID.ToString();
Session["UserNme"] = data.First().FullName.ToString();
int typeVal = data.First().Usertype;
if (typeVal == 1)
{
return RedirectToAction("page1");
}
else if (typeVal == 2)
{
return RedirectToAction("page2");
}
else
{
return RedirectToAction("Error");
}
return View(data);
}
logintable.cs
public partial class logintable
{
public logintable()
{
this.PerformanceDetails = new HashSet<PerformanceDetail>();
this.EvaluationDetails = new HashSet<EvaluationDetail>();
}
public string FullName { get; set; }
[Required(ErrorMessage = "Employee name is required")]
public string Username { get; set; }
[Required(ErrorMessage = "Password is required")]
public string Password { get; set; }
public virtual ICollection<PerformanceDetail> PerformanceDetails { get; set; }
public virtual ICollection<EvaluationDetail> EvaluationDetails { get; set; }
}
login.cshtml
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div>
<fieldset>
<legend>Login</legend>
<div class="editor-field">
#Html.TextBoxFor(u => u.Username)
#Html.ValidationMessageFor(u => u.Username)
</div>
<div class="editor-label">
#Html.LabelFor(u => u.Password)
</div>
<div class="editor-field">
#Html.PasswordFor(u => u.Password)
#Html.ValidationMessageFor(u => u.Password)
</div>
<input type="submit" value="Log In" />
</fieldset>
</div>
}
what i am missing here so it is not displaying messages.
That won't happen automatically
You need to follow at minimum certain steps:
Add validation Rules to your Model [You already done]
Add the scripts that will take care of client side validation (unobstrusive validation) [Required].
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Add the bundle in BundleConfig.cs file, under App_Start folder
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
~/Scripts/jquery.validate*"));

MVC4 edit post method not saving

Im new to asp.net MVC4 , I have an MVC4 application that is using SQL Server 2012 EntityFramework (code first). The Edit post method is not saving the data. On checking if ModelState.IsValid it return false, can anyone help me find whats wrong with my code
MODEL
public class Customer
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage="*")]
public string FirstName { get; set; }
[Required(ErrorMessage = "*")]
public string LastName { get; set; }
[Required(ErrorMessage = "*")]
[MaxLength(1, ErrorMessage="Initial only")]
public string MI { get; set; }
[Required(ErrorMessage = "*")]
public string Address { get; set; }
[Required(ErrorMessage = "*")]
public String ContactNo { get; set; }
[Required(ErrorMessage = "*")]
[DataType(DataType.EmailAddress, ErrorMessage = "Invalid Email")]
public string EmailAddress { get; set; }
[Required(ErrorMessage = "*")]
[MaxLength(8, ErrorMessage = "Max of 8")]
[MinLength(5, ErrorMessage = "Min of 5")]
[DataType(DataType.Password)]
[Display(Name = "Password")]
[NotMapped]
public string Password { get; set; }
[Required(ErrorMessage = "*")]
[DataType(DataType.Password)]
[NotMapped]
[Display(Name = "Retype-PW")]
public string RetypePassword { get; set; }
[Required]
[Display(Name = "How much is")]
[NotMapped]
public string Captcha { get; set; }
}
EDIT VIEW
<h2>Edit CUSTOMER</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Customer</legend>
#Html.HiddenFor(model => model.Id)
#Html.HiddenFor(model=>model.Captcha)
#Html.HiddenFor(model=>model.Password)
#Html.HiddenFor(model=>model.RetypePassword)
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.LastName)
#Html.ValidationMessageFor(model => model.LastName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.MI)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.MI)
#Html.ValidationMessageFor(model => model.MI)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ContactNo)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ContactNo)
#Html.ValidationMessageFor(model => model.ContactNo)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmailAddress)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.EmailAddress)
#Html.ValidationMessageFor(model => model.EmailAddress)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
EDIT CONTROLLER METHOD
public ActionResult Edit(int id = 0)
{
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
//
// POST: /Customer/Edit/5
[HttpPost]
public ActionResult Edit(Customer customer)
{
if (ModelState.IsValid)
{
db.Entry(customer).State = EntityState.Modified;
db.SaveChanges();
if (User.IsInRole("Administrator"))
{
return RedirectToAction("Index");
}
else
{
return RedirectToAction("Details");
}
}
return View(customer);
}
Thanks for the help
#Html.HiddenFor(model=>model.Captcha)
#Html.HiddenFor(model=>model.Password)
#Html.HiddenFor(model=>model.RetypePassword)
this lines are not safety, it's possible view the content in console at the same time maybe isn't the good value in password you make a 8 char limit but you read the value in bd, i hope this value is cripted!, you write a code to more to 8 char well the model isn't valid, try to read the value for this champs in the console and compare with your settings.
the problem you use the same model to create and edit, well for edit isn't required the captha and pasword, the options are make other model, setting not required, check if create or edit mode to set required,
help me find whats wrong with my code
You're using the scaffolded #Html.ValidationSummary(true), where true is passed for hidePropertyErrors. This is fine if your edit form shows an editor for each property of your model, but if not, your page will not show what ModelState errors prevented successful processing. Change true to false to see all errors.
You're using Entity Framework models as ViewModels.
You're allowing mass assignment.
You're not using an cross-site request forgery token.
You've just run into the prime case that demonstrates why you should use ViewModels. One solution is to remove model errors for properties you don't want to see as faulty.
Like:
ModelState.Remove("Captcha");
ModelState.Remove("Password");
ModelState.Remove("RetypePassword");
if (ModelState.IsValid)
{
// your code ...
But this will cause your model to be updated with an empty password null for the properties for which you didn't provide an editor, which you don't want to and which will fail anyway. So you'll need to load the existing entity and update it:
ModelState.Remove("Captcha");
ModelState.Remove("Password");
ModelState.Remove("RetypePassword");
if (ModelState.IsValid)
{
var existingCustomer = db.Customers.First(c => c.ID == customer.ID);
// Update properties of attached entity
existingCustomer.FirstName = customer.FirstName;
existingCustomer.LastName = customer.LastName;
// and so on...
To circumvent most of this clumsiness, simply define a ViewModel:
public class EditCustomerModel
{
[Required(ErrorMessage="*")]
public string FirstName { get; set; }
[Required(ErrorMessage="*")]
public string LastName { get; set; }
// and so on...
}
Then in your action method will look like this:
public ActionResult Edit(EditCustomerModel customer)
{
if (ModelState.IsValid)
{
var existingCustomer = db.Customers.First(c => c.ID == customer.ID);
// Update properties of attached entity
existingCustomer.FirstName = customer.FirstName;
existingCustomer.LastName = customer.LastName;
db.SaveChanges();
return RedirectToAction(...);
}
return View();
}
I used CodeCaster 2nd suggestion but it didn't work, but when I put hidden input for my 3 notmapped fields(Captcha, password, retypepassword) on my view and assigning default values it works now.
<input type="hidden" id="Captcha" name="Captcha" value="Captcha" />
<input type="hidden" id="Password" name="Password" value="Password" />
<input type="hidden" id="RetypePassword" name="RetypePassword" value="RetypePassword" />

Form not saving data to model

I am using MVC in order to build a blog. What I want is to save post comments to its corresponding place in the database but it does not work.
My post model is as follows:
public class Post
{
[Key]
public int PostId { get; set; }
public string Title { get; set; }
public DateTime CreatedDate{get;set;}
public DateTime UpdateDate { get; set; }
public string Body { get; set; }
public ICollection<Comment> Comments { get; set;}
public ICollection<Tag> Tags { get; set; }
}
My Comment model is as follows:
public class Comment
{
[Key]
public int CommentId { get; set; }
public int PostId { get; set; }
[ForeignKey("PostId")]
public virtual Post Post{get; set;}
public string CommentCreateDate { get; set; }
public string CommentUpdateDate { get; set; }
public string CommeterName { get; set; }
public string EmailAddress { get; set; }
public string CommentText { get; set; }
public bool Approved { get; set; }
}
I have the following Action Methods:
[HttpGet]
public ActionResult CreateComment()
{
return View();
}
[HttpPost]
[ValidateInput(false)]
public ActionResult CreateComment(int id, string name, string email, string txt, bool aproved = false)
{
Post post = GetPost(id);
Comment comment = new Comment();
comment.Post = post;
comment.CommentCreateDate = DateTime.Now.ToString();
comment.CommeterName = name;
comment.EmailAddress = email;
comment.CommentText = txt;
comment.Approved = aproved;
db.Comments.Add(comment);
db.SaveChanges();
m_commentList.Add(comment);
return RedirectToAction("CreateComment", new { id = id });
}
And in my view I am trying this:
#model Blog.Models.Comment
#{
ViewBag.Title = "CreateComment";
}
<h2>Create a Comment</h2>
#using (Html.BeginForm())
{
<fieldset>
<legend>Enter Comment</legend>
<div class="editor-label">
#Html.LabelFor(model => model.CommeterName)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.CommeterName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmailAddress)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.EmailAddress)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CommentText)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.CommentText)
</div>
<p>
<input type="submit" value="Create comment" />
</p>
</fieldset>
}
I get no exception but none of the data from the form is being saved. Only the data that is set in the action result, that is, CommentCreateDate and Approved. I am not sure what I am doing wrong.
I have tried a second option which is to include the id of the comment in BeginForm() as follows:
#using (Html.BeginForm(new {id = Model.CommentId}))
{
<fieldset>
<legend>Enter Comment</legend>
<div class="editor-label">
#Html.LabelFor(model => model.CommeterName)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.CommeterName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.EmailAddress)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.EmailAddress)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CommentText)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.CommentText)
</div>
<p>
<input type="submit" value="Create comment" />
</p>
</fieldset>
}
This will give me a null reference exception even if I use the new keyword :
System.NullReferenceException: Object reference not set to an instance of an object.
Why is this happening? Can anybody help?
Thank you
Your action signature should be:
public ActionResult CreateComment(Comment model)
The names generated for the form fields will bind back to the properties of the same model class. There's no way for the framework to know, for example, that the CommenterName property should match up to the name parameter of the action.
Your second example makes very little sense - you're trying to write out the ID but you have never set one. In fact, you don't even pass a Comment to the view with the form, which is why you get a NullReferenceException:
[HttpGet]
public ActionResult CreateComment()
{
return View();
}
Also, you should be careful with what fields you expose to your models and actions. For example, a user could easily force their comment to be approved just by adding the following markup via their browser's development console:
<input type="hidden" name="approved" value="true" />
Anything that is either in your model properties or a parameter to your action can be set by the user.
An altogether better option would be to use a dedicated model class for the form:
public class CreateCommentViewModel
{
public string Name { get; set; }
public string Email { get; set; }
public string Text { get; set; }
}
Then to map this to your Comment in your action with:
[HttpPost]
public ActionResult CreateComment(CommentViewModel model)
{
var comment = new Comment();
comment.CommenterName = model.Name;
// etc...
}
This prevents the user from being able to set things like Approved and CreatedDate.

DropDownList in ASP.NEt MVC Edit method

Good day,
I'm write asp.net mvc3 project with bundle of SQL Server 2012 & EF, I'm use dropdownlist for create & update entry in database. Everything works fine when I add page, but when I'm try to Edit it's unable to save changes. I was try to take brackpoint and in debugging mode Inner exception told that
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
This is my code:
[Table("Pages", Schema = "myprojectname")]
[Bind(Exclude = "PageId")]
public class Page
{
public int PageId { get; set; }
public string PageContent { get; set; }
public int PageTitleId { get; set; }
public virtual PageTitle PageTitle { get; set; }
}
[Table("PageTitles", Schema = "myprojectname")]
public class PageTitle
{
public int PageTitleId { get; set; }
public string Title { get; set; }
public List<Page> Pages { get; set; }
}
public DbSet<Page> Pages { get; set; }
public DbSet<PageTitle> PageTitles { get; set; }
public ActionResult PageEdit(int id)
{
Page page = context.Pages.Find(id);
ViewBag.PageTitleId = new SelectList(context.PageTitles, "PageTitleId", "Title", page.PageTitleId);
return View(page);
}
[HttpPost]
[ValidateInput(false)]
public ActionResult PageEdit(Page page)
{
try
{
if (ModelState.IsValid)
{
context.Entry(page).State = EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Index", "Administrator");
}
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save changes. Please try again");
}
ViewBag.PageTitleId = new SelectList(context.PageTitles, "PageTitleId", "Title", page.PageTitleId);
return View(page);
}
#model BalticCenter.Web.Models.Entities.SitePages.Page
#{
ViewBag.Title = "PageEdit";
Layout = "~/Views/Shared/_AdministratorLayout.cshtml";
}
<h2>PageEdit</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Page</legend>
#Html.HiddenFor(x => x.PageId)
<div class="editor-label">
#Html.LabelFor(model => model.PageTitleId, "PageTitle")
</div>
<div class="editor-field">
#Html.DropDownList("PageTitleId", String.Empty)
#Html.ValidationMessageFor(model => model.PageTitleId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PageContent)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.PageContent)
#Html.ValidationMessageFor(model => model.PageContent)
</div>
<p>
<input type="submit" value="Edit" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
I don't see my mistake. Any ideas?
You have your class Page decorated with [Bind(Exclude = "PageId")]
This means that when you set EntityState to Modified the Entity have no primeary key (id)
context.Entry(page).State = EntityState.Modified;
context.SaveChanges();
And there fore the database can't save the changes

Model (complex type) won't submit to action

I have some problem posting a form with 'complex type' model:
I have a Model:
public class CircleEditViewModel
{
[Key]
public int CircleId { get; set; }
[Required]
[MaxLength(100)]
public string Name { get; set; }
public bool IsSystem { get; set; }
public class UserInCircle
{
public UserInCircle(User user)
{
this.UserId = user.UserId;
FullName = user.FullName;
}
public int UserId { get; set; }
public byte[] Picture { get; set; }
public string FullName { get; set; }
public bool isInCircle { get; set; }
}
public List<UserInCircle> Users { get; set; }
}
My first problem was that at post event, my Users where null.. so i followed a few posts on here (like MVC- Model Binding on a Complex Type) to use a for instead of a foreach,but since i did so, my form won't post anymore:
View:
#model Wims.Website.ViewModels.CircleEditViewModel
<script type="text/javascript">
$(document).ready(function () {
$.validator.unobtrusive.parse('form');
});
</script>
#using (Ajax.BeginForm(Html.ViewContext.RouteData.Values["Action"].ToString(), null, new AjaxOptions { HttpMethod = "POST", OnSuccess = "SaveDone(data)" }, new { id = "editform" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Circle</legend>
#Html.Label(DateTime.Now.ToString());
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</fieldset>
if (Model.Users != null)
{
for (int i = 0; i < Model.Users.Count; i++)
{
<div class="userDetail">
<div>
<div>
#Html.DisplayFor(model => Model.Users[i].isInCircle);
</div>
<div class="iconDiv">
#Html.Image("~/Content/Images/defaultUser.jpg", Model.Users[i].FullName, null);
</div>
<div>
#Html.TextBoxFor(model => Model.Users[i].FullName)
#Html.HiddenFor(model => Model.Users[i].UserId)
</div>
</div>
</div>
<div style="clear: both"></div>
}
}
#Html.GenerateSecureDataControls(model => model.CircleId)
<input type="submit" value="Save" />
}
My view is rendered as a partial loaded thru ajax (not sure it makes any difference here).
Any idea why it won't post? If i remove all the '[]' like 'Users[0].FullName' to Users0.FullName i will post, but of course it won't be bound.
Thanks for your help
Edit just in case needed: Action:
[HttpPost]
public ActionResult Edit(CircleEditViewModel circleData, FormCollection collection)
{
if (ModelState.IsValid)
{
using (var logic = new CircleLogic())
{
Circle circle = logic.GetCircleById(circleData.CircleId, WebMatrix.WebData.WebSecurity.CurrentUserId);
if (circle == null)
{
return HttpNotFound();
}
else
{
circle.Name = circleData.Name;
logic.UpdateCircle(circle, GetSelectedUser(collection));
}
return PartialView("_CircleAndUsers", GetData(logic, circle.CircleId));
}
}
return this.Json(new { success = false, viewdata = RenderRazorViewToString("_CircleAndUsers", circleData) });
}
Pablo Romeo was right, i added a default ctor and it worked.

Categories

Resources