I have a view in one of my controller which have list of items. When user clicks each item, browser must navigate to page which brings details about this item.
Controller for Details
accepts values through post method and have complex input object as its input.
Here is sample method for to navigate to details page using GET
method to send values:
function openDetailsPage(commodityID, commodityName) {
dateFrom = convertNumbers2English('@(((FilterViewModel)ViewBag.ViewModel).dateValue_1)');
dateTo = convertNumbers2English('@(((FilterViewModel)ViewBag.ViewModel).dateValue_2)');
dateFrom = changeDateSeparator(dateFrom);
dateTo = changeDateSeparator(dateTo);
if (dateTo == null || dateTo == undefined)
dateTo = "0";
if (dateFrom == null || dateFrom == undefined)
dateFrom = "0";
@{
string reportTypes = "0";
if (((FilterViewModel)ViewBag.ViewModel).purchaseReportTypes != null)
{
reportTypes = String.Join(",", ((FilterViewModel)ViewBag.ViewModel).purchaseReportTypes);
}
}
alert('@reportTypes');
var url = '@Url.Action("ReportDetailed","BuyReport",new {
commodityType =(((FilterViewModel)ViewBag.ViewModel).commodityType),
commodityName="dummyCommodityName",
department=((FilterViewModel)ViewBag.ViewModel).department,
repository=((FilterViewModel)ViewBag.ViewModel).repository,
commodity ="dummyCommodityID",
purchaseReportTypes=reportTypes,
dateValue_1="dummyDate1",
dateValue_2="dummyDate2"
})';
alert(url);
@*var url = '@Url.Action("ReportDetailed","BuyReport",
new RouteValueDictionary
{
{"commodityType",((FilterViewModel)ViewBag.ViewModel).commodityType},
{"commodityName","dummyCommodityName" },
{"department",((FilterViewModel)ViewBag.ViewModel).department },
{"repository",((FilterViewModel)ViewBag.ViewModel).repository },
{"commodity","dummyCommodityID"},
{"purchaseReportTypes",((FilterViewModel)ViewBag.ViewModel).purchaseReportTypes },
{"dateValue_1",((FilterViewModel)ViewBag.ViewModel).dateValue_1 },
{ "dateValue_2",((FilterViewModel)ViewBag.ViewModel).dateValue_2 }
})';*@
url = url.replace("dummyCommodityID", commodityID);
url = url.replace("dummyCommodityName", commodityName);
url = url.replace("dummyDate1", dateFrom);
url = url.replace("dummyDate2", dateTo);
alert(url);
openLink(url);
}
I have some difficulties with this type of routing for values:
- Input object is complex so route would be so complex. E.g.
/BuyReport/ReportDetailed?commodityType=0&commodityName=dummyCommodityName&department=1&repository=2&commodity=dummyCommodityID&dateValue_1=dummyDate1&dateValue_2=dummyDate2
or/BuyReport/ReportDetailed/0/itemName/1/2/1/123/
- Any special characters in get parameters such as
/
will break routing - I cannot pass stuff like arrays so I should convert them before sending
So I'm looking for a method to send parameters using 'Post' method like what form submit button does with below constraints:
- I have no forms in my view
- I want to post values to controller and page must navigate to details view
- Each item in first page, have different row and different ID so I think creating a form for each row is not reasonable.
I want to know are there any ways to implement Post
parameters according to my requirements? I would not care if it would be a mixture of C#, JS and jQuery.
More Details:
Here is a sample row in my list page which calls openDetailsPage
js function:
<a onclick="openDetailsPage(@item.CommodityId,'@Html.DisplayFor(modelItem => item.CommodityName)')">
<div class="ios-content-box px-4 py-1 mb-3 ios-hover-box">
<div class="row font-12 my-2 ios-divider-line">
<div class="col-6 f-w-600 color-orange text-right">@Html.DisplayFor(modelItem => item.CommodityName)</div>
<div class="col-6 text-left"> <i class="fas fa-chevron-left fa-fw color-orange "></i></div>
</div>
<div class="row font-12 my-2 ios-divider-line">
<div class="col-6 text-gray-600 text-right">type</div>
<div class="col-6 text-gray-600 text-left">@Html.DisplayFor(modelItem => item.TypesName)</div>
</div>
<div class="row font-12 my-2 ios-divider-line">
<div class="col-6 text-gray-600 text-right">Code</div>
<div class="col-6 text-gray-600 text-left">@Html.DisplayFor(modelItem => item.CommodityCode)</div>
</div>
<div class="row font-12 my-2 ios-divider-line">
<div class="col-6 text-gray-600 text-right">Barcode</div>
<div class="col-6 text-gray-600 text-left">@Html.DisplayFor(modelItem => item.CommodityBarcode)</div>
</div>
<div class="row font-12 my-2 ios-divider-line">
<div class="col-6 text-gray-600 text-right">Unit Price</div>
<div class="col-6 text-gray-600 text-left">@Html.DisplayFor(modelItem => item.UnitPrice)</div>
</div>
<div class="row font-12 my-2 ios-divider-line">
<div class="col-6 text-gray-600 text-right">Total Price</div>
<div class="col-6 text-gray-600 text-left">@Html.DisplayFor(modelItem => item.SumPrice)</div>
</div>
</div>
</a>
Currently my controller is as below:
[Route("BuyReport/ReportDetailed/{commodityType}/{commodityName}/{department}/{repository}/{commodity}/{purchaseReportTypes}/{dateValue_1}/{dateValue_2}")]
public async Task<ActionResult> ReportDetailed(
string commodityType,
string commodityName,
string department,
string repository,
string commodity,
string purchaseReportTypes,
string dateValue_1,
string dateValue_2
)
{
}
But I want to change it to something like this:
[HttpPost]
public async Task<ActionResult> ReportDetailed(DetailedViewModel detailedviewmodel){
string commodity = detailedviewmodel.commodity;
string commoditytype = detailedviewmodel.commoditytype;
string department = detailedviewmodel.department;
string purchasereporttypes = detailedviewmodel.purchasereporttypes;
string repository = detailedviewmodel.repository;
string startdate = detailedviewmodel.datevalue_1;
string enddate = detailedviewmodel.datevalue_2;
string commdoityname = detailedviewmodel.commodityname;
}
Where DetailedViewModel
is defined as below:
public class DetailedViewModel
{
public string commodityType { get; set; }
public string commodityName { get; set; }
public string department { get; set; }
public string repository { get; set; }
public string commodity { get; set; }
public string[] purchaseReportTypes { get; set; }
public string dateValue_1 { get; set; }//start date
public string dateValue_2 { get; set; }//end date
}