Forgive the newbie ASP.NET MVC question. I am used to tutorials where Code First is used with the Entity Framework. Here, this is not the case. I have a form that I want the user to fill out. When it has been filled out, I want to use EF to write the values to an existing database. I can't figure out how to "trap" the values in the view so I can write my EF code. I used a model and I redirected the BeginForm to an "Edit" action method but I don't know how to get my filled in class. Here is the HomeController methods:
[HttpGet]
public ActionResult Trial()
{
UserAccount account = new UserAccount();
return View(account);
}
public ActionResult Edit()
{
}
Here is the model class:
public class UserAccount
{
public int AccountID { get; set; }
public string AccountName { get; set; }
public string RegistrationCode { get; set; }
public DateTime Created { get; set; }
}
}
Here is the View the wizard generated. When I hit the "Create" button, I want to go to the "Edit" action menu or someplace I can use EF to write to the existing database table. How do I do this?
#model AlphaFrontEndService.Models.UserAccount
#{
ViewBag.Title = "Trial";
}
<h2>Trial</h2>
#using (Html.BeginForm("Edit", "Home"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>UserAccount</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.AccountID, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.AccountID)
#Html.ValidationMessageFor(model => model.AccountID)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.AccountName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.AccountName)
#Html.ValidationMessageFor(model => model.AccountName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RegistrationCode, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.RegistrationCode)
#Html.ValidationMessageFor(model => model.RegistrationCode)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Created, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Created)
#Html.ValidationMessageFor(model => model.Created)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
You need a POST action for Trial method like below:
[HttpPost]
public ActionResult Trial(UserAccount model)
{
if (ModelState.IsValid)
{
//Store the form data into your database
}
return View(model);
}
Then in your view, add a submit button element inside the form, also instead of Edit, you just need to use Trial for the postback.
#using (Html.BeginForm("Trial", "Home")) {
//
<input type="submit" value="Submit"/>
}
Note: You don't need to create other Edit action method if you don't have some other reasons.
If you don't know how to save the data to your database, below is an example:
Create your DbContext class
public class MyDbContext : DbContext
{
public MyDbContext()
: base("name=YourDbConnection")
{
}
public DbSet<UserAccount> UserAccounts { get; set; }
}
Then the action method will looks like:
public class HomeController : Controller
{
//
[HttpPost]
public ActionResult Trial(UserAccount model)
{
if (ModelState.IsValid)
{
using (var db = new MyDbContext())
{
db.UserAccounts.Add(model);
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(model);
}
}
Related
I am trying to read a value from a view in aps.net mvc: I am aware that this seems like a very basic issue, however, i could not find any solution for this, so i am turning to you: In my case, it seems as if the parameter playlistModel.Model.Name is never sent, or at least is null.
My controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(PlaylistViewModelDetails playlistModel)
{
if (!String.IsNullOrEmpty(playlistModel.Model.Name))
{
//this is never called due to playlistModel.Model.Name being null.
return RedirectToAction("Index");
}
return View(playlistModel);
}
#model Orpheus.Models.ViewModels.PlaylistViewModelDetails
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Erstellen" class="btn btn-default" />
</div>
</div>
</div>
}
public class PlaylistViewModelDetails
{
public PlaylistModel Model = new PlaylistModel(); //a seperate class containing a string value, which must be read from the form
}
Thank you for helping me to solve this issue!
Your PlaylistViewModelDetails contains only a field for Model. The DefaultModelBinder only binds properties, not fields.
Change your model to
public class PlaylistViewModelDetails
{
public PlaylistModel Model { get; set; }
}
and add a parameter-less constructor if you want to initialize PlaylistModel
public PlaylistViewModelDetails()
{
Model = new PlaylistModel();
}
Note also Name in PlaylistModel also need to be a property.
I have some problems with SelectList and DropDownList.
Ich have the two Models (TimeRecord has a navigation-property to Project):
public class Project
{
public int ProjectId { get; set; }
[Required]
public string ProjectName { get; set; }
}
and
public class TimeRecord
{
public int TimeRecordId { get; set; }
public int ProjectId { get; set; }
public string Description { get; set; }
public Project TmRecProject { get; set; }
}
In my Controller in the Create-action method the SelectList is pass by ViewBag to the View (till now all is correct working)
public ActionResult Create()
{
ViewBag.ProjectId = new SelectList(db.Projects, "ProjectId", "ProjectName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(TimeRecord timeRecord)
{
if (ModelState.IsValid)
{
db.TimeRecords.Add(timeRecord);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(timeRecord);
}
Here is the View:
#model SelectListDropDownTest.Models.TimeRecord
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>TimeRecord</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.TmRecProject.ProjectId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProjectId", null, new { #class = "form-control" } )
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
In the Create-View I can select a Project from the DropDownList. My Problem is when I pass the Model "TimeRecord" back to the Controller the Project "TmRecProject" is always null.
What is the best way to solve this Problem?
First of all I am not able to understand how are you able to select value from dropdown list as you have not bind your 'ViewBag.ProjectId' with your drop down list.
Change in your view and your code will start working !!!!
Change:
Bind the drop down list with the model in View.
#Html.DropDownListFor(model => model.TmRecProject.ProjectId, ViewBag.ProjectId as IEnumerable<SelectListItem>, new { #class = "form-control" })
Others are as it is and you will get data on your post method.
I have the following model:
public class Photo
{
public int PhotoId { get; set; }
public byte[] ImageData { get; set; }
public DateTime DateUploaded { get; set; }
public string Description { get; set; }
public bool IsActive { get; set; }
}
I would like the user to be able to enter the details for the photo then post the model the the controller. My controller action is as follows:
[HttpPost]
public ActionResult Create(WilhanWebsite.DomainClasses.Photo photo)
{
if (ModelState.IsValid)
{
photo.DateUploaded = DateTime.Now;
_context.Photos.Add(photo);
_context.SaveChanges();
return RedirectToAction("Index");
}
//we only get here if there was a problem
return View(photo);
}
My view is as follows:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Photo</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.ImageData, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="uploadImages" class="input-files" />
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DateUploaded, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DateUploaded)
#Html.ValidationMessageFor(model => model.DateUploaded)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Description, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IsActive, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.IsActive)
#Html.ValidationMessageFor(model => model.IsActive)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
The view is displayed ok and allows the user to select a file from their local disk and enter the other model details.
My problem is that although the model is posted to the controller ok, the Description, Date and IsActive flags are populated ok - the Image data is null.
Could anyone please let me know what I need to change so that the byte array for the photo is included in the model posted to the controller?
The file input in your view has a name uploadImages. I can't see a property with this name in your view model. You seem to have some ImageData property which is a byte array, but there doesn't seem to be a corresponding input field with this name in your view.
This explains why you get null. You could make this work by respecting the convention. So for example if you intend to have such an input field in your view:
<input type="file" name="uploadImages" class="input-files" />
then make sure that you have a property on your view model with the same name. And of course of type HttpPostedFileBase.
public HttpPostedFileBase UploadImages { get; set; }
Also in your view make sure you are setting the proper content type of multipart/form-data:
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
}
You probably might want to go through the following blog post to better familiarize yourself with the basics of how uploading of files work in ASP.NET MVC. I've also written a similar answer here that you might consult.
So once you add the HttpPostedFileBase property with the UploadImages name in your view model you could adapt your controller action to read the byte array and store it your ImageData property:
[HttpPost]
public ActionResult Create(WilhanWebsite.DomainClasses.Photo photo)
{
if (ModelState.IsValid)
{
photo.DateUploaded = DateTime.Now;
photo.ImageData = new byte[photo.UploadImages.ContentLength];
photo.UploadImages.Read(photo.ImageData, 0, photo.ImageData.Length);
_context.Photos.Add(photo);
_context.SaveChanges();
return RedirectToAction("Index");
}
//we only get here if there was a problem
return View(photo);
}
Now bear in mind that this is an absolutely awful solution. Never do that in a real world application. In a correctly designed application you will have a view model that your controller action will take as a parameter. You're never gonna directly use your autogenerated EF model as parameter to your controller action. You will have a view model with the HttpPostedFileBase property which will be mapped to your domain model.
So in a properly designed application you will have a PhotoViewModel view model class that your controller action will take.
Change this line:
#using (Html.BeginForm())
To this:
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
Then change:
<input type="file" name="uploadImages" class="input-files" />
To:
<input type="file" name="ImageData" class="input-files" />
Then change this line:
public byte[] ImageData { get; set; }
To this:
public HttpPostedFileBase ImageData { get; set; }
Finally, use some code like this to read the image into a byte array:
var bs = new byte[ImageData.ContentLength];
using (var fs = ImageData.InputStream)
{
var offset = 0;
do
{
offset += fs.Read(bs, offset, bs.Length - offset);
} while (offset < bs.Length);
}
View:
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
<input type="file" id="ImageFile" name="ImageFile" .../>
...
}
Controller:
[HttpPost]
public ActionResult Create(Photo photo, HttpPostedFileBase ImageFile)
{
byte[] buf = new byte[ImageFile.ContentLength];
ImageFile.InputStream.Read(buf, 0, buf.Length);
photo.ImageData = buf;
...
}
I'm learning about using ViewModels to pass information from the view to the controller and vice versa. I have my create action, view, and viewmodel working perfectly but I'm having trouble with the edit one. I get the error:
The model item passed into the dictionary is of type 'CatVM.Models.Cat', but this dictionary requires a model item of type 'CatVM.Models.EditCatViewModel'.
Here is my code:
Controller Method
// GET: /Cats/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Cat cat = unitOfWork.CatRepository.GetByID(id);
if (cat == null)
{
return HttpNotFound();
}
return View(cat);
}
View
#model CatVM.Models.EditCatViewModel
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Cat</h4>
<hr />
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Color, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Color)
#Html.ValidationMessageFor(model => model.Color)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FurLength, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FurLength)
#Html.ValidationMessageFor(model => model.FurLength)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Size, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Size)
#Html.ValidationMessageFor(model => model.Size)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
EditCatViewModel
public class EditCatViewModel
{
public int ID { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[StringLength(50)]
public string Color { get; set; }
[Required]
[StringLength(50)]
[Display(Name = "Fur Type")]
public string FurLength { get; set; }
[StringLength(50)]
public string Size { get; set; }
}
}
That's because the item you receive from CatRepository.GetByID(id); is of type Cat, not EditCatViewModel.
You can bypass this by constructing a new viewmodel from this object:
Cat cat = unitOfWork.CatRepository.GetByID(id);
var viewModel = new EditCatViewModel {
Name = cat.Name,
Color = cat.Color,
FurLength = cat.FurLength,
Size = cat.Size
};
return View(viewModel);
Alternatively you could construct implicit or explicit casting methods or use a mapping tool like AutoMapper.
Your return view should be of type CatVM.Models.EditCatViewModel now your returning a Cat
return View(cat);
transform your model in a view model and pass this object back to the view
I am semi-new to ASP.NET MVC, I have used it in the past but not to the extent of what I have been planning to use it for and to learn from for some projects I am working on. I know this question has been asked a lot over the internet and there are many solutions so I will try and keep this as specific as possible regarding uploading images and storing them in a SQL Server database.
I am currently using .NET 4.5 with MVC5 (VS 2013) to do all my coding.
To begin I found a great tutorial that got me up and running with being able to upload images to my SQL Server 2008 database: http://www.mikesdotnetting.com/Article/125/ASP.NET-MVC-Uploading-and-Downloading-Files
Everything works great after I figured out how the functions worked from the site, but the issue I am having is that I have multiple text fields that I want to include data from into the SQL Server database along with including an image upload feature that I created based off the tutorial I found online.
The first part of my code is the Models (BeerList.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
namespace YBPP_Production.Models
{
public class BeerList
{
public int ID { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
[Required(ErrorMessage = "Company is required.")]
public string Company { get; set; }
[Required(ErrorMessage = "Type is required.")]
public string Type { get; set; }
[Required(ErrorMessage = "City is required.")]
public string City { get; set; }
[Required(ErrorMessage = "State is required.")]
public string State { get; set; }
[Required(ErrorMessage = "Country is required")]
public string Country { get; set; }
public string ABV { get; set; }
public string IBU { get; set; }
}
public class Info : DbContext
{
public DbSet<DBName> MoreDB { get; set; }
}
}
The string listed there are the text fields I am trying to pull into my database and I can do that but when I try to mix in the image upload feature either the text will upload or the image will upload depending on how I do the calls.
The Controllers section of my code (BeerListController.cs)
// GET: /BeerList/Create
public ActionResult Create()
{
return View();
}
// POST: /BeerList/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,Name,Company,Type,City,State,Country,ABV,IBU")] BeerList beerlist)
{
if (ModelState.IsValid)
{
db.BeerListDB.Add(beerlist);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(beerlist);
}
public ActionResult FileUpload(HttpPostedFileBase file)
{
//Begin the Image Uploading Process
foreach (string upload in Request.Files)
{
if (!Request.Files[upload].HasFile()) continue;
string mimeType = Request.Files[upload].ContentType;
Stream fileStream = Request.Files[upload].InputStream;
string fileName = Path.GetFileName(Request.Files[upload].FileName);
int fileLength = Request.Files[upload].ContentLength;
byte[] fileData = new byte[fileLength];
fileStream.Read(fileData, 0, fileLength);
const string connect = #"Server=localhost;database=<database-name>;uid=<username-here>;pwd=<there-a-passwordhere>";
using (var conn = new SqlConnection(connect))
{
var qry = "INSERT INTO BeerLists (FileContent, mimeType, FileName) VALUES (#FileContent, #mimeType, #FileName)";
var cmd = new SqlCommand(qry, conn);
cmd.Parameters.AddWithValue("#FileContent", fileData);
cmd.Parameters.AddWithValue("#MimeType", mimeType);
cmd.Parameters.AddWithValue("#FileName", fileName);
conn.Open();
cmd.ExecuteNonQuery();
}
}
return View();
}
The view part of my code (Create.cshtml)
#model YBPP_Production.Models.BeerList
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype="multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>BeerList</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Company, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Company)
#Html.ValidationMessageFor(model => model.Company)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Type, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Type)
#Html.ValidationMessageFor(model => model.Type)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.City, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.City)
#Html.ValidationMessageFor(model => model.City)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.State, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.State)
#Html.ValidationMessageFor(model => model.State)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Country, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Country)
#Html.ValidationMessageFor(model => model.Country)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ABV, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ABV)
#Html.ValidationMessageFor(model => model.ABV)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IBU, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.IBU)
#Html.ValidationMessageFor(model => model.IBU)
</div>
</div>
<div class="form-group">
<p class="control-label col-md-2">Image Upload:</p>
<div class="col-md-10">
<input type="file" id="ImageUpload" name="ImageUpload" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" name="Submit" id="Submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
So what I am looking to hopefully get help with is being able to merge the function of Create and FileUpload into one function so that the form will take both the text in the text-fields and the image that gets uploaded with it. I have read a bunch of other people's posts and code and they all seem to have their own way to doing things but everyone example never includes text-fields or any other form functions just the basic image upload.
Thank you very very much in advance for any direction/suggestions/help to this issue.
You can create model that contains HttpPostedFileBase, then save your entire form with selected file.
Model:
public class BeerListModel
{
public int ID { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
[Required]
public HttpPostedFileBase file { get; set; }
}
View:
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="form-group">
<p class="control-label col-md-2">Image Upload:</p>
<input type="file" id="file" name="file" />
</div>
<div class="form-group">
<input type="submit" name="Submit" id="Submit" value="Create" class="btn btn-default" />
</div>
</div>
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(BeerListModel model)
{
if (ModelState.IsValid)
{
//your logic
}
return View("Create");
}
#Szakus' answer is the overall direction you want to go with respect to uploading a file, however when you asked, " I am still a bit confused as to what I should put as far as my logic for the Controller" you inadvertently got to the root of your problem.
I would strongly recommend you do some research into separation of concerns. Putting raw SQL code in your controller is not a great idea and will open your application to a host of the other issues.
I know this doesn't really answer your question but having been where you are now I can tell you that the old adage, "an ounce of prevention is worth a pound of cure" will save you major headaches down the road.
If you want to see an example of a really good .net MVC project that you can use as sort of a template in building your skills I would recommend the open source shopping cart nopCommerce.