asp mvc return viewmodel with html anchor - viewmodel

I have a view for a blog post that return a view model with the post and the comments, and an anchor point at the end of the page where the comment form is.
After i submit the comment form, i want the POST method to return the View() but with the anchor point in the link
ie : www.blog.com/article/my-first-article#comments
right now i only have www.blog.com/article/my-first-article and in order to view the Validation Errors you must scroll down to the comment.
Any Ideas?
Thanks,
Alex
[HttpPost]
public ActionResult Index(ArticleWithCommentsViewModel vm)
{
if (ModelState.IsValid)
{
var newComm = new comment();
newComm.Name = vm.Name;
newComm.Email = vm.Email;
newComm.CreatedDate = DateTime.Now;
newComm.Comm = vm.Comment;
newComm.ArticleID = vm.ArticleToComment;
_db.comments.InsertOnSubmit(newComm);
_db.SubmitChanges();
return RedirectToAction("Index", "Article");
}
ArticleWithCommentsViewModel vm2 = new ArticleWithCommentsViewModel();
vm2.TheArticle = _db.Articles.ToList().Single(x => x.ArticleID == vm.ArticleToComment);
vm2.comments = _db.comments.ToList().Where(x => x.ArticleID == vm.ArticleToComment);
return View(vm2);
}

Think might be a little low tech but it might work:
return Redirect("www.blog.com/article/my-first-article#comments");

Related

Routing Issue Prevents Display of Image from Database

I'm working on an MVC C# .net Core application. Code is still a work in progress. I'm trying to display an image stored from TinyMce in a SqlServer Database and one of my routes seems to add an extra directory address in the url. So, I figure this is a routing issue, but I'm open to other ideas.
I've searched the web and read microsoft docs, but can't seem to figure out the correct route.
This action method works correctly. Notice there is no {id} parameter.
Displays image correctly in the list.
When View Image is clicked in browser produces the following route...
localhost:44353/images/users/MyImage.jpg
[Route("/[controller]/PostList")]
public IActionResult PostList(Guid tagId, Guid authorId, int numPerPage = 10)
{
ICollection<Post> posts;
string currentTag = string.Empty;
string currentAuthor = string.Empty;
if (tagId == Guid.Empty && authorId == Guid.Empty)
{
posts = _blogRepository.GetRecentPosts(numPerPage).ToList();
currentTag = "All posts";
currentAuthor = "All authors";
}
else if (!(tagId == Guid.Empty) && authorId == Guid.Empty)
{
Tag tag = _tagRepository.GetAllTags().FirstOrDefault(t => t.Id == tagId);
posts = _blogRepository.GetPostsByTag(tag).OrderBy(p => p.ModifiedDate).ToList();
currentTag = tag.Content;
currentAuthor = "All authors";
}
else if (!(authorId == Guid.Empty) && tagId == Guid.Empty)
{
Author author = _authorRepository.Authors.FirstOrDefault(a => a.Id == authorId);
posts = _blogRepository.GetPostsByAuthor(author).OrderBy(p => p.ModifiedDate).ToList();
currentTag = "All posts";
currentAuthor = author.AuthorName;
}
else
posts = _blogRepository.GetRecentPosts(numPerPage).ToList();
return View(new PostListViewModel
{
CurrentTag = currentTag,
CurrentAuthor = currentAuthor,
Posts = posts,
AllTags = _tagRepository.GetAllTags().ToList(),
AllAuthors = _authorRepository.Authors.ToList()
});
}
This Action method does not display the image
When View Image is clicked in browser produces the following route...
localhost:44353/Blog/images/users/MyImage.jpg
Adding {id} apparently changes the route...
I tried several different routes to no avail...
[Route("/[controller]/PostDetail/{id}")]
public IActionResult PostDetail(Guid id)
{
var post = _blogRepository.FindCurrentPost(id);
if (post == null)
return NotFound();
return View(new PostDetailViewModel() {
Post = post,
AllAuthors = _authorRepository.Authors.ToList(),
AllTags = _tagRepository.GetAllTags().ToList()
});
}
Would like to be able to display the image and have the correct route.
I finally figured it out!
I removed all the routes that were stomping the PostDetail Route and added a very simple route to remove "Blog" from the url. I don't know why I had to remove it for the detail but could leave it in the list (I suspect a bug in the version of .net core I'm using which is 2.0.9., but I really don't know.
This is the route to remove the controller from the URL (note: worked only after remove most other routes I defined for the controller first...) Now the image will show up.
[Route("PostDetail/{id}")]
public IActionResult PostDetail(Guid id)
{
var post = _blogRepository.FindCurrentPost(id);
if (post == null)
return NotFound();
return View(new PostDetailViewModel() {
Post = post,
AllAuthors = _authorRepository.Authors.ToList(),
AllTags = _tagRepository.GetAllTags().ToList()
});
}

Post selected dropdown to controller MVC using AJAX or other way

I need to post the selected item's id from dropdown to post method of same controller and the render the content in same view
PLease help me fast :(
My View
#Html.DropDownListFor(x => x.hotelmodel.SelectedHotelId, Model.hotelmodel.DrpHotelList)
<div>
<p>#Model.percentageoccupied</p>
<p>#Model.Revenue</p>
<p>#Model.UnSold</p>
<div>
MY HttpGetMethod
[HttpGet]
public ActionResult Counter()
{
var personid = ((PersonModel)Session["PersonSession"]).PersonId;
var model = new CounterforModel();
model.hotelmodel.DrpHotelList = iCommonservice.GetHotelListByPersonId(personid);
return View(model);
}
My HttpPostMethod
[HttpPost]
public ActionResult Counter(int id)
{
var result = iCommonservice.LoadCounter(id);
model.percentageoccupied = Convert.ToInt32(result[0].percentageoccupied);
model.Revenue = Convert.ToDecimal(result[0].Revenue);
model.UnSold = Convert.ToInt32(result[0].UnSold);
return View(model);
}
In your POST method pass your View Model as parameter. Then you can use the posted hotelModel.SelectedHotelId for what you need, update the model values and pass your updated model to the View.
public ActionResult Counter(CounterforModel model)
{
var result = iCommonservice.LoadCounter(model.hotelmodel.SelectedHotelId);
model.percentageoccupied = Convert.ToInt32(result[0].percentageoccupied);
model.Revenue = Convert.ToDecimal(result[0].Revenue);
model.UnSold = Convert.ToInt32(result[0].UnSold);
return View(model);
}
If you want, you can use #Ajax.BeginForm() or jQuery .ajax() to make an ajax call to your action. You can look here.

Return to current url in asp.net mvc

I have a method:
public ActionResult AddProductToCart(int productId)
{
var product = _productService.GetProductById(productId);
if (product == null)
return RedirectToAction("Index", "Home");
int productVariantId = 0;
if (_shoppingCartService.DirectAddToCartAllowed(productId, out productVariantId))
{
var productVariant = _productService.GetProductVariantById(productVariantId);
var addToCartWarnings = _shoppingCartService.AddToCart(_workContext.CurrentCustomer,
productVariant, ShoppingCartType.ShoppingCart,
string.Empty, decimal.Zero, 1, true);
if (addToCartWarnings.Count == 0)
//return RedirectToRoute("ShoppingCart");
else
return RedirectToRoute("Product", new { productId = product.Id, SeName = product.GetSeName() });
}
else
return RedirectToRoute("Product", new { productId = product.Id, SeName = product.GetSeName() });
}
You see the line which is commented out: I want there to not trigger any redirect but just stay on the same page from where this request was made.
If I put return View() it's not fine because it will search for View with this name while this method is a simple action to add to cart..
Can you please give me a solution of how to Redirect to current url or to stay on the same page?
You could pass an additional returnUrl query string parameter to this method indicating the url to get back to once the product has been added to the cart:
public ActionResult AddProductToCart(int productId, string returnUrl)
so that you can redirect back to wherever you were:
if (addToCartWarnings.Count == 0)
{
// TODO: the usual checks that returnUrl belongs to your domain
// to avoid hackers spoofing your users with fake domains
if (!Url.IsLocalUrl(returnUrl))
{
// oops, someone tried to pwn your site => take respective actions
}
return Redirect(returnUrl);
}
and when generating the link to this action:
#Html.ActionLink(
"Add product 254 to the cart",
"AddProductToCart",
new { productId = 254, returnUrl = Request.RawUrl }
)
or if you are POSTing to this action (which by the way you should probably be because it is modifying state on the server - it adds a product to a cart or something):
#using (Html.BeginForm("AddProductToCart", "Products"))
{
#Html.Hidden("returnurl", Request.RawUrl)
#Html.HiddenFor(x => x.ProductId)
<button type="submit">Add product to cart</button>
}
Another possibility is to use AJAX to invoke this method. This way the user will stay on the page wherever he was before calling it.
Assuming you mean return to where you were before visiting that controller:
return Redirect(Request.UrlReferrer.ToString());
Keep in mind that if you POSTed to get to that [previous] page, you're going to be at a loss since you're not mimicking the same request.

Rendering same View after Http Post in MVC

Trying to repost a view but im getting null to the field I want.
Heres the controller...
public ActionResult Upload()
{
VMTest vm = new VMTest();
return View(vm);
}
[HttpPost]
public ActionResult Upload(VMTest vm, String submitButton)
{
if (submitButton == "Upload")
{
//do some processing and render the same view
vm.FileName = "2222"; // dynamic creation of filename
vm.File.SaveAs(#vm.FileName); // save file to server
return View(vm);
}
else if (submitButton == "Save")
{
//read the file from the server
FileHelperEngine engine = new FileHelperEngine(typeof(PaymentUploadFile));
PaymentUploadFile[] payments = (PaymentUploadFile[])engine.ReadFile(#vm.FileName); // the problem lays here #vm.FileName has no value during upload
//save the record of the file to db
return View("Success");
}
else
{
return View("Error");
}
}
I already had a #Html.HiddenFor(model => Model.FileName) inside my view.
But still I got a null value for Model.FileName.
Any help pls
Thanks
If you intend to modify some values of your view model in the POST action you need to remove the old value from modelstate first:
ModelState.Remove("FileName");
vm.FileName = "2222";
The reason for this is that Html helpers such as TextBox, Hidden, ... will first use the value in the modelstate when binding and after that the value in your view model.
Also instead of:
#Html.HiddenFor(model => Model.FileName)
you should use:
#Html.HiddenFor(model => model.FileName)
Notice the lowercase m in the expression.
The above answer is a good one. You can also do the following
public ActionResult Upload()
{
VMTest vm = new VMTest();
ModelState.Clear();
return View(vm);
}
I usually call ModelState.Clear() before loading a new view. The sytntax for HiddenFor should be
#Html.HiddenFor(m => m.FileName);
I hope this helps.

Pass a value from one controller to another in asp.net mvc

I've been new to ASP.NET MVC. This is what I'm doing. I've 2 Controllers:Home and Customerservice.
Now I have a Customer list where when I click details gets redirected to the products he acquired.
So, I need to pass in the id so that the products of that customer can be displayed. So, my home consists of customer details. Now i need to pass that id to CustomerService controller ,Index action. This is what I've done in Home:
public ActionResult Customers()
{
var dc = new ServicesDataContext();
var query = (from m in dc.Customers
select m);
return View(query);
}
public ActionResult Details(int id)
{
var datacontext = new ServicesDataContext();
var serviceToUpdate = datacontext.Customers.First(m => m.CustomerId == id);
ViewData.Model = serviceToUpdate;
// return View();
return Redirect("/CustomerService");
}
[HttpPost]
public ActionResult Details(FormCollection form)
{
var id = Int32.Parse(form["CustomerID"]);
var datacontext = new ServicesDataContext();
var service = datacontext.Customers.First(m => m.CustomerId == id);
return Redirect("Customers");
}
}
Now I'm not sure whether I need to pass an id as parameter for index in CustomerService. SO can you please guide me in finishing this?
If you are using any Redirect (such as RedirectToAction) you can use TempData to store any parameters. The semantics have slightly changed in MVC 3 but TempData is designed to pass data between actions in a POST-Redirect-GET scenario.
Passing it as a parameter is probably your best option. Try using something like return RedirectToAction(ActionName, ControllerName, RouteValues);.

Resources