First i would like to apologize if this is a stupid question.
While learning MVC i came a cross creating a strong type views based on model which for example will display all Users by 2 different functions, first will return a View passing a collection of users second will return a collection of JSON objects. so my question is, as i'm not familiar with JSON and for me using Models are more clear, why then using JSON in MVC?
In short why using:
var users = _db.Users
.Where(r => r.Name.Contains(q))
.Take(10)
.Select(r => new { r.Name,r.LastName,r.Address.Country });
return Json(users, JsonRequestBehavior.AllowGet);
In place of:
var users= _db.Users
.Where(r => r.Name.Contains(q))
.Take(10);
return View(users);
Maybe this is a bad code example, but why converting Models to Jason before passing them to a view, if we can directly pass the models.
For the first code snippet, it is more likely that it is used for a ajax call to seamlessly load the data from the server to the client and perhaps keep refreshing it without reloading the page. Also, the Users entity may have much more information than needed by the client, so the first example is reducing the information served and doesn't require you to create a new model to represent it.
The second example would be a controller action actually returning a view and that view is strongly typed.
If you would make a project that uses the WebApi, you wouldn't return views, you would expect the client to ask for data and that the client renders it how it sees fit.
If you want the call to return HTML that can be rendered in a browser, you would return a View, which basically takes the data and applies it to an HTML template.
If you want the call to return data only (most likely to be processed by an AJAX request), then you would return JSON.
The first is going to return JSON with a content type of application/json while the latter will return html with the content type text/html (after the appropriate View Rendering Engine has rendered the view in question) - they can be considered two different representations of the same resource. You may want to return JSON in response to a request made via AJAX and return only the data from the model that is required, but you may want to return HTML in response to a "normal" request.
out of the box, ASP.NET MVC does not support Content Negotiation, that is, make a request with the Accept header set to a particular MIME type will likely not yield a response with the expected content type - controller actions will in the majority of cases be configured to return a resource in one particular content type (usually html). ASP.NET Web Api on the other hand does support Content Negotiation out of the box.
JSON (= data only) is generally used in asynchronous (AJAX) requests as they can easily be processed by Javascript, while Views are styled HTML responses ready to be displayed by the browser.
Client side libraries understand JSON very well, so if you want to parse the result and manipulate them using a client side framework/custom scripts, then JSON is a better option (AngularJs is one example).
In Addition to your question, when using JSON, first you convert Model to JSON but when you users post a request you might reconvert JSON to model in order to persist result to DB. :-)
I
Related
I have tried to follow this post in order to create a 3 page form wizard that passes data to each page.
He uses the HTML helper serialize, to serialize an object in the view.
#Html.Serialize("wizard", Model)
However this HTML helper isn't available in MVC 5 it seems.
I found another related post to this here where he suggests using the following to serialize the object.
#Html.Hidden("otherComplexData", new Microsoft.Web.Mvc.MvcSerializer().Serialize(complexObject))
But I then get the following error
There is no argument given that corresponds to the required formal parameter 'mode' of 'MvcSerializer.Serialize(object, SerializationMode)'
It seems to want a SerializationMode, however the documented one doesn't. https://msdn.microsoft.com/en-us/library/microsoft.web.mvc.mvcserializer.serialize(v=vs.118).aspx
What direction can I go in now?
Thanks.
Here's the Serialization option you need:
https://github.com/ASP-NET-MVC/ASP.NET-Mvc-3/blob/master/mvc3/src/MvcFutures/Mvc/SerializationMode.cs
Options are Signed or EncryptedAndSigned.
You can try that and see if it will work.
There's multiple ways to encode data that will work for you. You could put the values in a hidden input using Json.Encode for the view, and Json.Decode on the server side.
I have list of data in my api controller.
I want to pass this data to view using something similar to viewbag.
I know we cant use viewbag in apicontrller , So Is there any alternative for it.
Normally ApiControllers do not return views. They return models, or HttpResponseMessage for that matter. So you could simply have a view model that will contain the required property and then have your API action return this view model.
You are not supposed to tho that, the API controllers return only data (XML, Json, etc). So you should have two controllers:
System.Web.Http.ApiControlle Use this to return collections of data for example:
public List<Company> Get()
{
return this._companyService.GetCompanies();
}
Returns a list of companies in Json or XML not a view.
System.Web.Mvc.Controller use this one for returning HTML without data for example an HTML table without rows or client-side templates.
How to link the two? The idea is to render in the client-side with JavaScript, there is a good few reasons to do it this way, the main ones are that you have data and presentation in two completely separated feeds so you will be able to re-use your data feed (in mobile apps for example).
To render in the client-side is good idea to use some JavaScript rendering engine, take a look to http://handlebarsjs.com/.
Use Jquery.getJSON() to get your JSON and get your handlebars template from your DOM or via Ajax, select a DOM alement to insert the generated HTML. Once you have the JSON, template and container use the function below:
function RenderJson (json,template,container) {
var compiledTemplate = Handlebars.compile(template);
var html = compiledTemplate(json);
$(container).html(html); //set new content
}
I know it can seem like a more complicated process but it you try it you will see the advantages, you will be able for example to test your data feed and your data presentation separately.
Hope it helps :)
My goal is to have the user be able to download some information currently stored in Session. There are multiple key/value pairs in Session I would like to have the user download as one XML file.
The control I am working with has a client-side 'onClick' event exposed. I was planning on calling a PageMethod to extract the data I wanted from Session, and return that data to the client.
I've seen a very clean implementation of this in MVC and I am wondering if this clean implementation is possible in ASP.NET AJAX, as well. If not, I am wondering what the best route would be to go for this.
In MVC/JavaScript I see something like this:
location.href = "../WorkOrders/Export/" + workOrderID;
public ActionResult Export(int id)
{
WorkOrderPdfExporter exporter = new WorkOrderPdfExporter();
byte[] buffer = exporter.Export(id);
return File(buffer, "application/pdf", String.Format("workorder#{0}.pdf", id));
}
This Export method returns a FileContentResult which is an MVC thing. I am wondering if something like this exists in ASP.NET AJAX, and if the datatype is suitable to return for a Page Method.
If not, what should I be doing here? I was thinking about creating a dictionary, sticking the relevant session objects into this dictionary, serializing it to XML (I have a Serializable Dictionary class implemented), ...and then attempting to return that XML for download?
Thanks for your time.
You can write directly to HttpResponse.OutputStream - you will need to set the correct ContentType too.
The code example for OutputStream is rather verbose (mostly dealing with a dynamically created image), but if you ignore those parts, you will have a basic function that will need minor modification for your use.
i am calling a web service by aspx page and wants my return output as a json format with a specific view like (grid view) in asp.net...so here is any view available in JSON which display my output like grid view..pls give me suggetion as soon as possible....thax
salman ansari
As far as I know, WebServices are based on XML SOAP objects, I anot sure if these can be handled like Json objects or converted. You could create a page (or view in MVC), that returns json objects specifically.
Recently I started working with MVC, before that I used "classic" ASP.NET.
After using Ruby on Rails (RoR), I wonder how to implement POST request handling in MVC similar to how RoR operates. In RoR you use the Post method, so you need only one function for a view.
In ASP.NET MVC I need to use 2 separate functions for GET and for POST, so I need to initialize the same data twice, and I don't like to repeat something in my code.
How can I check if the request is POST in one method?
Update:
Solution is found: I have to use Request.HttpMethod.
Thank you!
I came across this question wanting to know the same thing. Below is a detailed description of my situation and the solution that I used (which utilizes the other answers provided here). I originally tried to use the two separate method approach, but I ran into a problem when the method signatures of these methods became identical.
I have a page that displays report data. At the top of the page there is a form with some fields, which allow the user to specify report parameters such as start date, end date, etc.
I originally approached this by creating two separate methods to handle the Get and the Post methods. The post method would redirect the browser to the get method so that any parameters that were specified would be added to the query string and so that the browser would not prompt the user with a dialog saying that it is going to resend the data that they entered if they refresh. Note: I realized later that I could accomplish this by setting the method attribute of my form element to "Get", but I think ideally a controller shouldn't have knowledge of how a view is implemented, so in my opinion that is irrelevant.
As I developed these two methods I eventually found myself in a situation where the method signatures became identical. Furthermore, my code for these two methods became nearly identical, so I decided to merge them into a single method and to just check the request verb so that I could do something slightly different when the request is not a "Get". A distilled example of my two methods is shown below:
// this will not compile because the method signatures are the same
public ActionResult MyReport(DateRangeReportItem report)
{
// if there are no validation errors and the required report parameters are completed
if (ModelState.IsValid && report.ParametersAreComplete)
{
// retrieve report data and populate it on the report model
report.Result = GetReportData(report.CreateReportParameters());
}
return View(report);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyReport(DateRangeReportItem report)
{
if (ModelState.IsValid && report.ParametersAreComplete)
{
// redirect to the same action so that if the user refreshes the browser it will submit a get request instead of a post request
// this avoids the browser prompting the user with a dialog saying that their data will be resubmitted
return RedirectToAction("MyReport", new { StartDate = report.StartDate, EndDate = report.EndDate });
}
else
{
// there were validation errors, or the report parameters are not yet complete
return View(report);
}
}
Why am I accepting a model object as the parameter to my get method? The reason is that I wanted to take advantage of the validation logic already built into the model object. If someone navigates to my page directly with all parameters already specified in the query string, then I want to go ahead and retrieve the report data and display it on the page. However, if the parameters specified in the query string are invalid then I also want validation errors to appear on the page. By putting my model object as the parameter, the MVC framework will automatically attempt to populate it and will capture any validation errors without any additional work on my part.
I used the other answers posted for this question to create a RequestHttpVerb property on a base controller class in my project:
public HttpVerbs RequestHttpVerb
{
get { return (HttpVerbs)Enum.Parse(typeof(HttpVerbs), this.Request.HttpMethod, true); }
}
So finally my consolidated method looks like the following:
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public ActionResult MyReport(DateRangeReportItem report)
{
// check if there are any validation errors in the model
// and whether all required report parameters have been completed
if (ModelState.IsValid && report.ParametersAreComplete)
{
// this is unnecessary if the form method is set to "Get"
// but within the controller I do not know for sure if that will be the case in the view
if (HttpVerbs.Get != this.RequestHttpVerb)
{
// redirect to the same action so that if the user refreshes the browser it will submit a get request instead of a post request
// this avoids the browser prompting the user with a dialog saying that their data will be resubmitted
return RedirectToAction("MyReport", new { StartDate = report.StartDate, EndDate = report.EndDate });
}
// there were no validation errors and all required report parameters are complete
// retrieve report data and populate that data on the model
report.Result = GetReportData(report.CreateReportParameters());
}
// display the view with the report object
// Any model state errors that occurred while populating the model will result in validation errors being displayed
return View(report);
}
That's my current solution to the problem. I would prefer not to have to check the Request.HttpMethod property in order to determine whether I needed to perform the redirect, but I didn't see another solution to my problem. I would have been fine with keeping two separate methods to handle Get and Post requests, but the identical method signature prevented this. I would have preferred to rename my Post action handler method to avoid the method signature conflict and to use some mechanism to indicate to the MVC framework that my renamed method should still handle the "MyReport" action, but I am not aware of any such mechanism in the MVC framework.
You only need separate methods for GET and POST if their method signatures differ, there's no reason why one action method can't handle GET and POST methods.
If you need to know whether it was a GET or POST, you could check using Request.HttpMethod in your action, but I would advise using a separate method decorated with the [AcceptVerbs(HttpVerbs.Post)] attribute as suggested by the other posters.
You don't check in ASP.NET MVC. You decorate your method with the [AcceptVerbs(HttpVerbs.Post)] attribute to indicate that the method applies to post only, and accept the model in the method used to handle the post.
I'd strongly suggest doing the walkthrough for NerdDinner to understand more about the ASP.NET MVC framework.
You may take a look at the Request.HttpMethod property.
Correct way to do is using ModelBinding during Post request.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(EmployeeViewModel model)
{
//validate data, save employee, handle validation errors...
}
This way you will not have to init your data again.