locked
Trouble sending value to controller from frontend and returning view from it -- RRS feed

  • Question

  • User-215451226 posted

    Hi.

    My project is in .netcore 2.2. As you already read above, my problem is like so -
    Am sending parameter value from razor view to backend controller.

    cshtml:

    <a href="api/Product/ProductDetail?id=@product.Id">
                                        @if (product.product_imageurl != null)
                                        {
                                            <img class="card-img-top img-fluid" src="@product.product_imageurl?w=170&h=170"  alt="@product.product_name" />
                                        }
                                        else
                                        {
                                            <img class="card-img-top img-fluid" src="/Images/no-image.png" alt="@product.product_name" />
                                        }
                                    </a>

    Controller code:

    [Route("api/[controller]")]
        public class ProductController : Controller
        {
    		protected ProductDataService pService {get;set;}
    
            public ProductController(ProductDataService _pS)
            {
                pService = _pS;
            }
    	
    		[Route("ProductDetail")]
            [HttpGet]
            public IActionResult ProductDetail(int p_id)
            {
                if(p_id>0)
                {
                    var pEntity = pService.GetProductById(p_id);
                    if(pEntity!=null)
                    {
                        ViewData["ProductId"] = pEntity.Id;
                        return View("ProductDetail", pEntity);
                    }
                    else
                    {
                        return RedirectToAction("Index");
                    }
                }
                else
                {
                    return RedirectToAction("Index");
                }
            }
    	
    	}

    When I click hyperlink the link I generate is like so for eg:

    https://localhost:44383/api/Product/ProductDetail?id=7

    Trouble is no value gets passed to [int id]. If I change return type to JsonResult it does get value from request, but then, obviously I can't return view or use redirecttoaction. Hope u understand the crux of this problem. I do need to return that view obviously.
    So 2 questions that arise --
    . what change in cshtml the markup
    . what change in the controller code


    Solutions. Thanks.

    Thursday, July 16, 2020 12:12 PM

Answers

  • User-215451226 posted

    I solved myself long ago. these ^^^ answers no help although I wouldn't say they were bad. unrelated.
    delete thread

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, July 22, 2020 3:33 PM

All replies

  • User475983607 posted

    The querystring parameter name, id, does not match the action input parameter name, p_id.

    https://localhost:44383/api/Product/ProductDetail?p_id=7
    [Route("ProductDetail")]
    [HttpGet]
    public IActionResult ProductDetail(int p_id)
    {

    The markup will cause the JSON result to be displayed in the browser which seems incorrect.

    <a href="api/Product/ProductDetail?p_id=@product.Id">

    I recommend going through the Getting Started tutorials on this site.  The tutorials cover fundamental Web API programming patterns that are very helpful.  I think you'll also be interested in reading about routing in Web API.  Lastly, 2.2 is no longer supported.  Either drop back to 2.1 or move forward to 3.1. 

    Thursday, July 16, 2020 12:25 PM
  • User711641945 posted

    Hi PGChoudhury,

    Trouble is no value gets passed to [int id]. If I change return type to JsonResult it does get value from request

    How did you get that?It is not related to the return type.The reason why you do not get the id is because your name is different.Model binding system could not identify it.

    You just need to follow what mgebhard said,change the parameter name in your razor view.Also,change the name in the action is also acceptable:

    Controller:

    public IActionResult ProductDetail(int id)
    {
    }

    View:

    <a href="api/Product/ProductDetail?id=@product.Id">XXX</a>

    Be sure the @product.Id is actually have value.

    Best Regards,

    Rena

    Friday, July 17, 2020 7:02 AM
  • User-215451226 posted

    @mgebhard    Am reading ur reply. As far as my created project is concerned, version numbers can't be changed.
    Getting started tutorials are not needed and irrelevant in this regard. Not needed. I am looking at the one related to routing.

    Regarding returning the necessary view with bound entity, can you write exactly what is to be done?? I hope you have actually read my controller code. forget ambiguity between p_id and id.

    Friday, July 17, 2020 2:48 PM
  • User-215451226 posted

    @Rena Ni -- I figured that out long ago. nothing more than a typo.

    What solution do you have for the more important portion - returning the view with my result from Iactionresult. For which the error is -->

    An unhandled exception occurred while processing the request. InvalidOperationException

     

    ProductDetail view is there in my project.

    Friday, July 17, 2020 2:53 PM
  • User475983607 posted

    The problem is your code is so poorly written that I have no idea what you are trying to do.  That's why I recommended the Getting Started tutorials.   Simply Web API does not return a View or redirect.  While your controller inherits from Controller which is an MVC construct the route is similar to an api URL.  The intention is not clear IMHO. 

    Are you trying to make an AJAX call to Web API?  Are you trying to make an HTTP Request form C# code to Web API?  Are you trying to build an MVC application and really need a basic MVC controller?  How does you application work?

    Friday, July 17, 2020 3:05 PM
  • User-215451226 posted

    The problem is your code is so poorly written that I have no idea what you are trying to do.  That's why I recommended the Getting Started tutorials.   Simply Web API does not return a View or redirect.  This type of information is covered in any beginning level tutorial.

    What api? What does it matter? I have no idea either where are you taking my problem.
    I'll wait for someone else to write a proper relevant answer to the specific question posted here.

    Friday, July 17, 2020 3:17 PM
  • User475983607 posted

    PGChoudhury

    What api? What does it matter? I have no idea either where are you taking my problem.
    I'll wait for someone else to write a proper relevant answer to the specific question posted here.

    It matters because you specifically configured the route similar to an api route but the ProductController inherits  from an MVC controller.

    [Route("api/[controller]")]
    public class ProductController : Controller
    {

    The MVC controller pattern.

    public class ProductController : Controller
    {
        protected ProductDataService pService {get;set;}
    
        public ProductController(ProductDataService _pS)
        {
            pService = _pS;
        }
    
       [HttpGet]
        public IActionResult ProductDetail(int id)
        {
            if(id>0)
            {
                var pEntity = pService.GetProductById(id);
                if(pEntity!=null)
                {
                    ViewData["ProductId"] = pEntity.Id;
                    return View("ProductDetail", pEntity);
                }
                else
                {
                    return RedirectToAction("Index");
                }
            }
            else
            {
                return RedirectToAction("Index");
            }
        }
    }

    A working example.

        public class Product
        {
            public int Id { get; set; }
        }
    using Microsoft.AspNetCore.Mvc;
    using MvcApi21.Models;
    
    namespace MvcApi21.Controllers
    {
        public class ProductController : Controller
        {
            public IActionResult Index()
            {
                Product p = new Product() { Id = 1 };
                return View(p);
            }
    
            [HttpGet]
            public IActionResult ProductDetail(int id)
            {
                return Content("ProductDetail");
            }
        }
    }
    @model Product
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <div>
        <a asp-action="ProductDetail" asp-route-id="@Model.Id">Detials</a>
    </div>
    <div>
        <a href="/Product/ProductDetail/1">Details</a>
    </div>

    I really think going through the Getting Started tutorials will help you a lot as the tutorials cover this, as well as many, fundamental programming patterns in MVC.

    Friday, July 17, 2020 3:44 PM
  • User-474980206 posted

    the fact that you don't know the difference between a view controller and a webapi controller, means you have no basic understanding of MVC. You are just cutting / pasting code hoping its works. as we can not explain anything to you (as it require more background knowledge than you have), we can just give you working code. please give full requirements of what you are trying to do in detail.  

    also you will also need to explain your project structure as it seems to be non-standard.

    Friday, July 17, 2020 3:50 PM
  • User-215451226 posted

    that's totally irrelevant. completely. Absolutely no use to my specific question.

    I have every previous reply posted by the 2 handles saved with me here, including the multiple time edits. And I am amused it offers so much worth in the relevant knowledge copying my posted code only and showing it to me too.

    epic !
    Friday, July 17, 2020 4:16 PM
  • User475983607 posted


    that's totally irrelevant. completely. Absolutely no use to my specific question.

    I have every previous reply posted by the 2 handles saved with me here, including the multiple time edits. And I am amused it offers so much worth in the relevant knowledge copying my posted code only and showing it to me too.

    epic !

    I don't understand your response.  What's not relevant? 

    So 2 questions that arise --
    . what change in cshtml the markup
    . what change in the controller code

    Your original code is confusing which makes it difficult to understand the intention.  We cut through the nonsensical "api" routes and focused on the HTTP GET.  The ProductDetails action defines a p_id argument that does not match the link which has an id parameter.  The first step is using the same name.  I provided two examples through out this thread.  One with p_id and one using id.  The latter assume you are using the default route configuration.

    If you fixed the code and the id is being passed to ProductDetails but you are receiving the error.  An unhandled exception occurred while processing the request. InvalidOperationException.  Then you have other issues with our design, most likely the service, which we cannot see.

    Please run your code through the debugger.  If you need community assistance then share your most recent source code and all the relevant code.  

    Saturday, July 18, 2020 12:09 PM
  • User-215451226 posted

    So main question topic of concern remains. Unsolved as per this thread.
    How do you return or redirect to necessary view that is bound to the relevant model from within the IActionResult. there's no doc or resource that demonstrates

    @Rena Ni -- I figured that out long ago. nothing more than a typo.

    What solution do you have for the more important portion - returning the view with my result from Iactionresult. For which the error is -->

    An unhandled exception occurred while processing the request. InvalidOperationException

    ProductDetail view is there in my project.

    Saturday, July 18, 2020 3:59 PM
  • User-474980206 posted

    redirects return a url the the browser does a get on. There is no model data, you can pass url parameters. see docs how to pass data

       https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.redirecttoaction?view=aspnetcore-3.1

    note: redirects make no sense from an api controller.

    Again this is all covered in a beginners tutorial

    Saturday, July 18, 2020 6:30 PM
  • User475983607 posted

    How do you return or redirect to necessary view that is bound to the relevant model from within the IActionResult. there's no doc or resource that demonstrates
     

    An action returns a View.  The default convention is the action name matches the view name and the view is within a folder that matches the controller name.   The View overload allows you to pass a model to the View.

    public class ProductController : Controller
    {
        public IActionResult Index()
        {
            Product p = new Product() { Id = 1 };
            return View(p);
        }
    }

    The Product/Index View is strongly typed.  That means the @model type in the View matches the the type passed in View(p);

    @model Product
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <div>
        <a asp-action="ProductDetail" asp-route-id="@Model.Id">Detials</a>
    </div>
    <div>
        <a href="/Product/ProductDetail/1">Details</a>
    </div>

    The View over load also allow you to define the View and location.  It is up to to know the path and View name in this situation.  The follow example fetches the same View as the previous example.  

    public IActionResult Index()
    {
        Product p = new Product() { Id = 1 };
        return View("~/Views/Product/Index.cshtml", p);
    }

    Lastly, there is no such thing as redirecting to a view.  The browser is redirected (status 302) to an controller/action.  That action returns a view.  Whether or not a model is passed to the View depends how you designed the action.

    Basic example.

    public class ProductController : Controller
    {
        [HttpGet]
        public IActionResult Index()
        {
            Product p = new Product() { Id = 1 };
            return View(p);
        }
    
        [HttpGet]
        public IActionResult Error(string message)
        {
            ViewBag.Message = message ?? "Oops no error but somehting bad happened";
            return View();
        }
    
        [HttpGet]
        public IActionResult ProductDetail(int? id)
        {
            if (id.HasValue)
            {
                Product p = new Product() { Id = id.Value };
                return View(p);
            }
    
            return RedirectToAction("Error", new { message = "Huston we have a problem!" });
        }
    }

    Index View

    @model Product
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <div>
        <a asp-action="ProductDetail" asp-route-id="@Model.Id">Detials</a>
    </div>
    <div>
        <a asp-action="ProductDetail">Cause an error</a>
    </div>

    ProductDetial View

    @model Product
    @{
        ViewData["Title"] = "ProductDetail";
    }
    
    <h1>ProductDetail</h1>
    
    <div>
        The ID is @Model.Id
    </div>
    <div>
        <a asp-action="Index">Back to Product</a>
    </div>

    Error View

    @{
        ViewData["Title"] = "Error";
    }
    
    <div>
        <h1>@ViewBag.Message</h1>
    </div>
    <div>
        <a asp-action="Index">Back to Product</a>
    </div>

    Saturday, July 18, 2020 8:43 PM
  • User-215451226 posted

    I solved myself long ago. these ^^^ answers no help although I wouldn't say they were bad. unrelated.
    delete thread

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, July 22, 2020 3:33 PM