asp.net mvc using url - asp.net-mvc

There are VideoAlbum controller and Video controller. When I want to create a video, albumId comes from url.(http://localhost:38500/Admin/Video/Create?albumId=0)
In Creat(video) I am taking video name and some information. I want to post albumId with these information.
Here is my form:
#using (Html.BeginForm("Create", "Video", FormMethod.Post, new { #enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<fieldset id="Proje_Bilgileri">
<div >
#Html.Label("Ad:")
</div>
<div >
#Html.EditorFor(model => model.Name)
</div>
<div >
#Html.Label("Kaynak:")
</div>
<div >
#Html.TextAreaFor(model => model.Data)
</div>
</fieldset>
<input class="button" id="formuGönder" type="submit" value="Save" />
}

Without seeing how you persist your videos to a database for example, it is hard to answer this question.
But if you are using a database, it should be your database that should be creating the new video id so you
do not need to pass it.
Instead your create action should be something similar to below:
[HttpPost]
public ActionResult Create(Video video)
{
if (ModelState.IsValid)
{
db.Videos.Add(video);
db.SaveChanges();
return RedirectToAction("Index");
}
}
You can see this in the music store tutorial

Related

Asp.Net MVC 5 1 View 2 models with viewmodel The model item passed into the dictionary is of type error

I am new to Asp.Net MVC and I am coding a simple blog with using ASP.NET MVC 5 Framework. I can create edit and delete posts. You can see my code on GitHub in details. And I want to add comment property to Details page of every posts or articles. I spent so much time for this and tried several ways. I am trying to make it with using ViewModel Here is my code.
CommentVM:
public DateTime Date { get; set; }
public string CommentContent { get; set; }
public Article articles { get; set; }
public List<Comment> commentList { get; set; }// to show comments which is written before.
Details View:(I modified Details page of Articles. it was #model Blog.Models.Comment I turned to CommentVM and added model.articles.Title. So there is no error in Visual Studio.)
#model Blog.Models.CommentVM
#{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>Article</h4>
<hr />
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.articles.Title)
</dt>
<dd>
#Html.DisplayFor(model => model.articles.Title)
</dd>
.
.
.
</dl>
</div>
<div class="jumbotron">
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-md-10">
#Html.EditorFor(model => model.Date, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="col-md-10">
#Html.EditorFor(model => model.CommentContent, new { htmlAttributes = new { #class = "form-control" } })
</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>
Of course this code is not enough. First of all I should write a controller for this. Default controller for this Details page is this:
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Article article = db.Articles.Find(id);
if (article == null)
{
return HttpNotFound();
}
return View(article);
}
How will I change this Controller Method and View to create and show comments under articles? If you recommend good ViewModel tutorial, I will appretiate this. I want 3 things in Details page 1) Details of an article 2) Create comment 3) show under this comment as in forums or any blog. Please help
You should create a partial view for showing the comments, the model of that view being List<Comment> for displaying the list of comments.
For adding a new comment also can be done using a partial view which will have Comment as the model
Or you can follow the method mentioned in this post
CSHTML
<% using (Html.BeginForm(new { Action = "AddComment", postId = Model._id}))
{ %>
<h2>Title: <%= Model.Title%> </h2>
<%= Model.Body%>
<h3>Comments</h3>
<% if(Model.Comments.Count > 0)
{ %>
<% foreach (var comment in Model.Comments)
{ %>
Name: <%= comment.Name %>
Comment: <%= comment.Text %>
<% } %>
<%
}%>
<h4>Enter Comments</h4>
Name: <%= Html.TextBox("Name")%>
Comment: <%= Html.TextArea("Text")%>
<input type="submit" value="Submit" />
<% } %>

Send Forms issue

I'm developing an application on asp.net.I use the standard modelbinder
I have code
#model Sciencecom.Models.Billboards1
#{
ViewBag.Title = "CreateBilboard";
SelectList owners = new SelectList(new SciencecomEntities().Owners.Select(m=>m.Name).ToList());
}
#using (Html.BeginForm("Bilboard", "Data", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true)
#Html.ValidationMessage("Error")
#*владелец*#
<input type="text" name="Locality" value="345"/>
<input type="text" name="Locality" value="3435" />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Добавить" class="btn btn-default" />
</div>
</div>
</div>
}
I send form on controller.but i have issue .I have reference-null
public ActionResult Bilboard( IEnumerable<Sciencecom.Models.Billboards1> Billboard, IEnumerable<Sciencecom.Models.Surface> test)
{
return View();
}
what ideas?
Inside your form you have only 2 input fields with the same name (Locality) which is quite confusing. So on your server all you can get is a variable with the same name as your input field because that's the only information that is posted back when the form is submitted:
public ActionResult Bilboard(Locality locality)
{
...
}
In the code you have shown in your question your Bilboard action seem to be taking some Billboard and test collection arguments but they are not present as input fields inside your form so you cannot possibly expect them to be populated.

Uploading a file will pass a null object

I have the following _CreateOrEditPartial partial view which contain a text & a file upload:-
#model TMS.Models.DataCenter
#* This partial view defines form fields that will appear when creating and editing entities *#
#Html.AntiForgeryToken()
<div>
<span class="f">Name </span>
#Html.EditorFor(model=>model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div>
<span class="f">Data Center Picture </span>
<input type="file" name="DataCenterfile" />
</div>
and the following main view :-
#using (Html.BeginForm("Create","DataCenter", FormMethod.Post))
{
#Html.ValidationSummary(true)
#Html.Partial("_CreateOrEdit", Model)
<input type="submit" value="Create" class="btn btn-primary"/>
}
Which will call the following ActionMethod:-
[HttpPost]
[ValidateAntiForgeryToken]
[CheckUserPermissions(Action = "Edit", Model = "DataCenter")]
public ActionResult Create(DataCenter dc, HttpPostedFileBase DataCenterfile)
{
// Verify that the user selected a file
if (DataCenterfile != null && DataCenterfile.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(DataCenterfile.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
DataCenterfile.SaveAs(path);
}
but the datacenterfile will always be null .. can anyone advice what is causing this problem?
Thanks
You forgot to add the enctype attribute to your form.
Something like this:
#using (Html.BeginForm("actionName", "controllerName", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
}
About enctype attribute: What does enctype='multipart/form-data' mean?

MVC4 link between view and controller

I'm writing my first MVC app (MVC4). A lot of it's been generated using the excellent Razor tools in VS2010, but now I've run into a wall and I feel I don't understand something fundamental.
In my app,
a User can have access to many Clients.
I have a Client Controller and View.
I have a User Controller and View (expanded version of the simple
membership's UserProfile, populated using User.Identity).
What I want to do is let the user edit a client's details and ALSO edit their own account details on the same page.
I've tried using Html.Partial to add the UserProfile view to the Client view, but it bombs out trying to pass the UserProfile view the Client model.
How do I make the Client view call the UserProfile controller so it can read the User.Identity and return the correct UserProfile view?
I tried making it a viewmodel with both the client and userprofile classes attached, and doing it all on the one screen, but it refused to send values to the controller on submit.
Client view:
#model MyProject.Client
<div>
#Html.Partial("_AcctDetailsPartial")
</div>
<div>
#using (Html.BeginForm())
{
.
.
.
#Html.HiddenFor(model => model.ClientID)
{
.
.
.
<client fields>
{
.
.
.
<div class="form-actions">
<button type="submit" name="ButtonName" value="Company" class="btn blue"><i class="icon-ok"></i> Save</button>
<button type="button" class="btn">Cancel</button>
</div>
}
</div>
UserProfile View:
#model Surecall.UserProfile
<div style="height: auto;" id="accordion1-1" class="accordion collapse">
#using (Html.BeginForm())
{
<h3 class="form-section">Personal Info</h3>
<label class="control-label">First Name</label>
#Html.TextBoxFor(m => m.FirstName, new { #class = "m-wrap span8", #id="FirstName" })
<label class="control-label">Last Name</label>
#Html.TextBoxFor(m => m.Surname, new { #class = "m-wrap span8" })
<label class="control-label">Phone Number</label>
#Html.TextBoxFor(m => m.Mobile, new { #class = "m-wrap span8" })
<label class="control-label">Email</label>
#Html.TextBoxFor(m => m.Email, new { #class = "m-wrap span8" })
<label class="control-label">Position</label>
#Html.TextBoxFor(m => m.Occupation, new { #class = "m-wrap span8" })
<label class="control-label">Interests</label>
#Html.TextBoxFor(m => m.Interests, new { #class = "m-wrap span8" })
<div class="form-actions">
<button type="submit" name="SaveLoginDetails" value="SaveUser" class="btn green"><i class="icon-ok"></i> Save</button>
<button type="button" class="btn">Cancel</button>
</div>
}
</div>
What you are looking for is a Viewmodel.
Right now, your controller serves back a view consisting of the "Client" class/model. But you want a view consisting of Client + UserProfile.
I am not considering unut of work, repository and similar patterns. What you first need is to create the viewmodel
public class ClientUserProfileVM()
{
public Client client {get; set; }
public UserProfile user { get; set; } //use actual Usermodel here
}
In your controller write something like this
public ActionResult GetClientAndUser()
{
ClientUserProfileVM viewmodel = here comes some LINQ magic
select new ClientUserProfileVM {
client,
user
};
return View(viewmodel);
}
This way you are giving a viewmodel to your view consiting of a client and a user, which you can access with #model.user or #model.client in your view
There are plenty of interseting links for this:
ViewModel Best Practices
What is ViewModel in MVC?
http://www.youtube.com/watch?v=AkptHlDSKSQ

Having trouble with ASP.NET MVC 4 image uploading

I'm trying to upload a image along with other fields. Been following examples from here and here
However it seems that the image object isn't passed to the controller and i'm unable to find any error.
Here's the view:
#model Project.Models.ContentNode
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm("Create", "News", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>News</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>
#*Image upload field*#
<div class="editor-field">
<input type="file" name="file" />
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Body)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.Body)
#Html.ValidationMessageFor(model => model.Body)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Here are the controller methods:
public ActionResult Create()
{
var model = new ContentNode();
return View( model );
}
[HttpPost]
public ActionResult Create(ContentNode nyF, HttpPostedFileBase imageData)
{
// Get the type of content from DB
var k = (from ct in _db.ContentTypes
where ct.ID == 1
select ct).Single();
var curUser = (from u in _db.Users
where u.Username == User.Identity.Name
select u).Single();
nyF.Author = curUser;
nyF.ContentType = k;
nyF.dateCreated = DateTime.Now;
_db.ContentNodes.Add(nyF);
_db.SaveChanges();
// Process image
if ((imageData != null && imageData.ContentLength > 0))
{
var fileName = Path.GetFileName(imageData.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
imageData.SaveAs(path);
}
else
{
return Content("The image object wasn't received");
}
return View(nyF);
}
I've read over the whole thing over and over and am unable to see the error. Anyone here willing to point out what I'm doing wrong?
The name of the input file needs to match the action parameter
<input type="file" name="file" />
should be
<input type="file" name="imageData" />
or you change your action parameter name
public ActionResult Create(ContentNode nyF, HttpPostedFileBase file)
You can upload file, using Request.Files in your post method.
You can validate uploaded file using following code.
Request.Files[0].ContentLength

Resources