MVC repository and interface returning Json - json

I'm new at MVC and can't get this to work. I basically have a Users class, a UserRepository, and a IUser interface.
This is my code:
public class Users
{
public string UserName { get; set; }
public string Department { get; set; }
public string UserType { get; set; }
}
public class UsersRepository : TimeAttendanceMVC.Models.IUsers
{
public Users Return_UserName_Dept()
{
Users U = new Users();
List<Users> LoggedInUser = new List<Users>();
U.UserName = "TestUser";
U.Department = "Finance";
U.UserType = "Administrator";
LoggedInUser.Add(U);
//string json = JsonConvert.SerializeObject(LoggedInUser, Formatting.Indented);
//return json;
return Json(LoggedInUser.ToArray(), JsonRequestBehavior.AllowGet);
}
}
namespace TimeAttendanceMVC.Models
{
public class IUsers
{
List<Users> Return_UserName_Dept();
}
}
There are a few errors that I get. In UsersRepository.cs where i'm returning Json, the error says that "The name Json does not exist in the current context". The error from IUsers.cs is that "Return_UserName_Dept() must declare a body because it is not marked abstract...".
Can anybody please help me with this. I just don't know how this is supposed to work and i'm trying to learn MVC by working on this application. It's actually the FullCalendar application found here - link to FullCalendar. I'm trying to turn it into an MVC application.
EDIT:
Maybe I need to do this:
public JsonResult Return_UserName_Dept()
instead of public Users Return_UserName_Dept()

You should be doing this on your controller in some method which returns a json action (jsonresult). The repository should be returning your data only and all the operations you need to do, whether you're converting data to json or any other logic should happen at the controller or at some helper class which would be called by the controller..
Edit:
In order to have a method which returns a JsonResult, you need to have a reference to System.Web.Mvc.ActionResult and since the repository is usually at the model, you won't have this reference.. another thing is that you might be breaking your design the logic should be available at the controller for what you want
Edit 2:
The code below is from an old post you can see here. Note how the action PopulateDetails gets the user object from the repository and that's all the repository does.. the actual logic is happening inside this method, such as populate the rest of the UserModel class, and then it returns the JsonResult:
public JsonResult PopulateDetails(UserModel model)
{
UserResultModel userResultModel = new UserResultModel();
if (String.IsNullOrEmpty(model.UserId))
{
userResultModel.Message = "UserId can not be blank";
return Json(userResultModel);
}
User user = _userRepository.GetUser(model.UserId);
if (user == null)
{
userResultModel.Message = String.Format("No UserId found for {0}", model.UserId);
return Json(userResultModel);
}
userResultModel.LastName = user.LastName;
userResultModel.FirstName = user.FirstName;
userResultModel.Message = String.Empty; //success message is empty in this case
return Json(userResultModel);
}

Related

Display Message to User instead of empty JSON on HTML when records are empty in the database

I have an application where I have an html page which takes user input through a textbox.This is a REST Spring Framework and is divided as Controller, Entity, Service, Repository, View and the main application class.
I take an input value and search in the Mongodb database, If the value is present, I return the entity object from Service to Controller. The controller returns the same Entity View object.- PersonView in this case. I get a JSON Data.
The above scenario works well as long as there are records in the database. In case if the record is not present, it returns an empty JSON. My Controller returns Person View Object and I do not wish to change the signature and make the return type as String since in that case it returns the address on my HTML page.
Considering this, how should I handle the case when there are no records in the database and I wish to display a message on this same HTML page saying there are no records available.
I tried throwing an exception but in this case too, how Do I display message on my HTML considering that my Controller returns JSON object and I do not wish to change its signature?
Controller Class is as below:
public PersonView searchPerson(#PathVariable String pname) {
List<Person> pList= PersonService.searchPerson(pname);
PersonView personView = new PersonView();
personView.setPersonView(pList);
return personView;
EDIT:
Here is the function from personView Class that I call in Controller:
public List<Person> setPersonView() {
this.personView = personView;
}
Here is the service Impl class:
public List<Person> searchPerson(String name) throws Exception {
List<Person> personlist= new ArrayList<Person>();
personlist = personRepository.findByName(name);
if (personlist.isEmpty())
throw new Exception("Records not found in the the database");
return personlist;
}
Create a custom Exception class:
public class EntityNotFoundException extends RuntimeException {
public EntityNotFoundException(String message) {
super(message);
}
}
Now, in you controller code:
public List<Person> searchPerson(String name) {
List<Person> personlist= new ArrayList<Person>();
personlist = personRepository.findByName(name);
if (personlist.isEmpty()) {
throw new EntityNotFoundException("Records not found in the the database");
}
return personlist;
}
After that you can try something like this in you controller class:
private static final MappingJacksonJsonView JSON_VIEW = new MappingJacksonJsonView();
#ExceptionHandler(EntityNotFoundException.class)
public ModelAndView handleNotFoundException( Exception ex )
{
return new ModelAndView(JSON_VIEW, "error", new ErrorMessage("No Record in Db") );
}
Your ErrorMessage class can be a simple POJO:
public class ErrorMessage {
private String message;
ErrorMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
Although already answered, I will add some points here.
Please note that at some point of time you will have a requirement to send the
headers, Response body (with different Objects). So consider using ResponseEntity Object which will be a wrapper to your List. Here is the sample code.
public ResponseEntity<List<Person>> searchPerson(String name) {
List<Person> personlist= new ArrayList<Person>();
personlist = personRepository.findByName(name);
if (personlist.isEmpty()) {
return new ResponseEntity(new EntityNotFoundException("Records not found in the the database"), HttpStatus.BAD_REQUEST);
}
return new ResponseEntity(personlist , HttpStatus.OK);
}
Response Entity Object provides flexibility to greater extent. Read the documentation here.
https://docs.spring.io/spring/docs/current/javadocapi/org/springframework/http/ResponseEntity.html

Proper way to return JSON list in Web API with MVC and partial model

I am trying to use Web API to grab certain fields from my MVC controller. I can't seem to match the right type with the right list. I am fine with converting everything to string.
I either get an error in code (can not convert types), or if I get it to compile, I get this error:
"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'."
From other similar posts, people responded with how to create a list, but not with the declaration of the return value of the Get. Please include both.
Also I would prefer not to add additional controllers as I need to do this on a number of my models.
Here is my code--note you can see I tried a number of different ways:
public class APICLIENTsController : ApiController
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET api/<controller>
public IEnumerable<string> Get()
//public IEnumerable<CLIENT> Get()
{
//return db.CLIENTs.OrderBy(x => x.CLIENTNAME).ToList();
string[] listOfUsers = db.CLIENTs.OrderBy(x => x.CLIENTNAME).Select(r => new
{
ID = r.CLIENTID.ToString(),
NAME = r.CLIENTNAME
});
return listOfUsers.ToList();
//return db.CLIENTs.Select(x => new { x.CLIENTNAME }).ToArray();
}
If you want to return JSON use the
JsonResult
type.
public JsonResult Get()
{
//return db.CLIENTs.OrderBy(x => x.CLIENTNAME).ToList();
string[] listOfUsers = db.CLIENTs.OrderBy(x => x.CLIENTNAME).Select(r => new
{
ID = r.CLIENTID.ToString(),
NAME = r.CLIENTNAME
});
return Json(listOfUsers.ToList(), JsonRequestBehavior.AllowGet);
}
Your query is returning a collection of anonymous objects, not string[] so it will throw an exception. Even if you were to generate string[] by concatenating the CLIENTID and CLIENTNAME properties, it would be a little use to the client.
Create a model to represent what you need to return to the view
public class ClientVM
{
public int ID { get; set; }
public string Name { get; set; }
}
and modify your method to
public IEnumerable<ClientVM> Get()
{
IEnumerable<ClientVM> model = db.CLIENTs.OrderBy(x => x.CLIENTNAME).Select(r => new ClientVM
{
ID = r.CLIENTID,
Name = r.CLIENTNAME
});
return model;
}
Side note: depending on how your calling and consuming this in the client, you may need to change the Content-Type to specifically return json (refer these answers for more detail)

asp.net mvc 5 Dapper Json is mapping the whole model class

I am using Dapper in my ASP.NET MVC 5 application and in my query I only want 2 fields to return but the Json returns all of the fields. This is my model
public class thread
{
[Key]
public int id { get; set; }
public int? profileID { get; set; }
public int numberkeeper { get; set; }
public int? photocount { get; set; }
}
This is my controller..
[ResponseType(typeof(thread))]
public IHttpActionResult Getstream()
{
string Connectionstring = ConfigurationManager.ConnectionStrings["db"].ConnectionString;
using (System.Data.SqlClient.SqlConnection sqlConnection = new System.Data.SqlClient.SqlConnection(Connectionstring))
{
sqlConnection.Open();
var statevi = sqlConnection.Query<thread>("Select top 5 id,numberkeeper from threads").ToList();
if (statevi == null)
{
return NotFound();
}
return Ok(statevi);
}
}
That code returns Json as it is using .Net Web API,as you can see from the query I only want 2 fields returned. When I run it and see the Json it displays all fields (4) and off course the 2 fields not selected show up as null . I wanted so that the Json only shows the returnn of id and numberkeeper
Create a View Model class:
public class ThreadViewModel
{
public int id { get; set; }
public int numberkeeper { get; set; }
}
Let Dapper know you want it to create the ThreadViewModel for you:
var statevi = sqlConnection.Query<ThreadViewModel>("Select top 5 id,numberkeeper from threads").ToList();
This way you both query the database for the relevant properties and return just them to the client (without Dapper creating the full object with nulls).
If you create a new model that exposes the only two members that you want to render, that will prevent Web API from returning back additional JSON.
You could also convert the data after loading it into a new anonymous model using LINQ.
return Ok(statevi.Select(s => new { s.id, s.numberkeeper }));
If you want to keep the same model, but suppress null valued members Web API allows you to configure the JSON formatting to exclude null properties.
config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
If you want to use 2 or selected rows from query then you can use query method and extension method...
1. LINQ query method
using (System.Data.SqlClient.SqlConnection sqlConnection = new System.Data.SqlClient.SqlConnection(Connectionstring))
{
sqlConnection.Open();
var statevi = sqlConnection.Query<thread>("Select top 5 id,numberkeeper from threads").ToList();
if (statevi == null)
{
return NotFound();
}
var result = (from d in statevi
select new { d.id, d.numberkeeper }).ToList();
return Ok(result);
}
Extension Method: change this syntax to result of query method of above
var result = query.Select(d => new { d.Id, d.Title }).ToList();
both will give result same.
let me tell if it is working fine for your project or not.

Web API - Converting JSON to Complex Object Type (DTO) with inheritance

I have the following scenario:
public class WidgetBaseDTO
{
public int WidgetID
{
get;
set;
}
}
public class WidgetTypeA : WidgetBaseDTO
{
public string SomeProperty1
{
get;
set;
}
}
public class WidgetTypeB : WidgetBaseDTO
{
public int SomeProperty2
{
get;
set;
}
}
and my web service returns the following dashboard object whereas the Widgets collection could be of either type A or B:
public class DashboardDTO
{
public List<WidgetBaseDTO> Widgets
{
get;
set;
}
}
my problem is that although the client receives correct JSON content, which is dependent on the Widget type, when reading the response content, they are all being translated to WidgetBaseDTO. what is the correct way to convert these objects to the relevant types?
this is how the response is being read:
string relativeRequestUri = string.Format("api/dashboards/GetDashboard?dashboardID={0}", dashboardID);
using (var client = new HttpClient())
{
// set client options
client.BaseAddress = this.BaseUri;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// make request
HttpResponseMessage response = client.GetAsync(relativeRequestUri).Result;
if (response.IsSuccessStatusCode)
{
DashboardDTO dashboard = response.Content.ReadAsAsync<DashboardDTO>().Result;
}
I believe after receiving the response you are probably trying to cast WidgetBaseDTO to either WidgetTypeA or WidgetTypeB and you are seeing null? if yes, then you can try after making the following setting to the Json formatter on the server...make sure to make this setting on the client side's json formatter too.
config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects;
The above setting will cause the type information of WidgetTypeA or WidgetTypeB to be put over the wire which gives a hint to the client as to the actual type of the object being deserialized...you can try looking at the wire format of the response to get an idea...
Client side:
JsonMediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
jsonFormatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects;
WidgetBaseDTO baseDTO = resp.Content.ReadAsAsync<WidgetBaseDTO>(new MediaTypeFormatter[] { jsonFormatter }).Result;

asp.net mvc json result format

public class JsonCategoriesDisplay
{
public JsonCategoriesDisplay() { }
public int CategoryID { set; get; }
public string CategoryTitle { set; get; }
}
public class ArticleCategoryRepository
{
private DB db = new DB();
public IQueryable<JsonCategoriesDisplay> JsonFindAllCategories()
{
var result = from c in db.ArticleCategories
select new JsonCategoriesDisplay
{
CategoryID = c.CategoryID,
CategoryTitle = c.Title
};
return result;
}
....
}
public class ArticleController : Controller
{
ArticleRepository articleRepository = new ArticleRepository();
ArticleCategoryRepository articleCategoryRepository = new ArticleCategoryRepository();
public string Categories()
{
var jsonCats = articleCategoryRepository.JsonFindAllCategories().ToList();
//return Json(jsonCats, JsonRequestBehavior.AllowGet);
return new JavaScriptSerializer().Serialize(new { jsonCats});
}
}
This results with following:
{"jsonCats":[{"CategoryID":2,"CategoryTitle":"Politika"},{"CategoryID":3,"CategoryTitle":"Informatika"},{"CategoryID":4,"CategoryTitle":"Nova
kategorija"},{"CategoryID":5,"CategoryTitle":"Testna
kategorija"}]}
If I use line that is commented and place JsonResult instead of returning string, I get following result:<
[{"CategoryID":2,"CategoryTitle":"Politika"},{"CategoryID":3,"CategoryTitle":"Informatika"},{"CategoryID":4,"CategoryTitle":"Nova
kategorija"},{"CategoryID":5,"CategoryTitle":"Testna
kategorija"}]
But, I need result to be formatted like this:
{'2':'Politika','3':'Informatika','4':'Nova
kateorija','5':'Testna kategorija'}
Is there a simple way to accomplish this or I will need to hardcode result?
Have a look at the Json.Net library
The Json.NET library makes working
with JavaScript and JSON formatted
data in .NET simple. Quickly read and
write JSON using the JsonReader and
JsonWriter or serialize your .NET
objects with a single method call
using the JsonSerializer.
I have successfully used it within a .net mvc project.
ile,
you really should look at the json.net lib, i was in a similar dilemma recently with json/jquery and mvc and tried my own hand-rolled version but hit the many limitations in my own implemetation. the newton json lib is quite simply a no-brainer - simple to use and always being updated. the current version works fantastically with nested structures, thus making that particular json formatting issue a non-issue.
give it a look, will take you 15 mins to get to grips with.
Try returning it as an Array, Also if you return a JsonResult you can save alot of code (looks like you were attempting to get the formatting you wanted)
public class ArticleController : Controller
{
ArticleRepository articleRepository = new ArticleRepository();
ArticleCategoryRepository articleCategoryRepository = new ArticleCategoryRepository();
public JsonResult Categories()
{
var jsonCats = articleCategoryRepository.JsonFindAllCategories().ToArray();
return Json(jsonCats, JsonRequestBehavior.AllowGet);
}
}
in my test I got a result of
[{"Id":1,"Name":"Cat 1"},{"Id":2,"Name":"Cat 2"}]