Problems passing parameter to an action - c#

I'm trying to pass data to an action inside the same controller. I'm using RedirectToAction, but I'm not succeeding.
The action is called but the data I'm trying to pass to it has its values ​​null.
My Model:
public class PlaylistModel
{
public Guid PlayListID { get; set; }
[Display(Name = "Nome da Playlist")]
public string NomePlayList { get; set; }
[Display(Name = "Descrição")]
public string Descricao { get; set; }
[Display(Name = "Código")]
public string CodigoPlayList { get; set; }
public string Estado { get; set; }
public string EmailUser { get; set; }
public List<VideoThumbnails> VideosIdsYoutube { get; set; }
[Display(Name = "Categorias")]
public List<string> Categorias { get; set; }
}
This action receives the data, does the processing and calls the other action
[HttpPost]
public ActionResult CreatePlaylist(string Categorias, string NomePlayList)
{
PlaylistModel playListModel = new PlaylistModel();
playListModel.VideosIdsYoutube = AppCache.Instance.VideoParaAPI.VideoThumbnails.ToList();
playListModel.Categorias = Categorias.Split(',').ToList();
playListModel.NomePlayList = NomePlayList;
playListModel.Estado = EnumEstadoDaPlayList.Nova.ToString();
playListModel.EmailUser = AppUser.User.Email;
var api = new AccessAPI.Playlist.AccessAPIPlaylist();
var playlist = api.CriarNova(playListModel);
if(playlist != null)
{
return RedirectToAction("ExibirPlaylist", new RouteValueDictionary(new { controller = "Playlist", action = "ExibirPlaylist", pPlayList = playlist }));
}
else
{
return Problem("Não foi possível criar a playlist!");
}
}
This other action is called by the previous one, but the model arrives with null values
[HttpGet]
public ActionResult ExibirPlaylist(PlaylistModel pPlayList)
{
var apiVideo = new AccessAPI.Video.AccessAPIVideo();
var videos = apiVideo.ConsultarPorPlayListId(pPlayList.PlayListID).ToList();
if(videos.Count > 0)
{
videos.ForEach(v =>
{
pPlayList.VideosIdsYoutube.Add(new Dommain.Cache.VideoThumbnails() { CanalID = v.CanalID, DataDePublicacao = v.DataDePublicacao, NomeDoCanal = v.NomeDoCanal, NomeDoVideo = v.NomeDoVideo, Thumbnail = v.Thumbnail, VideoId = v.VideoIdYoutube});
});
}
return View();
}

The RouteValueDictionary in RedirectToAction() pass only simple types, like string, int etc. The RedirectToAction() doesn't serialize the complex data types. Therefore, may be the easiest way to use the TempData.
In the CreatePlaylist(string Categorias, string NomePlayList):
TempData["playListModel"] = playlist;
return RedirectToAction("ExibirPlaylist");
And then:
[HttpGet]
public ActionResult ExibirPlaylist()
{
if (TempData["playListModel"] is PlaylistModel pPlayList)
{
// Your code using `pPlayList`
}
return View("Index");
}
The MVC uses the binary serialization, by default. And in some cases the binary serialization can fail: Storing objects (non-string things) in TempDataDictionary does not round trip correctly. Therefore, it is preferably to serialize the specified object to a JSON string by JsonConvert.SerializeObject().

Related

How to use lambda expression to access correct data type?

I am using lambda expression to access values with data type, but the problem I have data type for Time as Time(7) on my local database and using Entity Framework. On my model this data type is define as DateTime.
How do I now access this data type to be time?
This is my code:
public List GetIncident_Details()
{
Entities incident = new Entities();
List result = new List();
var c_incident = incident.Incident_Template.Select(c => c).ToList();
if (c_incident != null && c_incident.Count() > 0)
{
foreach (var cData in c_incident)
{
Incident_DropDown model = new Incident_DropDown();
model.Title = cData.Title;
model.Description = cData.Description;
model.Date_Occurred = cData.Date_Occurred;
// How do I change this to have access?
// It's complaining about the data type object being set to a string?
model.Time = cData.Time;
model.Assignment_Group = cData.Assignment_Group;
model.Reported_CI = cData.Reported_CI;
result.Add(model);
}
}
return result;
}
public class Incident_DropDown
{
public string Title { get; set; }
public string Description { get; set; }
public string Date_Occurred { get; set; }
public DateTime Time { get; set; } // Time
public string Assignment_Group { get; set; }
public string Reported_CI { get; set; }
}
Took some advice from #alexey-rumyantsev, then had to test my code by interrogating model data type for Time it was Date Time, then change to Timespan. While testing this data type compare to my local database record and it was passing correct vales when debugging.
// Model name
public class Incident_DropDown
{
public string Title { get; set; }
public string Description { get; set; }
public string Date_Occured { get; set; }
public TimeSpan Time { get; set; } // had to change to work
public string Assignment_Group { get; set; }
public string Reported_CI { get; set; }
}
// Controller
public List<Incident_DropDown> GetIncident_Details()
{
Entities incident = new Entities();
List<Incident_DropDown> result = new List<Incident_DropDown>();
var c_incident = incident.Incident_Template.Select(c => c).ToList();
if (c_incident != null && c_incident.Count() > 0)
{
foreach (var cData in c_incident)
{
Incident_DropDown model = new Incident_DropDown();
model.Title = cData.Title;
model.Description = cData.Description;
model.Date_Occured = cData.Date_Occured;
model.Time = cData.Time; // This here enable to pass correct time as per database record
model.Assignment_Group = cData.Assignment_Group;
model.Reported_CI = cData.Reported_CI;
result.Add(model);
}
}
return result;
}

ASP NET Core (MVC) problem with passing parameters from the view to the controller

I got a two DropDownList's in View. When i try pass those parameters, method in controller called but parameters equals a null.
When i check in browser (F12-network) i watch parameters - they are sended but in method still nulls
P.S.
I try change type of parameters on List or Location and JobTitle or CommonEntity, but its doesn't work
Controller:
public class HelloController: Controller
{
[HttpGet]
public IActionResult Index()
{
var locations = new List<Location>()
{
new Location()
{
Id = 0,
Title = "Russia"
},
new Location()
{
Id = 1,
Title = "Canada"
}
};
ViewBag.Location = locations;
var jobs = new List<JobTitle>()
{
new JobsTitle()
{
Id = 0,
Title = "Manager"
} ,
new JobsTitle()
{
Id = 1,
Title = "Programmer"
}
};
ViewBag.JobTitle = new SelectList(jobs, "Title", "Title");
return View();
}
[HttpPost]
public string Find(string answer1, string answer2)
{
return "Fine";
}
View:
#using Stargate.Core.Models.CoreEntities
#model CommonEntity
#using (Html.BeginForm())
{
#Html.DropDownListFor(m => m.Location.Title, new SelectList(ViewBag.Location, "Title", "Title"))
#Html.DropDownListFor(m => m.JobTitle.Title, new SelectList(ViewBag.JobTitle, "Title", "Title"))
<button type="submit">Find</button>
}
Models:
public class CommonEntity
{
public Location Location { get; set; }
public JobTitle JobTitle { get; set; }
}
public class JobTitle
{
public long Id { get; set; }
public string Title { get; set; }
}
public class Location
{
public long Id { get; set; }
public string Title { get; set; }
}
Because the parameter names you accept are answer1, answer2, you should have a matching name in your view to make it possible to bind successfully.
You can modify your front-end code as follows(DropDownListForto DropDownList):
#model CommonEntity
#using (Html.BeginForm("Find", "Hello"))
{
#Html.DropDownList("answer1", new SelectList(ViewBag.Location, "Title", "Title"))
#Html.DropDownList("answer2", new SelectList(ViewBag.JobTitle, "Title", "Title"))
<button type="submit">Find</button>
}
Your Controller:
public class HelloController : Controller
{
[HttpGet]
public IActionResult Index()
{
var locations = new List<Location>()
{
new Location()
{
Id = 0,
Title = "Russia"
},
new Location()
{
Id = 1,
Title = "Canada"
}
};
ViewBag.Location = locations;
var jobs = new List<JobTitle>()
{
new JobTitle()
{
Id = 0,
Title = "Manager"
} ,
new JobTitle()
{
Id = 1,
Title = "Programmer"
}
};
ViewBag.JobTitle = jobs;
return View();
}
[HttpPost]
public string Find(string answer1,string answer2)
{
return "Fine";
}
}
Class:
public class CommonEntity
{
public Location Location { get; set; }
public JobTitle JobTitle { get; set; }
}
public class JobTitle
{
public long Id { get; set; }
public string Title { get; set; }
}
public class Location
{
public long Id { get; set; }
public string Title { get; set; }
}
Result:
you are doing things wrongly,
you should correct your cshtml so that when submitting the form, it will target your Find Action,
#using (Html.BeginForm("Find", "Hello"))
In your Find Action you should provide in input args resolvable by the DefaultModelBinder, since you don't have a ViewModel to intercept the response, I would suggest that you recieve a FormCollection and you can access your values from there.
[HttpPost]
public string Find(FormCollection form)
{
return "Fine";
}
Try updating parameters as below. Please refer Model Binding in ASP.NET Core for more details.
[HttpPost]
public string Find(Location Location, JobTitle JobTitle)
{
return "Fine";
}
Or you can try with parameter of CommonEntity like below.
[HttpPost]
public string Find(CommonEntity commonEntity)
{
var locationTitle = commonEntity.Location.Title;
var jobTitle = commonEntity.JobTitle.Title;
return "Fine";
}

json response through MongoDb

When the below API method is called through the API
public IActionResult FirstStudent()
{
var collection = this.database.GetCollection<BsonDocument>("students");
var filter = Builders<BsonDocument>.Filter.Eq("RollNo", "1");
var document = collection.Find(filter).First();
var firstStudent= document.ToJson();
return Ok(firstStudent);
}
the response has Content-Type as text/plain.
I need the Content-Type as application/json.
Any suggestions?
the easiest thing to do would be to create a student model and simply return an ok result with the student model like this:
public class Student
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public int RollNo { get; set; }
public string Name { get; set; }
}
public IActionResult FirstStudent()
{
var collection = this.database.GetCollection<Student>("Student");
var filter = Builders<Student>.Filter.Where(s => s.RollNo == 1);
var document = collection.Find(filter).First();
return Ok(document);
}

In MVC getting "Self referencing loop detected" error

I am getting an error while executing an application using MVC4, Web API, AngularJS . The error is following:
Self referencing loop detected with type
'System.Data.Entity.DynamicProxies.Product_259FEB40BD6111F44AA3C3CED8DD40E7E44B22CC11A32AE621E84E2239F79B2C'. Path '[0].category.products'.
My products.cs file under model folder is:
public partial class Product
{
[JsonIgnore]
[Key]
public int ProductID { get; set; }
public string ProductName { get; set; }
public Nullable<int> SupplierID { get; set; }
public Nullable<int> CategoryID { get; set; }
public string QuantityPerUnit { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public Nullable<short> UnitsInStock { get; set; }
public Nullable<short> UnitsOnOrder { get; set; }
public Nullable<int> ReorderLevel { get; set; }
public bool Discontinued { get; set; }
public virtual Category Category { get; set; }
public virtual Supplier Supplier { get; set; }
}
Product controller is:
public class ProductController : JsonController
{
private readonly DBEntities _db = new DBEntities();
public ActionResult GetProduct()
{
var productList = _db.Products;
return Json(productList, JsonRequestBehavior.AllowGet);
}
}
Class that returns JSON and included in product controller is:
public class JsonController : Controller
{
public new ActionResult Json(object data, JsonRequestBehavior behavior)
{
var jsonSerializerSetting = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
if (Request.RequestType == WebRequestMethods.Http.Get && behavior == JsonRequestBehavior.DenyGet)
{
throw new InvalidOperationException("GET is not permitted for this request.");
}
var jsonResult = new ContentResult
{
Content = JsonConvert.SerializeObject(data, jsonSerializerSetting),
ContentType = "application/json"
};
return jsonResult;
}
}
The productController.js file which is using AngularJS is:
myApp.controller('productController',
['$scope', 'productDataService', '$location',
function productController($scope, productDataService) {
$scope.products = [];
$scope.currentPage = 1;
$scope.pageSize = 10;
loadProductData();
function loadProductData() {
productDataService.getProducts()
.then(function () {
$scope.products = productDataService.products;
},
function () {
//Error goes here...
})
.then(function () {
$scope.isBusy = false;
});
$scope.pageChangeHandler = function (num) {
console.log('Product page changed to ' + num);
}
};
}
]);
Data service is like:
myApp.factory('productDataService', ['$http', '$q',
function ($http, $q) {
var _products = [];
var _getProducts = function () {
var deferred = $q.defer();
var controllerQuery = "product/GetProduct";
$http.get(controllerQuery)
.then(function (result) {
// Successful
angular.copy(result.data, _products);
deferred.resolve();
},
function (error) {
// Error
deferred.reject();
});
return deferred.promise;
};
return {
products: _products,
getProducts: _getProducts
};
}
]);
Same type of code is working well for another application but I not clear why the above mentioned code is not working.
Any help will be thankfully accepted.
Thanks
Partha
You can do this:
return new ContentResult
{
Content = JsonConvert.SerializeObject(data, Formatting.None, new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore}),
ContentType = "application/json"
};
Open WebApiConfig and register following JsonFormatter
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore;
Yeah this is probably due to json trying to serializer your navigation objects.
public virtual Category Category { get; set; }
public virtual Supplier Supplier { get; set; }
1.Do quest test to rule this out.
2.Code up a ignore rule for them or create a DTO object for Product,

Error in downloading a file in ASP.NET MVC

I am working in ASP.NET MVC. I have stored a file in the database now I want to download and display its contents. I am working in layers.
Here is my code.
Controller Action used for uploading file
[HttpPost]
public ActionResult Edit(int id, UpdateAdvertisement model, HttpPostedFileBase file)
{
try
{
AdvertisementDTO add = new AdvertisementDTO();
add.DocImage = new byte[file.ContentLength];
add.ContentType = file.ContentType;
add.DocName = Convert.ToString(DateTime.Now.Ticks);
new AdvertisementHandler().Update(id, add);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Controller Action for downloading file
public FileContentResult DownloadFile(int id)
{
string DocumentContentType = new AdvertisementHandler().DownloadContent(id);
string DocumentName = new AdvertisementHandler().DownloadDocumentName(id);
byte[] DocumentImage = new AdvertisementHandler().DownloadImage(id);
//return File(filename, contentType, "Report.pdf");
return File(DocumentImage, DocumentContentType, DocumentName);
//return File.ReadAllBytes(DocumentName);
}
Business Logic Layer
These are the queries that are used to access database.
public byte[] DownloadImage(int id)
{
byte[] file = (from f in db.TBL_ADVERTISEMENT
where f.ID == id
select new AdvertisementDTO
{
DocImage = f.DOCUMENT_IMG
}
).ToArray();
return file;
}
public string DownloadContent(int id )
{
string file = (from f in db.TBL_ADVERTISEMENT
where f.ID == id
select new AdvertisementDTO
{
ContentType = f.CONTENTTYPE
}
).ToString();
return file;
}
public string DownloadDocumentName(int id)
{
string file = (from f in db.TBL_ADVERTISEMENT
where f.ID == id
select new AdvertisementDTO
{
DocName = f.DOC_NAME
}
).ToString();
return file;
}
This error arises when i compile this code
Error 1
Cannot implicitly convert type 'ORS.DTO.AdvertisementDTO[]' to 'byte[]'
F:\Projects\Online Recruitment System\ORS.BLL\AdvertisementHandler.cs 59 28 ORS.BLL
Here is my AdvertisementDTO...
namespace ORS.DTO
{
public class AdvertisementDTO
{
public int ID { get; set; }
public string AddNumber { get; set; }
public string Description { get; set; }
public byte[] DocImage { get; set; }
public string ContentType { get; set; }
public string DocName { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int StatusID { get; set; }
public virtual RecordStatusDTO RecordStatus { get; set; }
}
}
Calling .ToArray() on an object does not convert it to a byte array. You omitted the definition of AdvertisementDTO so I can only guess that it is already a byte array. If that's not the case please post the code for AdvertisementDTO and I'll update this post.
byte[] file = (from f in db.TBL_ADVERTISEMENT
where f.ID == id
select f.DOCUMENT_IMG).SingleOrDefault();
return file;

Categories

Resources