Can not Call PartialView with Parameter in Mvc [duplicate] - c#

This question already has answers here:
In MVC how can I use the controller to render a partial view only for approved users?
(3 answers)
Closed 4 years ago.
I'm Trying to call Partial View Into view i want to call parameterized method which is returing the partial view so how to call it.
My code is below.
View
#{Html.RenderPartial("~/Views/Appoinment/GetALLAppoinmentMedicine.cshtml",
new List<HMS.Models.AppointmentViewModel> { new HMS.Models.AppointmentViewModel() },
new ViewDataDictionary { { "aid", Model.AppoinmentIDP} });}
Controller
public ActionResult GetALLAppoinmentMedicine(int aid)
{
var idParam = new SqlParameter
{
ParameterName = "APPIDP",
Value = aid
};
var SpResult = DB.Database.SqlQuery<AppointmentViewModel>("exec uspAppoinmentMedicine_GetAll #APPIDP", idParam).ToList<AppointmentViewModel>();
IEnumerable<AppointmentViewModel> Result = SpResult.Select(s => new AppointmentViewModel
{
MadicineName = s.MadicineName,
PotencyName = s.PotencyName,
SizeofPills = s.SizeofPills,
Dose = s.Dose,
DoseType = s.DoseType,
Repitation = s.Repitation,
Quantity = s.Quantity,
Duration = s.Duration
});
return View(Result);
}

Try to use #{ Html.RenderAction("ChildAction","Home", new {param="abc"}):
It invokes the specified child action method and renders the result inline in the parent view.
Hope this will work.

You can pass parameter or model as per your need..
dont forget to put the reference to the model in partial view
eg.#Html.Partial("_SomePartial", Model)

The return type of Html.RenderAction is void that means it directly render the responses in View where return type of Html.Action is MvcHtmlString you can catch its render view in the controller and modified it also by using following method
#{Html.RenderAction("GetALLAppoinmentMedicine", "ControllerName",new {uid= 1})}
If you want to use Ajax.ActionLink, replace your Html.ActionLink with:
#Ajax.ActionLink(
"Partial",
"GetALLAppoinmentMedicine",
"ControllerName",
new AjaxOptions { aid = 1 }
)
and of course you need to include a holder in your page where the partial will be displayed:
<div id="myresult"></div>
Also don't forget to include:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"
type="text/javascript"></script>
in your main view in order to enable Ajax.* helpers. And make sure that unobtrusive javascript is enabled in your web.config (it should be by default):

Related

ViewDataDictionary vs anonymous object in ASP.net MVC 5

I am a beginner and I am going through some tutorials in my MVC. So, I came across two scenarios.
Scenario 1.
I had to pass some data to my view on post and then send that data as hidden field. Here is the code.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ForgotPassword(ForgotPasswordMV viewModel)
{
if (ModelState.IsValid)
{
return RedirectToAction("VerifyToken", new { emailId = viewModel.EmailId });
}
^^ USING ANONYMOUS OBJECTS
return View();
}
public ActionResult VerifyToken(string emailId = null)
{
VerifyTokenMV viewModel = new VerifyTokenMV
{
EmailId = emailId
};
return View(viewModel);
}
VerifyToken View
#using (#Html.BeginForm("VerifyToken", "Security"))
{
#Html.HiddenFor(m => m.EmailId)
<button class="btn btn-primary">Continue</button>
}
Works Perfectly fine. I am able to receive values of EmailId. So far so good.
Scenario 2.
Needed to open a partial view from Main view, here is the snippet.
Main cshtml file
<div class="abc">
#Html.Partial("../Widget/Customize", Model.Unit, new ViewDataDictionary() { { "ElementName", "UnitWidget" } })
</div>
partial cshtml file
#{
string custWidgetElementName = ViewBag.ElementName;
}
// some html code below
Observation:
In scenario 2 why have I used ViewDataDictionary. Although both example works perfectly fine. But is there any reason that I had to use ViewDataDictionary. In scenraio 1 can we use ViewDataDictionary? If Yes, then which one is optimum solution.
Question: When I need to pass values shall I use new {key : value} or use ViewDataDictionary or there is no corelation? Instead of ViewDataDictionary can I use anonymous object in Senario 2
Your two scenarios are totally different. They are not doing the same thing.
In scenario 1 when using this line:
return RedirectToAction("VerifyToken", new { emailId = viewModel.EmailId });
A new URL is genrated and sent back to the client (the browser) with HTTP Code 301 or 302. When received the browser will re-contact your application wiht the received URL. With that URL, your application will execute the associated action. In your case, the client's browser will call VerifyToken action with the emailId parameter setted when you call RedirectionToAction into ForgotPassword action. So using RedirectionToAction method is just telling that method to generate a new URL with parameter defined in the anonymous type.
In scenario 2 is completely different to scenario 1. With this line:
#Html.Partial("../Widget/Customize", Model.Unit, new ViewDataDictionary() { { "ElementName", "UnitWidget" } })
You're telling your view to inject the partial view which path is ../Widget/Customize. Because that partial view the strongly typed, you passed Model.Unit as an second parameter. You use also a third parameter new ViewDataDictionary() { { "ElementName", "UnitWidget" } } because your partial seems to internally need to access to the dynamic property ViewBag or dictionary property ViewData of your view.
Conclusion:
In scenario 1 you are just telling the client's browser to go to the new URL you have generated after requesting ForgetPassword URL. We just call that a rediretion.
In scenario 2, you're just rendering a partial view into a view. The client's broswer doesn't know anything what's going on with partial views they don't know if they exist.

How do you use the Html.BeginFrom method when passing attributes to your controller?

First of all, I'm fairly certain that this is already answered, and I'm sorry that it's most likely a re-post, but I can't find the answer right now. Zzz.
Here is my razor code (stripped of non-essentials):
#model SurveyApp.Models.LoginModel
#{
var x = ViewBag.Culture; //x gets populated with "en-CA"
}
#using (Html.BeginForm("Login", "Account", FormMethod.Post, new { culture = x, id = "login-form" }))
{
//...
Submit
}
I'm pretty sure that this is all of the relevant code, because in my [httppost]login method, I am getting null in the second parameter.
Here is the login prototype (or whatever you call it):
public ActionResult Login(LoginModel model, string culture)
{
//...
}
Am I using the attribute parameter of the Html.BeginForm call improperly?
You should put those as hidden form fields. The attributes on a form tag don't get submitted unless its the URL.

Redirect to MVC ActionResult with Parameters when DropDownList option is changed

I am using MVC to create part of a website. In one of my Views I have a DropDownList. When a new drop down list option is selected, or in other words onchange, I want my page to be redirected to a specific Controller ActionResult. I am able to get to MyAction ActionResult if there are no parameters, however I can't figure out how to send in the needed parameters.
My Controller Action:
public virtual ActionResult MyAction(int param1, int param2)
{
return View();
}
My DropDownList in View:
#Html.DropDownList(
"viewDataItem", Model.MyEnumerableList as SelectList,
new { onchange = #"
var form = document.forms[0];
form.action='MyAction';
form.submit();"
} )
The above code calls MyAction, however it does not send in the parameters. Is there a way to somehow add the parameters to this code?
Another thought was to somehow use #{Response.Redirect(#Url.Action("MyAction", "myController", new { param1 = 2, param2= 3 }));} as my DropDownList action since Response.Redirect allows me to redirect to MyAction with parameters. Is there a way to somehow make onchanged = Response.Redirect?
The tried making onchange equal the response, but the nothing happens when I change my option:
#Html.DropDownList(
"name", Model.MyEnumerableList as SelectList,
new
{
onchange = {Response.Redirect(#Url.Action("MyAction", "controllerName", new { param1 = 5, param2 = 3 }));}
})
In short, how do I call an ActionResult with parameters whenever my DropDownList option is changed?
Similar questions were asked here and here, but the answers provide in those links all use JavaScript and I don't know how to use JS with cshtml. I tried some of those answers, but none of them solved my problems.
You can specify on the onchange event a javascript function and inside that function:
var url = '#Html.Raw(Url.Action("MyAction", "controllerName", new { param1=5, param2=2 }))';
and then:
window.location = url;
Finally the code should be:
#Html.DropDownList(
"viewDataItem", Model.MyEnumerableList as SelectList,
new { onchange = "SelectionChanged()"
} )
<script>
function SelectionChanged()
{
var url = '#Html.Raw(Url.Action("MyAction", "controllerName", new { param1=5, param2=2 }))';
window.location = url;
}
</script>
Is there a way to somehow add the parameters to this code?
Sure, there are many ways. One of them would be:
#Html.DropDownList(
"viewDataItem", Model.MyEnumerableList as SelectList,
new { onchange = #"
var form = document.forms[0];
form.action='MyAction?param1=5&param2=3';
form.submit(); /*Just make sure that form 'method' attribute is set to 'post'*/"
} )
But a much better way is described in the answer you mentioned.
Is there a way to somehow make onchanged = Response.Redirect?
Not the way you're trying to use it. onchanged is a javascript event, and javascript knows nothing about Response property or other MVC server-side stuff.

Receiving an error while passing an argument from a view to a method from controller

So, these are the 2 pieces of code that are causing the error.
The View:
...
#foreach (FinalCampaign fc in #Model)
{
<h1>#fc.Camp.Id</h1>
<h2>#Html.ActionLink(#fc.Camp.Name, "GoToPage", "Home", fc.Camp.Id, null)</h2>
<p>#fc.Camp.CampaignStartDate - <font color="Blue"><u>#fc.Username</u></font></p>
<p>#fc.Camp.Description</p>
}
And here is the "GotoPage" function from my controller:
public ActionResult GoToPage(string id)
{
CampaignCommentsModel ff = new CampaignCommentsModel();
var cT = new CampaignTable(new OracleDatabase("DefaultConnection"));
Campaign camp = cT.GetCampaignById(id);
...
return View(ff);
}
And this is my problem: the "id" from GotoPage (the argument) is null, it doesn't receive the value from my view.
You should use:
<h2>#Html.ActionLink(#fc.Camp.Name, "GoToPage", "Home", new { id = fc.Camp.Id}, null)</h2>
You can not pass a nested properties in this way. The default model binder can not associate such an object with a parameter in your action method.
ActionLink extension: https://msdn.microsoft.com/en-us/library/dd492124(v=vs.118).aspx
Model binding: What is model binding in ASP.NET MVC?
<h2>#Html.ActionLink(#fc.Camp.Name, "GoToPage", "Home",new {id = fc.Camp.Id}, null)</h2>
See here Actionlink method

How to replace div's content by partial view or update it's content depending on what json result returns on ajax complete?

Well I have simple ajax form:
This is MyPartialView
#using(Ajax.BeginForm("action", "controller", new AjaxOptions
{
OnBegin = "beginRequest",
OnComplete = "completeRequest",
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "div-to-replace"
}, }))
{
<input type="text" id="my-input" />
...
}
This is parent view:
<div id="div-to-replace">
#Html.RenderPartial("MyPartialView")
</div>
In my controller I have:
[HttpPost]
public ActionResult action(Model model)
{
if (ModelState.IsValid)
{
// do staff with model
// return partial view
return PartialView("MyPartialView");
}
// else add error and return json result
return Json(new {error = "invalid data"});
}
And my javascript on ajax complete method:
function completeRequest(data) {
var result = $.parseJSON(data.responseText);
if (result != 'undefined' && result != null && result.error) {
// just display error and not replace all content
// attachModelError is my custom method, it just adds vlaidation-error class to inputs, etc.
attachModelError("my-input", result.error);
return;
}
// or show returned html (depending on returned model form inputs will be modified:
// select box with different items in my case
$('#div-to-replace').html(data.responseText);
}
But the problem is I have empty #div-to-replace if model state is invalid. If model state is ok every thing works fine. If I use different insertion mode it creates duplicates of div's content before or after div.
Summary:
I want different InsertionMode behavior depending on json result. I don't need replace data if (result != 'undefined' && result != null && result.error).
I had to solve this problem once so very long ago. I came up with a simple solution, which today, may not be the best solution but it gets the job done.
My solution involved setting up a controller action that would render just the partial with data that it would need and have my JavaScript request it.
C#
MyController: Controller
{
public ActionResult GetPartialViewAction()
{
return PartialView("mypartialview", new partialViewModel());
}
}
JavaScript
$.ajax({
url: "/my/getpartialaction/"
}).done(function(data) {
$("#partialViewDiv").html(data);
});
HTML
<div id="partialViewDiv"></div>
A better solution would be to use a MVVM/MVC JavaScript library that would allow you to leverage html templates and only have to transmit the data over your ajax solution. I recommend looking into knockout.js or backbone.js for this more accepted pattern.
I have the same problem with the default c# ajax forms. I have a solution what might work.
jQuery:
$(function () {
var ajaxFormSubmit = function () {
var $form = $(this);
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: $form.serialize(),
cache: false
}
$.ajax(options).done(function (data) {
data.replaces.each(function (replace) {
$(replace.id).replaceWith(replace.html);
});
});
return false;
};
$("form[data-ajax='true']").submit(ajaxFormSubmit);});
form.cshtml
#using (Html.BeginForm("Create", "Menu", FormMethod.Post, new { data_ajax = "true" }))
{}
model sample
public string Id {get;set;}
public string Html {get;set;}
The last thing you need to do in your controller is return a json result with a list of your model sample, id is target element to update, for the html you must use a render partial / or view as string.
For render view to partial see [question]: https://stackoverflow.com/questions/434453

Categories