Show all images in a view "details" in ASP.NET MVC? - asp.net

I try to show all my images in my db but for some reason that I don't understand I can't... if someone can help me, I would appreciate it.... I'm new in ASP.NET MVC, I know a few things but that's all
My View Detail
<div class="row">
<div class="col-md-3">
<img src="#Url.Action("PaginasComics", "Comics", new {IdC = Model.Pages})" />
</div>
</div>
My view is not an IEnumerable<> view, I been thinking in create a partial view and put in this part but i dont know if will work and i dont know how...
Controller
public ActionResult PaginasComics(string IdPagina)
{
var PaginasC = db.Paginas.Where(x => x.IdPaginaC.ToString() == IdPagina).FirstOrDefault();
return File(PaginasC.Paginas, "imagen/jpeg", string.Format("{0}.jpg", IdPagina));
}
This is how I show the images, but is not working... I have the same code to "PORTADA" in model comics and it's work... I'm not really good work with arrays, maybe that's what I need.
Models
public class Comics
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int IdComics { get; set; }
public string Titulo { get; set; } //title
public byte[] Portada { get; set; } //cover
public DateTime FechadeEstreno { get; set; } //date release
public ICollection<PaginasComics> Pages { get; set; }
}
public class PaginasComics
{
public int IdPaginaC { get; set; }
public byte[] Paginas {get; set;}
public int Id_Comic { get; set; } //foreig key of comics
// here i save all the images
}

your url action, you passing IdC as parameters but your controllers asked for IdPagina parameter. try changes the url signature as requested in controller
<img src="#Url.Action("PaginasComics", "Comics", new {IdPagina = Model.Pages})" />

Issue was there you didn't use correctly qoutes in url.Action. And second action method parameter name should match with the parameter you defined in the url.action.
My View Detail
For getting multiple images from Action method and show in the View change this like:
#{
foreach(var pageId in Model.Pages){
<div class="row">
<div class="col-md-3">
<img src="#Url.Action('PaginasComics', 'Comics', new {IdPagina = pageId })" />
</div>
</div>
}
}
For getting single image from Action method and show in the View change this like:
#{
<div class="row">
<div class="col-md-3">
<img src="#Url.Action('PaginasComics', 'Comics', new {IdPagina = Model.Pages })" />
</div>
</div>
}

Related

Why is the object I tried to get from QueryString empty?

I am trying to create a blog site with asp.net core 3.1. I want to add a comment to the blog post, but I cannot get a query string to which blog post I posted.
I shared my codes as follows. Now, what is the reason why the id from the query string always returns 0?
Or what is the situation I am constantly doing wrong?
There is probably a very simple solution but it took me all day please can you help?
Entity;
public class Content : IEntity
{
public int Id { get; set; }
public int CategoryId { get; set; }
public int UserId { get; set; }
public virtual List<ContentComment> ContentComments { get; set; }
}
public class ContentComment : IEntity
{
public int id { get; set; }
public int UserId { get; set; }
public int ContentId { get; set; }
public string Comment { get; set; }
public DateTime CommnetCreateTime{ get; set; }
public virtual Content Contents { get; set; }
}
Controller :
public class BlogContentController : Controller
{
private IBlogService _blogService;
private IContentCommentsServices _contentCommentsServices;
public BlogContentController(IBlogService blogService, IContentCommentsServices contentCommentsServices)
{
_blogService = blogService;
_contentCommentsServices = contentCommentsServices;
}
public IActionResult Index(int id)
{
var blogModel = new ContentViewModel
{
Blogs = _blogService.GetById(id)
};
return View(blogModel);
}
public IActionResult CommentAdd()
{
var model = new ContentCommendViewModel()
{
ContentComments = new List<ContentComment>()
};
return Ok();
}
[HttpPost]
public IActionResult CommentAdd(ContentComment contentComment)
{
contentComment.ContentId = Convert.ToInt32(HttpContext.Request.Query["id"]);
_contentCommentsServices.Add(contentComment);
return RedirectToAction("CommentAdd");
}
}
View Page :
<div class="media-body mt-2" id="yorumyap">
<h5>Yorum Bırakın</h5>
<form asp-controller="BlogContent" asp-action="CommentAdd">
<div class="form-group">
<textarea name="Comment" class="form-control form-control-sm" rows="3" style="resize: none;" id="commenttext"></textarea>
</div>
<div class="text-right">
<button type="submit" class="btn btn-tekisimbilsim mb-2" id="commendAdd">Yorum Yap</button>
</div>
</form>
</div>
You are trying to get the 'id' from the query string of the request. This would require your post URL to look something like: https://example.com/BlogContent/CommentAdd?id=42. Based on the HTML you have provided, I bet your URL looks like: https://example.com/BlogContent/CommentAdd (you can determine what your URL looks like by using your browsers inspection tools to look at the form tag in the HTML). In order to get the desired behavior you will need to update your form tag to look something like this:
<form asp-controller="BlogContent" asp-action="CommentAdd" asp-route-id="#Model.BlogId">
the important part in this is the addition of the 'asp-route-id' tag helper. You can find information about this tag helper (listed as 'asp-route-{value}') and others at:
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-3.1#the-form-tag-helper
But wait, there's more! In this example I just gave more than likely your URL will turn out to be https://example.com/BlogContent/CommentAdd/42 (I say more than likely because this is determined by your route configuration). This will not give you the expected result and the id will again be zero! So you have a couple of options. The easiest is to change the 'asp-route-{value}' tag helper to be something like 'asp-route-contentId'. This would give you html that looks like:
<form asp-controller="BlogContent" asp-action="CommentAdd" asp-route-contentId="#Model.BlogId">
which would generate a URL that would be https://example.com/BlogContent/CommentAdd?contentId=42. You would then need to update your controller code to retrieve the id to look like this:
contentComment.ContentId = Convert.ToInt32(HttpContext.Request.Query["contentId"]);
There are a myriad of other options we could go into but I will stop this essay for the time being here.

Validation in MVC 5 .net

Im try to give alert if there is a error in form in my form there are some text fields validation like below
<div class="form-group">
<div class="row">
<div class="col-lg-4 col-md-4 col-sm-4 col-xm-12">
<label class="control-label form-text-align text-top-padding ">
#Resources.StandardPrice
</label>
</div>
<div class="col-lg-8 col-md-8 col-sm-8 col-xm-12 text-top-padding">
#Html.TextBoxFor(model => model.products.BasicPrice, new { #class = "form-control errorClass", #id = "basicPrice", #placeholder = #Resources.StandardPrice, #onblur = "addClass(this)", #maxlength = Resources.AddNewProductFieldMaxLength })
#Html.ValidationMessageFor(model => model.products.BasicPrice, null, new { #class = "help-inline" })
</div>
</div>
</div>
if there is some error in form how can I give a alert
In order to display the error message and prevent the submission of your form you have to add controls on your model (or ViewModel).
For example if you want that field to be required so that the form will not be submitted only if the user give a value to that field you have to add the [Required] to your product's model attribute "BasicPrice" as follow :
public class products {
public int ID { get; set; }
[Required]
public string Name { get; set; }
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Required]
public string Genre { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
[StringLength(5)]
public string Rating { get; set; }
}
Here's a link to the Microsoft official Documentation which explain the subject and give more details :
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-aspnet-mvc4/adding-validation-to-the-model
If you already did what #Mohamed Kamel Bouzekria suggested and still not working.
it's possible that you missing something in your controller which could this
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult YOurMethod( Model model)
{
if (ModelState.IsValid)//if there is no errors and valid values
{
//do something
db.SaveChanges();
return RedirectToAction("Index");
}
return View();//else return the same view that should display the errors
}
if it still not working then you missing something else in your view.if so post the full code of the view

How to code an auction site with ASP.Net/ MVC 5 / EF

I'm relatively new to ASP.NET so please bear with me.
I'm trying to code a straightforward auction site for a charity, using MVC 5 and Entity Framework with Code-First.
I have created an Item model and controller. The Item model holds fields like the title, description, starting bid, current bid, number of bids, high bidder, etc.
public class Item
{
public int ID { get; set; }
public string Code { get; set; }
public string Title { get; set; }
public string Description { get; set; }
[DisplayName("Starting Bid")] public int StartingBid { get; set; }
public int Increment {get; set;}
public int Bids { get; set; }
[DisplayName("Current Bid")] public int CurrentBid { get; set; }
public string HighBidder { get; set; }
public int CurrentOrStartingBid
{ // The price that is displayed next to an item
get
{
return Bids > 0 ? CurrentBid : StartingBid;
}
}
public int NextBid
{ // The minimum amount that is valid for a new bid
get
{
return Bids > 0 ? CurrentBid + Increment : StartingBid;
}
}
}
(What I have tried to do in the code above is to add these properties CurrentOrStartingBid and NextBid which are not intended to be part of the database record, they are just derivative properties rather than columns in the DB. So hopefully having these as read-only properties will do that...)
I am now making a view for the item detail. This shows the item description, and also features form controls for placing a bid, similar to what you would see on eBay. My question is about how to wire up the logic for the Bid button correctly.
I figure that in the view I should use an HTML form with a submit button for the bidding. This does an HTTP post when the button is hit, and allows me to write a method in the Item controller that gets called at that time.
So my Razor code in the view currently looks like this:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">£</span>
<input type="number" class="form-control" value="#Model.NextBid" id="CurrentBid" name="CurrentBid"/>
</div>
<br />
<button type="submit" class="btn btn-primary btn-lg">Place bid</button>
</div>
}
Using this code allows me to write a controller method with this signature:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Bid([Bind(Include = "ID,CurrentBid")] Item item)
This kind of works so far. But note that I am having to pass the amount that has been bid in the CurrentBid field of the item, before it has been validated server-side. This doesn't feel quite right to me. Is there a way of writing the method so it just takes a signature like this?
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Bid(int itemID, int bidAmount)
Maybe there's a way to do that with query strings or something?
Anyway, once inside the method, things again seem a little weird. Protecting from over-posting, the only fields in the item variable that are valid are ID and CurrentBid. So I then do a lookup in the DbContext to find the actual item that corresponds with that ID and update it:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Bid([Bind(Include = "ID,CurrentBid")] Item item)
{
if (ModelState.IsValid)
{
Item i2 = db.Items.Find(item.ID);
if (item.CurrentBid >= i2.NextBid)
{
i2.Bids++;
i2.CurrentBid = item.CurrentBid;
i2.HighBidder = HttpContext.User.Identity.Name;
db.Entry(i2).State = EntityState.Modified;
db.SaveChanges();
}
return View(i2);
}
return RedirectToAction("Auction");
}
This seems to work. But it does not feel right. I think I am missing some important concepts/patterns here. If any experienced MVC folks could sketch how they would wire up the client/server logic for this simple button, that would be great. (You would also be helping a good cause!)
Is there a way of writing the method so it just takes a signature like
this?
[HttpPost] [ValidateAntiForgeryToken]
public ActionResult Bid(int itemID, int bidAmount)
Sure there is a way, lets say you have a simple model like this -
public class Item
{
public int ID { get; set; }
public int NextBib { get; set; }
public int CurrentBid { get; set; }
public string Description { get; set; }
}
Then your Action is creating an Item and sending to View as shown below -
public ActionResult BidForm()
{
Item i = new Item();
i.ID = 100;
i.CurrentBid = 10;
return View(i);
}
And your view is as follows -
#model MVC.Controllers.Item
#{
ViewBag.Title = "BidForm";
}
<h2>BidForm</h2>
#using (Html.BeginForm("Bid", "sample", FormMethod.Post))
{
#Html.AntiForgeryToken()
<input type="hidden" name="itemId" value="#Model.ID" />
<input type="number" class="form-control" value="#Model.NextBib" id="CurrentBid" name="bidAmount" />
<input type="submit" value="Create" />
}
And your NextBid action would be -
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Bid(int itemID, int bidAmount)
{
return View();
}
As you see we have an HiddenField with name = itemID and a input type=number field with name = `bidAmount. Those are mapped to parameters of the action as shown below -
Some recommendations which you can consider -
Instead of using regular HTml.BeginForm(), you can go for Ajax.BeginForm() to give more intuitive user experience. Alternatively you can use JQuery POST operation too.
To prevent OVER posting, you need to create specific ViewModels for specific activities like increasing a bid, displaying a product etc. And you post only required viewModels for required activities, so that you can prevent over posting of form.

asp net mvc3 post a list of objects to action

I created a page with aspnet mvc3. It show all users info as a list. I want to do something with this list. There are some checkboxes that belong to each items. When I click some checkboxes and press submit button, I want to post the whole list as a collection and save each items of this collection to database. There are several notes on internet but there is no exact solution. I have a UserDto. and want to use this to transfer users data in all sections.
Does anyone have any full solution about this or can they give any idea?
Thanks in advance.
Kerem
I added some of my codes. You can see the lead sentences what they are about.
this is my index view detail:
#model List<DomainModel.UserApprovalDto>
#{
ViewBag.Title = "Manage Users";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>
Manage Users</h2>
<div>#Html.Partial("_PartialManageUsers", (List<DomainModel.UserApprovalDto>)Model) </div>
this is my partial view detail:
#model List<DomainModel.UserApprovalDto>
#using (Html.BeginForm("ConfirmUsers", "ManageUsers", FormMethod.Post))
{
<table>
<tr>
<th>
Name
</th>
<th>
Is Reported
</th>
</tr>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.DisplayFor(modelItem => Model[i].FirstName)
</td>
<td>
#Html.CheckBox("IsReported", Model[i].IsReported.HasValue ? Model[i].IsReported.Value : false)
#*#Html.CheckBoxFor(modelItem => Model[i].IsReported.Value);*# #* #if (Model[i].IsReported != null)
{
#Html.CheckBoxFor(modelItem => Model[i].IsReported.Value);
}
else
{
#Html.CheckBoxFor(modelItem => Model[i].IsReported.Value);
}*#
</td>
<td>
</td>
</tr>
}
</table>
<div>
<input name="submitUsers" type="submit" value="Save" />
</div>
}
this is my controller submit method
[HttpPost]
public ActionResult ConfirmUsers(List<DomainModel.UserApprovalDto> collection)
{
if (ModelState.IsValid)
{
//TO-DO
}
return RedirectToAction("Index");
}
this last one is my DTO class detail:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DomainModel
{
public class UserApprovalDto
{
public long UserId { get; set; }
public Guid CarUserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhotoPath { get; set; }
public string PhotoSmallPath { get; set; }
public string PhotoSquarePath { get; set; }
public string PhotoBigPath { get; set; }
public bool IsBlocked { get; set; }
public bool IsDeleted { get; set; }
}
}
when I submit this code my list return null collection to my controller method.
thanks for your comments.
Assuming you are creating a screen which adds/ remove users to a course. So let's create some viewmodels
public class CourseVM
{
public string Name { set;get;}
public int CourseID { set;get;}
public List<UserVM> Users { set;get;}
public CourseVM()
{
Users=new List<UserVM>();
}
}
public class UserVM
{
public string Name { set;get;}
public int UserID{ set;get;}
public bool IsSelected { set;get;}
}
Now in your GET Action, you will fill the values of the ViewModel and sent it to the view.
public ActionResult Add()
{
var vm = new CourseVM();
//The below code is hardcoded for demo. you may replace with DB data.
vm.Users.Add(new UseVM { Name = "Jon" , UserID=1});
vm.Users.Add(new UseVM { Name = "Scott", UserID=2 });
return View(vm);
}
Now Let's create an EditorTemplate. Go to Views/YourControllerName and Crete a Folder called "EditorTemplates" and Create a new View there with the same name as of the Property Name(UserVM.cshtml)
Add this code to your new editor template.
#model ChannelViewModel
<p>
<b>#Model.Name</b> :
#Html.CheckBoxFor(x => x.IsSelected) <br />
#Html.HiddenFor(x=>x.Id)
</p>
Now in your Main View, Call your Editor template using the EditorFor Html Helper method.
#model CourseVM
#using (Html.BeginForm())
{
<div>
#Html.EditorFor(m=>m.Users)
</div>
<input type="submit" value="Submit" />
}
Now when you post the form, Your Model will have the Users Collection where the Selected Checkboxes will be having a True value for the IsSelected Property.
[HttpPost]
public ActionResult Add(CourseVM model)
{
if(ModelState.IsValid)
{
//Check for model.Users collection and Each items
// IsSelected property value.
//Save and Redirect(PRG pattern)
}
return View(model);
}

ASP.NET MVC3: Interaction between Partial View and Main View

I have a partial view for contact. Currently the index view shows this partial view for contact details. There is a save button inside the partial view to save the edited data. There is a validation for age while saving the edited data. This much is working fine.
Whenever user edit age and save it, I need to show the corresponding horoscope prediction on the main view. How do we achieve it?
public class ContactEntity
{
public int ContactID { get; set; }
public string ContactName { get; set; }
[Range(18, 50, ErrorMessage = "Must be between 18 and 50")]
public int ContactAge { get; set; }
}
public class AgeHoroscope
{
public int Age { get; set; }
public string HoroscopePrediction { get; set; }
}
//Home Controller
namespace MYContactEditPartialViewTEST.Controllers
{
public class HomeController : Controller
{
List<AgeHoroscope> horoList = new List<AgeHoroscope>()
{
new AgeHoroscope{Age=16,HoroscopePrediction="You are confused"},
new AgeHoroscope{Age=26,HoroscopePrediction="You are very brilliant"},
new AgeHoroscope{Age=27,HoroscopePrediction="You are practical"}
};
public ActionResult Index()
{
AgeHoroscope selectedHoro = horoList[1];
return View(selectedHoro);
}
}
}
//Contact Controller
namespace MYContactEditPartialViewTEST.Controllers
{
public class ContactController : Controller
{
public PartialViewResult MyContactDetailEdit()
{
Thread.Sleep(500);
return PartialView(GetContact());
}
[HttpPost]
public PartialViewResult MyContactDetailEdit(string conatcclick)
{
//Save to database
Thread.Sleep(500);
return PartialView(GetContact());
}
private ContactEntity GetContact()
{
ContactEntity contactEntity = new ContactEntity();
contactEntity.ContactID = 1;
contactEntity.ContactName = "Lijo";
contactEntity.ContactAge = 26;
return contactEntity;
}
}
}
//Index.cshtml
#model MYContactEditPartialViewTEST.AgeHoroscope
#{
ViewBag.Title = "Index";
}
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<h2>
Index</h2>
<div>
<a>Your age is <b>#Html.DisplayFor(x => x.Age) </b>and the prediction is <b>" #Html.DisplayFor(x => x.HoroscopePrediction)
" </b></a>
<br />
</div>
<div style="border: 3px solid Teal">
#Html.Action("MyContactDetailEdit", "contact")
</div>
// MyContactDetailEdit.cshtml
#model MYContactEditPartialViewTEST.ContactEntity
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<h3>MyContactDetailEdit PARTIAL</h3>
<div>
#Html.HiddenFor(x => x.ContactID)
<br />
<div style="font-weight:bold">
Name:
<br />
</div>
#Html.DisplayFor(x => x.ContactName)
<br />
<br />
<div style="font-weight:bold">
Age
<br />
</div>
#Html.EditorFor(x => x.ContactAge)
#Html.ValidationMessageFor(model => model.ContactAge)
<br />
<br />
</div>
<input type="submit" id="saveButton" value="Save" />
}
READING
ASP.Net MVC Passing multiple parameters to a view
ASP.Net MVC 3 RC2, Partial Views Form Handling
I would like just use jQuery to do ajax post and then change the parent view client side directly
you'll need to create a new ViewModel to do this. This ViewModel (IndexViewModel.cs) would look something like this (I'm guessing at this):
public class IndexViewModel
{
public int ContactID { get; set; }
public string ContactName { get; set; }
public int ContactAge { get; set; }
public string HoroscopePrediction { get; set; }
}
you'd then use it in your controller index action (and view):
#model MYContactEditPartialViewTEST.IndexViewModel
the idea being that you'd populate the HoroscopePrediction in a join between ContactEntity and AgeHoroscope (or via Linq etc) and thus show each line in the index as a complete object (showing contact and horoscope).
As data is posted to "HomeController" and "Index" action, so changes are reflected when you change age in View.
Try to modify the home controller as follows,then it will work as expected.
1) Instead of having a list of AgeHoroscope, we can have a dictionary of age and prediction.
2) Create two Index Action for HttpGet and HttpPost as follows.
public class HomeController : Controller
{
Dictionary<int, string> AgePred = new Dictionary<int, string>()
{
{16,"You are confused"},
{26,"You are very brilliant"},
{27,"You are practical"}
};
[HttpGet]
public ActionResult Index()
{
AgeHoroscope selectedHoro = new AgeHoroscope() { Age = 26 };
selectedHoro.HoroscopePrediction = AgePred[selectedHoro.Age];
return View(selectedHoro);
}
[HttpPost]
public ActionResult Index(AgeHoroscope model,ContactEntity entity)
{
model.Age = entity.ContactAge;
model.HoroscopePrediction = AgePred[entity.ContactAge];
return View(model);
}
}

Resources