Throw into the database as it looks in HTML form - asp.net-mvc

It is such that I have to "update" the database with new content and I print it in pure HTML, but when I throw it into the database with the HTML as it has allocated so that it will in no way throw it into the database
[HttpPost]
[ValidateInput(false)]
public ActionResult index(IndholdViewModel model)
{
if (ModelState.IsValid)
{
var forsideindhold = db.forsides.FirstOrDefault(i => i.Id == 1);
if (forsideindhold != null)
{
//error here
forsideindhold.tekst = new HtmlString(model.Indhold);
.SubmitChanges();
return RedirectToAction("index/Opdater");
}
}
return View();
}
Error happens here:
forsideindhold.tekst = new HtmlString(model.Indhold);
What I well only imagine this is that it remove the HTML it has got hold of by my model.indhold and throw it into the database.
Error are:
cannot convert from 'System.Web.HtmlString' to 'string'

Well your problem is that you can't pass to HtmlString constructor HtmlString.
But actually i can't understand why you need it as long as forsideindhold.tekst is string. You should write it like this:
forsideindhold.tekst = model.Indhold.ToString();
Or:
forsideindhold.tekst = new HtmlString(model.Indhold.ToString()).ToString();

check your value is null or not before insert to model.
if(!string.IsNullOrWhiteSpace(model.Indhold)) forsideindhold.tekst = new HtmlString(model.Indhold.ToString()).ToString();

Related

Validate Data in a CSV file using MVC

I am trying to validate the UK phone number contain in a CSV file before inserting the data in the table. At the moment the if statement is not working when the mobile number is valid the code doesn't jump to the else block. See the code below.
Controller code
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> BulkMEssage(TextMessage messagedetail,
HttpPostedFileBase attachmentcsv,
MobileRecipient messagelink, int ddlshedule, string date)
{
if (ModelState.IsValid)
{
CsvFileDescription csvFileDescription = new CsvFileDescription
{
SeparatorChar = ',',
FirstLineHasColumnNames = true
};
CsvContext csvContext = new CsvContext();
StreamReader streamReader = new
StreamReader(attachmentcsv.InputStream);
IEnumerable<MobileRecipient> list =
csvContext.Read<MobileRecipient>(streamReader,
csvFileDescription);
foreach (var mobilenumber in list)
{
var phoneno = #"/^ (\+44\s ? 7\d{ 3}|\(? 07\d{ 3}\)?)\s ?\d{ 3}\s ?\d{ 3}$/";
if ((!mobilenumber.MobileNumber.Equals(phoneno)))
{
error message Here with the wrong format number
}
else
{
Insert Data in the database
}
}
}
I think I am using the regular expression the wrong way. The column name in my CSV file is called "MobileNumber". Please suggest if you have any better way to do this.

View/Model data isn't refreshing/changing after post/postback, even though I'm using the PRG pattern

Update I have saved my problem a long time ago. The problem was that I was trying to call the view model on the wrong view method! I was calling the base view method (Document), instead of one of it's derived method (like NewDocument, PDFDocument, etc.) Thus it was only giving me the Documents data, which didn't change. I was looking and using the wrong view method all the time... Stephen, when you asked me
"Why do you create derived classes in a method but then return only the base class"
I couldn't answer the question at the time because I didn't even know myself, until I remember that originally, the method wasn't returning the base class. I only changed it so that it can work with the base view method, which was wrong in the first place!
That's what I get for only getting 3-4 hours of sleep in 3 days. Everything works right now. Thanks.
I'm having a hard time trying to figure out why the data in my view isn't changing after I do a post. Originally I was doing it via return View() and it worked, but since it was a partial view, the page didn't look great, so I was reading up and saw that it was better to do it by Post-Redirect-Get pattern (PRG) and to use an id value to retrieve the values instead of sending the entire model via Tempdata. I even used ModelState.Clear() and that didn't even work. When I debugged the code, the model only has the values from when I first called it.
Here's part of my Get controller:
NewDocument Get Controller
[DocumentAuthenticationFilter]
public ActionResult NewDocument(int? id = null)
{
// This doesn't work. The view keeps on showing the data from View(Services.CreateNewDocument()).
if (id != null)
{
return View(Services.GetdocumentViewModelData(DocEnum.Section.NEW_DOC_INDEX, (int)id));
}
// This works fine
return View(Services.CreateNewDocument());
}
And here's the post that calls the redirect:
NewDocument Post controller
[HttpPost]
[ValidateAntiForgeryToken]
[MultipleButton(Name = "action", Argument = "AddDocuments")]
//[OutputCache(Duration = 30, VaryByParam = "*")]
public ActionResult AddDocumentViewModel(FormCollection frm, DocumentViewModel dvm)
{
try
{
if (ModelState.IsValid)
{
int? DocID = Services.AddingNewDocument(dvm);
// See, I even tried to clear it.
ModelState.Clear();
return base.RedirectToAction("NewDocument", new { id = DocID });
}
else
{
// Display errors in the modal
}
return base.RedirectToAction("NewDocument");
}
And here's the old way I did it:
NewDocument Post controller
[HttpPost]
[ValidateAntiForgeryToken]
[MultipleButton(Name = "action", Argument = "AddDocuments")]
//[OutputCache(Duration = 30, VaryByParam = "*")]
public ActionResult AddDocumentViewModel(FormCollection frm, DocumentViewModel dvm)
{
try
{
if (ModelState.IsValid)
{
Services.AddingNewDocument(ref dvm);
dvm.NewRecordMode = DocEnum.Action.UPDATE;
// It worked, but only the partial view showed, and not the entire view.
return PartialView("_NewDocument", dvm);
}
else
{
// Display errors in the model
}
return base.RedirectToAction("NewDocument");
}
Could it be because I'm using a custom model binding?
My Custom Model Binding
public class BaseClassModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var modelType = bindingContext.ModelType;
var modelTypeValue = controllerContext.Controller.ValueProvider.GetValue("ViewModel");
if (modelTypeValue == null)
throw new Exception("View does not contain the needed derived model type name");
var modelTypeName = modelTypeValue.AttemptedValue;
var type = modelType.Assembly.GetTypes().SingleOrDefault(x => x.IsSubclassOf(modelType) && x.Name == modelTypeName);
if (type == null)
{
throw new Exception(String.Format("Derived model type {0} not found", modelTypeName));
}
var instance = bindingContext.Model ?? base.CreateModel(controllerContext, bindingContext, type);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => instance, type);
return base.BindModel(controllerContext, bindingContext);
}
}
EDIT: And here's the GetDocumentViewModelData code:
GetDocumentFromViewModelData
public static DocumentViewModel GetDocumentViewModelData(DocEnum.Section docType, int id)
{
switch (docType)
{
case DocEnum.Section.NEW_DOCUMENT_INDEX:
// NewDocumentTypeViewModel is a child to DocumentTypeViewModel
DocumentTypeViewModel nd = NewDocumentService.GetViewModelByID(id);
return nd;
case DocEnum.Section.PDF_DOCUMENT:
DocumentTypeViewModel pdfvm = PDFDocumentService.GetViewModelByID(id);
return pdfvm;
case DocEnum.Section.XLS_DOCUMENT:
DocumentTypeViewModel xlsvm = XLSDocumentService.GetViewModelByID(id);
return xlsvm;
}
return null;
}
Edit: Also adding the GetViewModelByID function
GetViewModelByID
public static DocumentTypeViewModel GetViewModelByID(int id)
{
docEntities db = new docEntities();
NewDocumentTypeViewModel vm = new NewDocumentTypeViewModel();
// Calls a stored procedure called Select_Documents_ByID(id) to get the note entry
// that was submitted.
List<Select_Documents_ByID_Result> prevNotes = db.Select_Documents_ByID(id).ToList();
StringBuilder sNotes = new StringBuilder();
foreach (var note in prevNotes)
{
sNotes.AppendFormat("{0} - {1}: {2}\n\n", note.CreatedDate.ToString("yyyy-MM-dd HH:mm"), note.username, note.Entry);
}
vm.PreviousNotes = sNotes.ToString();
return vm;
}
Edit: I did a direct creation of the view model inside the Get controller, and it's the same result. when i debugged the view itself, the values from the new view model don't show up. Instead, the values from the initial view model, View(Services.CreateNewDocument()), shows.
[DocumentAuthenticationFilter]
public ActionResult NewDocument(int? id = null)
{
// Right here I created the view model to test thing, but I'm getting the same results. Nothing has changed.
if (id != null)
{
var d = new NewDocumentTypeViewModel(1, "Help!");
// This property is from the base class, DocumentTypeViewModel
d.DocumentTitle = "Testing!";
return View(d);
// Inside the view itself, none of the values in the view model, including the one
// belonging to the base class. It still shows the initial values.
}
// This works fine
// Or maybe not...
return View(Services.CreateNewDocument());
}
Edit: I wanted to see if it was also doing the same thing for the initial call to the view return View(Services.CreateNewDocument()), and decided to change the value for documentTitle in the base class from New Document to a randomly-generated number, after the object has been created.
Here's the code for DocumentTypeViewModel's default constructor:
public DocumentTypeViewModel()
{
DocumentTitle = "New Document";
NewRecordMode = DocEnum.Action.ADD;
DocumentID = 0;
}
And here's the Services.CreateNewDocument() code where I change the DocumentTitle after the View Model has been created.
public DocumentTypeViewModel CreateNewDocument()
{
DocumentTypeViewModel dtvm = new DocumentTypeViewModel();
Random r = new Random();
dtvm.DocumentTitle = r.Next(5, Int32.MaxValue).ToString();
return dtvm;
}
Now in the View, when I call DocumentTitle:
<div class="label-text-group">
#Html.LabelFor(model => model.DocumentTitle)
#Html.EditorFor(model => model.DocumentTitle)
</div>
You would expect to see a randomly-generated number every time the View gets called. Nope, what you would see is "New Document". Weird.
It's seems that Services.GetDocumentViewModelData() is not exactly working correctly. It only carries the values created by the base class' constructor when a view is created, not any values that have been added or changed within GetDocumentViewModelData() itself. Why is that? What's going on? Please help anybody!
I have solved it. Look at the Update section on top. Thanks Stephen.

Redirect page in c# mvc

I have link
http://localhost:3163/PaymentOrder?AgentCode=&InvoiceNo=&AgentName=&FromDate=&fromDate=12%2F11%2F2013&FromDate=12%2F11%2F2013+9%3A08%3A01+SA&toDate=12%2F11%2F2013
after click button "Delete" the page should be redirect to "Index"
return RedirectToAction("Index","PaymentOrder");
But i want keep link same as first, i don't know what method, please help me. thanks
I can fix it, i save session in
public ActionResult Index{
Session["LastPage"] = Request.Url.ToString();
}
after I'm
return Redirect(Session["LastPage"] as String);
You can pass the query strings to the third parameter of RedirecToAction
return RedirectToAction("Index","PaymentOrder", new { fromDate = model.FromDate });
Or pass the entire model as well, that contains the properties similar to your query strings
return RedirectToAction("Index","PaymentOrder", new { paymentModel = model });
As your query string is quite long, it would probably be better to write an extension method and use that instead, to keep your controllers thin. I haven't tested this, but something like this should work:
public static RouteValueDictionary ToRouteDictionary(this NameValueCollection nameValues)
{
if (nameValues == null || nameValues.HasKeys() == false)
return new RouteValueDictionary();
var routeValues = new RouteValueDictionary();
foreach (var key in nameValues.AllKeys)
routeValues.Add(key, nameValues[key]);
return routeValues;
}
Then in your controller:
return RedirectToAction("Index","PaymentOrder", Request.QueryString.ToRouteDictionary());
Just don't redirect but return the view, the URL will remain the same.

ViewBag Assignment

I'm trying to pass a value from my database to the view in asp.net mvc, very simple stuff
public ActionResult SettingsList() {
using (podio_doc_db db = new podio_doc_db() ) {
string app_id = db.Configs.Where(r => r.Key == "app.id").Select(r => r.Value).First();
ViewBag["app_id"] = app_id;
}
return View();
}
However I keep getting this error
Cannot apply indexing with [] to an expression of type 'System.Dynamic.DynamicObject'
It should be this instead:
ViewBag.app_id = app_id;
ViewBag is a dynamic type, meaning you can add parameters, like app_id, at run-time.

Asp.Net MVC 3 - Linq To Entities - PK with Null doesn't get inserted into the db (don't want null :))

I'm using the latest Asp.Net MVC version.
For some reason, when my POST (Action Create) in my controller gets hit.
I can't seem to be able to add it to the entityset.
What i have is,
1) My EntityModel (*.edmx file)
2) Controller which references the entity:
private db.DataContainer _db = new db.DataContainer();
3) My method (i'm using Guid as pk):
[HttpPost]
public ActionResult Create(Client client)
{
try
{
client.Id = Guid.NewGuid();
/* method 2
Client cl = new Client();
cl.Id = Guid.NewGuid();
cl.email = client.email;
cl.Adres = client.Adres;
cl.companyName = client.companyName;
cl.fax = client.fax;
cl.phone = client.phone;
*/
// client.Id = Guid.NewGuid();
_db.ClientSet.AddObject(client);
_db.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception ex)
{
var ex_message = ex.Message;
var ex_data = ex.Data;
var ex_ix = ex.InnerException;
return View();
}
}
4) Following is my InnerException:
[System.Data.SqlClient.SqlException] = {"Cannot insert the value NULL into column 'Id', table 'lst.dbo.ClientSet'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}
Both doesn't seem to work :(
GUIDs are not supported as primary keys in the Entity Framework. You will need to modify your save method to generate a new GUID for your added objects http://msdn.microsoft.com/en-us/library/dd283139.aspx
It seems that changing my "saveCommand" has given my a temporarily solution:
I chaned:
_db.SaveChanges()
To
_db.SaveChanges(System.Data.Objects.SaveOptions.None);

Resources