I am trying to understand how ASP.NET MVC works and I have been recommended to follow the MVC Music Store Tutorial, however I am having problems since I am using different (more current) software.
According to this page I should add a List of genres to my action method inside my StoreController.cs. However according to Visual studio, this piece of code seems to be incorrect or not recognized. The error says: Identifier expected;'new' is a keyword. Should I use different code or do this in my model class instead in some way?
public ActionResult Index()
{
var genres = new List<Genre>
{
new Genre = { Name = "Disco" },
new Genre = { Name = "Jazz" },
new Genre = { Name = "Rock" }
};
return View();
}
Shouldn't something like this do the job?:
public ActionResult Index()
{
//var genres = new List<Genre>
//{
// new Genre = { Name = "Disco" },
// new Genre = { Name = "Jazz" },
// new Genre = { Name = "Rock" }
//};
var genres = new List<Genre>();
genres.Add(new Genre() { Name = "Disco" });
genres.Add(new Genre() { Name = "Jazz" });
genres.Add(new Genre() { Name = "Rock" });
return View();
}
And doesn't this constantly add the genres everytime I would run through the Index action method?
Your syntax is incorrect. Your first snippet is an object initializer and is no different than your second block of code where you create a new instance of Genre and assign its Name property, only in the first case you are attempting to assign { Name = "Disco" } to new Genre().
Read more on Object Initializer
public ActionResult Index()
{
var genres = new List<Genre>
{
new Genre { Name = "Disco" },
new Genre { Name = "Jazz" },
new Genre { Name = "Rock" }
};
return View();
}
To answer your second question, yes, that list (which is entirely in memory) will get created and then discarded every time your action runs. It's only meant to be sample code, if your application is more complicated you will probably get lists like this from somewhere else. Also, the code doesn't seem to do anything with this list, but I assume that's left out - you probably want it as part of the model or viewbag etc.
Related
I need to define a string array type dataType in Grpc message. not sure how to do. right now i am doing it as a
repeated string Title= 1,
here i need name field as string array Type. But it is showing error that it is, field is readonly type when bind data in it:
public override async Task<UserResponse> CreateUser(
UserModel request, ServerCallContext context)
{
var eventResponse = new UserResponse();
var createCmd = new CreateUserCommand
{
Model = new UserDto
{
Title = request.Title,
Id = request.Id,
}
}
}
here in title i need to bind data
The generated code from protoc here gives you something like:
private readonly RepeatedField<string> title_ = new RepeatedField<string>();
[DebuggerNonUserCodeAttribute]
public RepeatedField<string> Title {
get { return title_; }
}
So: Title is indeed read-only. This means that instead of assigning it, you should explore what APIs exist for adding to it - i.e.
var user = new UserDto
{
Id = request.Id,
}
user.Title.Add(request.Title);
// or AddRange, etc
You may still be able to use initializer syntax, too:
new UserDto
{
Id = request.Id,
Title = { request.Title }
}
(which is an .Add)
I have been tasked at work to create a test script that will (using entity framework) look-up a value in a table if existing.
The code I have to work with has this constructor:
public PostProductHelper(
Func<IMachineDBContext> contextFactory )
{
_contextFactory = contextFactory;
}
My method to unit test could be something like this:
public string CheckAndRemoveProductNameFileExtIfExists(
string productName )
{
using ( var ctx = CreateContext() )
{
return ctx.Products.FirstOrDefault( d => d.Name == productName);
}
}
so, going by the examples when Googling I am supposed to do this:
MockProductRepository = Substitute.For<IProductRepository>();
MockMessagePublicationService = Substitute.For<IMessagePublicationService>();
MockMachineDBContext = Substitute.For<IMachineDBContext>(););
var Products = new List<Product>
{
new Product { Name = "BBB" },
new Product { Name = "ZZZ" },
new Product { Name = "AAA" },
}.AsQueryable();
MockMachineDBContext.Products.AddRange( Products );
But in order to pass to my constructor I have to modify this to:
MockProductRepository = Substitute.For<IProductRepository>();
MockMessagePublicationService = Substitute.For<IMessagePublicationService>();
MockMachineDBContext = Substitute.For<Func<IMachineDBContext>>();
var Products = new List<Product>
{
new Product { Name = "BBB" },
new Product { Name = "ZZZ" },
new Product { Name = "AAA" },
}.AsQueryable();
MockMachineDBContext.Products.AddRange( Products );
which errors on the last line saying 'cannot resolve symbol 'Products'.
I am not allowed to change this constructor and I appreciate I may be making some mistakes.
You are missing () after MockMachineDBContext in MockMachineDBContext().Products.AddRange( Products );
MockMachineDBContext is delegate.
For usage also see Substituting for delegates in NSubstitute.
I'm trying to run a RavenDB transformation to map my documents to view models, but I'm running into this error:
Error CS1503 - Argument 1: cannot convert from 'AnonymousType#1'
I'm not sure why I can't initialise the new list of OfferRate here. How can I map my document model to the view model correctly?
Offer_ViewModel.cs
public class Offer_ViewModel : AbstractTransformerCreationTask<Offer>
{
public Offer_ViewModel()
{
TransformResults = offers => offers
.Select(offer => new ViewModels.Offer
{
Id = offer.Id,
MerchantId = offer.MerchantId,
Title = offer.Title,
OfferRates = new List<OfferRate>
{
new OfferRate
{
Type = OfferRateType.Base,
Amount = offer.Amount,
Percentage = offer.Percentage
}
},
Currency = offer.Currency
});
}
}
I'm following the guide to map to view models using transformers here: https://ravendb.net/articles/working-with-view-models but the example doesn't include mapping aggregated objects.
From the comment above, changing the collection to an array works.
Offer_ViewModel.cs
public class Offer_ViewModel : AbstractTransformerCreationTask<Offer>
{
public Offer_ViewModel()
{
TransformResults = offers => offers
.Select(offer => new ViewModels.Offer
{
Id = offer.Id,
MerchantId = offer.MerchantId,
Title = offer.Title,
OfferRates = new[]
{
new OfferRate
{
Type = OfferRateType.Base,
Amount = offer.Amount,
Percentage = offer.Percentage
}
},
Currency = offer.Currency
});
}
}
I have a simple List with dummy data as follows:
List<Organisation> list = new List<Organisation>();
list.Add(new Organisation() { LogoUrl = "/images/logos/Blade.png", OrganisationId = 1, OrganisationName = "Blade" });
list.Add(new Organisation() { LogoUrl = "/images/logos/Torn.png", OrganisationId = 2, OrganisationName = "Torn" });
When I run the linq query:
var results = from org in OrganisationsController.GetDummyList()
where org.OrganisationName.StartsWith(searchString)
select org;
It always returns an Empty result. In this case the searchString is specified by the user and the example would be "Tor".
Using different variations like 'where org.OrganisationName == searchString' where the search string is Torn works. But StartsWith never works.
Any ideas where I'm going wrong?
EDIT:
From Jon's code I changed my code to look as follows:
public JsonResult Search(string searchString)
{
//create json result object
JsonResult data = new JsonResult();
var list = OrganisationsController.GetDummyList();
//query the list
var results = from org in list
where org.OrganisationName.ToLower().Contains(searchString.ToLower())
select org;
if (results.Any())
{
System.Diagnostics.Debug.Write("found");
}
//setup the data
data.Data = results;
//return the data
return Json(data, JsonRequestBehavior.AllowGet);
}
Note: I changed the StartsWith to Contains, but both are giving me similary problems.
One of my organisations is called 'Absa'. Here's the really strange thing when I fire up the app for the first time putting in 'bsa' returns nothing, I then enter 'Absa' and it returns a good result. Then I entered 'bsa' again just to double check and it returned Absa which it didn't in the first test. Why would the result not work at first then work later?
Thanks,
Jacques
Unable to reproduce. It works fine for me:
using System;
using System.Collections.Generic;
using System.Linq;
class Organisation
{
public string LogoUrl { get; set; }
// Removed redundant Organisation prefixes
public int Id { get; set; }
public string Name { get; set; }
}
class Test
{
static void Main()
{
// Used collection initializer for sanity
var list = new List<Organisation>
{
new Organisation { LogoUrl = "Blade.png", Id = 1, Name = "Blade" },
new Organisation { LogoUrl = "Torn.png", Id = 2, Name = "Torn" },
};
string searchString = "Tor";
var query = from org in list
where org.Name.StartsWith(searchString)
select org;
// Nicer version:
// var query = list.Where(org => org.Name.StartsWith(searchString));
Console.WriteLine(query.Count()); // 1
}
}
Work out the difference between your code and my code to find out what's wrong.
In particular, you've shown code using List<T>, which means LINQ to Objects. If your real code uses LINQ to SQL or Entity Framework, that could easily affect things.
I have a model Person (with among other fields the day of Birth)
and I want to pass a list of all persons, together with the calculated age of each person, to the view
Therefor:
The view model
public class vm_PersonList
{
public Person Person { get; set; }
public int age { get; set; }
}
The controller action:
public ActionResult PersonList()
{
ViewBag.Message = "My List";
var list = new List<vm_PersonList>();
var list_p = new vm_PersonList();
foreach (var p in db.Person)
{
list_p.Person = p;
//the age will be calculated based on p.birthDay, not relevant for the
//current question
list_p.age = 23;
list.Add(list_p);
}
return View(list);
}
The view
#model List<programname.Viewmodels.vm_PersonList>
#foreach (var p in Model)
{
<tr>
<td>
#p.Person.FullName
</td>
<td>
#p.age
</td>
</tr>
}
The Person table contains for example 6 entries.
When debugging the application I see:
At the end of the controller action "list" contains correctly the 6 different Person entries
In the view, the "Model" contains 6 entries, but 6 times the last "database entry".
Does anyone have a suggestion to solve this issue?
You are using the same list_p instance over and over again inside the loop. So you are constantly updating its Person property. And since Person is a reference type you are modifying the same reference in memory. At the last iteration of the loop you are obviously replacing this reference with the last instance of Person which explains why you are seeing the same person in the view.
Try like this, seems lot easier:
public ActionResult PersonList()
{
ViewBag.Message = "My List";
var model = db.Person.Select(p => new vm_PersonList
{
Person = p,
age = 23
}).ToList();
return View(model);
}
You are working on the same instance of vm_PersonList. Move the instantiation of vm_PersonList into the loop
foreach (var p in db.Person)
{
var list_p = new vm_PersonList();
list_p.Person = p;
//the age will be calculated based on p.birthDay, not relevant for the
//current question
list_p.age = 23;
list.Add(list_p);
}
It's an issue with the scope of your list_p instance. Try changing your controller code to:
public ActionResult PersonList()
{
ViewBag.Message = "My List";
var list = db.Person
.Select(p => new vm_PersonList
{
Person = p,
age = 23,
})
.ToList();
return View(list);
}