I'm new to asp.net mvc & I'm trying to make a website where user can sort a table after login. When I build the project I get errors like, Does not contain a definition for 'OrderByDescending'/'OrderBy'/'ToList'. Here are my codes,
Controller
ViewBag.CodeSort = String.IsNullOrEmpty(sortOrder) ? "code_desc" : "";
var sortedOut = new MkistatVsUserLogin { mkistats = dsedb.mkistats.AsQueryable() }; //Error in this line
switch (sortOrder)
{
case "code_desc":
sortedOut = sortedOut.OrderByDescending(s => s.MKISTAT_CODE); //error in this line
break;
default:
sortedOut = sortedOut.OrderBy(s => s.MKISTAT_CODE); //error in this line
break;
}
return View(sortedOut.ToList()); //error in this line
Model
public class MkistatVsUserLogin
{
public IQueryable<mkistat> mkistats { get; set; }
public idx Idxs { get; set; }
}
How can I solve this problem? Need this help badly. Tnx.
Because the IQueryable is the mkistats, not the sortedOut!
ViewBag.CodeSort = String.IsNullOrEmpty(sortOrder) ? "code_desc" : "";
var sortedOut = new MkistatVsUserLogin { mkistats = dsedb.mkistats.AsQueryable() }; //Error in this line
switch (sortOrder)
{
case "code_desc":
sortedOut.mkistats = sortedOut.mkistats.OrderByDescending(s => s.MKISTAT_CODE); //error in this line
break;
default:
sortedOut.mkistats = sortedOut.mkistats.OrderBy(s => s.MKISTAT_CODE); //error in this line
break;
}
return View(sortedOut); //error in this line
And the switch is wrong, but I am not sure how to solve it. It should probably be
switch (ViewBag.CodeSort)
Note that as the code is written, the view will only receive a List<mkistat>, not a full MkistatVsUserLogin object.
OrderByDescending is an extension method inside of System.Linq.
Make sure you have the relevant using statemenet at the top of your class
using System.Linq;
Related
I would like to ask about shopify pagination version 2020-01
First request query:
URL: https://klevarange.myshopify.com/admin/api/2020-01/orders.json?fulfillment_status=unfulfilled&limit=250&financial_status=paid&created_at_min=2019-08-27T16:15:47-04:00
Return Header:
"<https://klevarange.myshopify.com/admin/api/2020-01/orders.json?limit=250&page_info=eyJmaW5hbmNpYWxfc3RhdHVzIjoicGFpZCIsImZ1bGZpbGxtZW50X3N0YXR1cyI6InVuZnVsZmlsbGVkIiwiY3JlYXRlZF9hdF9taW4iOiIyMDE5LTA4LTI3IDIwOjE1OjQ3IFVUQyIsImxhc3RfaWQiOjIxMDQ4NzIxNzM2NTIsImxhc3RfdmFsdWUiOiIyMDIwLTAyLTI3IDAwOjA5OjUyIiwiZGlyZWN0aW9uIjoibmV4dCJ9>; rel=\"next\""
2nd Request Query:
"https://klevarange.myshopify.com/admin/api/2020-01/orders.json?limit=250&page_info=eyJmaW5hbmNpYWxfc3RhdHVzIjoicGFpZCIsImZ1bGZpbGxtZW50X3N0YXR1cyI6InVuZnVsZmlsbGVkIiwiY3JlYXRlZF9hdF9taW4iOiIyMDE5LTA4LTI3IDIwOjE1OjQ3IFVUQyIsImxhc3RfaWQiOjIxMDQ4NzI1MzQxMDAsImxhc3RfdmFsdWUiOiIyMDIwLTAyLTI3IDAwOjEwOjA3IiwiZGlyZWN0aW9uIjoibmV4dCJ9>; rel=\"next\""
Result: Bad Request
What should I put in page_info? Do I need to include the rel=\"next\"" in the page_info?
Thank you.
Remove > from your page_info variable
var page_info = "eyJmaW5hbmNpYWxfc3RhdHVzIjoicGFpZCIsImZ1bGZpbGxtZW50X3N0YXR1cyI6InVuZnVsZmlsbGVkIiwiY3JlYXRlZF9hdF9taW4iOiIyMDE5LTA4LTI3IDIwOjE1OjQ3IFVUQyIsImxhc3RfaWQiOjIxMDQ4NzI1MzQxMDAsImxhc3RfdmFsdWUiOiIyMDIwLTAyLTI3IDAwOjEwOjA3IiwiZGlyZWN0aW9uIjoibmV4dCJ9"
and Make your request URL like below.
https://klevarange.myshopify.com/admin/api/2020-01/orders.json?limit=250&page_info={page_info}
Digging Deeper
You need to iterate your while loop until there is no Link Parameter in the response header and this parameter is not a static value it is the address of last object you get and saying next will give you next 250 objects.
you need to update your pageInfo parameter in every request with newly generated next reference ( pageInfo )
When you do not get this parameter that means there is no next or previous page .
Have a look in this below code...( written in php )
How to create pagination in shopify rest api using php
You should use only this part: https://klevarange.myshopify.com/admin/api/2020-01/orders.json?limit=250&page_info=eyJmaW5hbmNpYWxfc3RhdHVzIjoicGFpZCIsImZ1bGZpbGxtZW50X3N0YXR1cyI6InVuZnVsZmlsbGVkIiwiY3JlYXRlZF9hdF9taW4iOiIyMDE5LTA4LTI3IDIwOjE1OjQ3IFVUQyIsImxhc3RfaWQiOjIxMDQ4NzI1MzQxMDAsImxhc3RfdmFsdWUiOiIyMDIwLTAyLTI3IDAwOjEwOjA3IiwiZGlyZWN0aW9uIjoibmV4dCJ9 i.e. without rel="next"
In the 2nd and all next requests, you can only pass up to 3 query parameters:
page_info
limit
fields
So if you want to get results from the next page you need to extract page_info value from the first response headers.
The idea is that you can move only forward or backwards while requesting the results and you can get the link (page_info token) to the next (or previous) page only after retrieving the current page results.
Maybe in the last 2 years, Shopify has made some modifications to their API, then I use GetNextPageFilter method. This is my approach.
public async Task<IEnumerable<Product>> ProductsGetList(string shopUrl, string accessToken)
{
var products = new List<Product>();
var service = new ProductService(shopUrl, accessToken);
var filter = GetFilters(shopUrl);
var productList = await service.ListAsync(filter);
if (productList != null && productList.Items.Any())
{
products.AddRange(productList.Items);
bool hasMorePages = productList.HasNextPage;
if (hasMorePages)
{
do
{
var filterList = productList.GetNextPageFilter(filter.Limit, filter.Fields);
productList = await service.ListAsync(filterList);
if (productList != null && productList.Items.Any())
{
products.AddRange(productList.Items);
hasMorePages = productList.HasNextPage;
}
} while (hasMorePages);
}
}
return products;
}
private ProductListFilter GetFilters(string url)
{
ProductListFilter filters = new ProductListFilter();
string queryString = new System.Uri(url).Query;
var queryDictionary = System.Web.HttpUtility.ParseQueryString(queryString);
foreach (var parameter in queryDictionary)
{
var key = (string)parameter;
var value = queryDictionary.Get(key);
switch (key)
{
case "published_status":
filters.PublishedStatus = value;
break;
case "published_at_max":
filters.PublishedAtMax = DateTimeOffset.Parse(value);
break;
case "published_at_min":
filters.PublishedAtMin = DateTimeOffset.Parse(value);
break;
case "updated_at_max":
filters.UpdatedAtMax = DateTimeOffset.Parse(value);
break;
case "updated_at_min":
filters.UpdatedAtMin = DateTimeOffset.Parse(value);
break;
case "created_at_max":
filters.CreatedAtMax = DateTimeOffset.Parse(value);
break;
case "presentment_currencies":
filters.PresentmentCurrencies = value.Split(',').AsEnumerable();
break;
case "created_at_min":
filters.CreatedAtMin = DateTimeOffset.Parse(value);
break;
case "status":
filters.Status = value;
break;
case "product_type":
filters.ProductType = value;
break;
case "handle":
filters.Handle = value;
break;
case "vendor":
filters.Vendor = value;
break;
case "title":
filters.Title = value;
break;
case "since_id":
filters.SinceId = long.Parse(value);
break;
case "collection_id":
filters.CollectionId = long.Parse(value);
break;
case "ids":
filters.Ids = value.Split(',').AsEnumerable().Cast<long>();
break;
case "limit":
filters.Limit = int.Parse(value);
break;
}
}
return filters;
}
Where shopUrl is the entire URL (https://{apiKey}:{password}#{hostname}/admin/api/{version}/{resource}.json) and accessToken is the URL {password} atribute
I'm writing this simple code in html:-
<a id="{{L.ID}}" target="_blank" href="/Home/RedirectToMaterialView?MaterialTypeID={{L.MaterialTypeID}}&SearchListID={{L.SearchListID}}&Category={{L.Category}}" style="cursor:pointer">Open</a>
Now this goes to my HomeController and works perfect in my local machine, where I redirect it to some other actionlink. c# controller actionresult is like this:-
public ActionResult RedirectToMaterialView(string MaterialTypeID, string SearchListID, string Category)
{
if (!string.IsNullOrEmpty(SearchListID))
{
dbundle.MaterialFetchID = Convert.ToInt32(SearchListID);
dbundle.MaterialIndicator = Convert.ToInt32(MaterialTypeID);
dbundle.MaterialFor = Convert.ToString(Category);
string queryString = string.Empty;
TempData["DBundle"] = dbundle;
switch (dbundle.MaterialFor)
{
case "Class":
switch (dbundle.MaterialIndicator)
{
case 1:
TempData["ClassMaterialHeading"] = Constants.EBook;
break;
case 2:
TempData["ClassMaterialHeading"] = Constants.Notes;
break;
default:
TempData["ClassMaterialHeading"] = "";
break;
}
return RedirectToAction(Constants.ClassMaterial, new { id= dbundle.MaterialFetchID, MatFor =dbundle.MaterialFor});
case "Degree":
switch (dbundle.MaterialIndicator)
{
case 1:
TempData["DegreeMaterialHeading"] = Constants.EBook;
break;
case 2:
TempData["DegreeMaterialHeading"] = Constants.Notes;
break;
default:
TempData["DegreeMaterialHeading"] = "";
break;
}
return RedirectToAction(Constants.DegreeMaterial, new { id = dbundle.MaterialFetchID, MatFor = dbundle.MaterialFor });
default:
return RedirectToAction(Constants.School);
}
}
else
return RedirectToAction(Constants.Degree);
}
But when I run this code on server. It's redirecting to a blank page.
I don't know what's creating problem. Maybe I'm missing something in the link. But I can't figure out what's the problem on server which is not on my machine.
Help Appreciated.
I'm doing a Workflow Activity that comes from a CRM process .
I have two inputs that are EntityReference and are being filled in the process.
Don't printing the trace that is after the try . Just enter the catch. And i donĂ½ know why.
My code is:
public class WK_DecorrerObjetivo : CodeActivity
{
//inputs dialog --- // input alvo
[Input("Alvo")]
[ReferenceTarget("xpto_alvo")]
public InArgument<EntityReference> alvo { get; set; }
//input actividade xpto_atividadeobjetivoid
[Input("Actividade Objetivo")]
[ReferenceTarget("xpto_atividadedeobjetivo")]
public InArgument<EntityReference> atividadeObjetivo { get; set; }
protected override void Execute(CodeActivityContext Execontext)
{
ITracingService _tracing;
IWorkflowContext context = null;
IOrganizationServiceFactory serviceFactory = null;
IOrganizationService service = null;
OrganizationServiceContext serviceContext = null;
try
{
#region Get Work Flow Context
context = Execontext.GetExtension<IWorkflowContext>();
serviceFactory = Execontext.GetExtension<IOrganizationServiceFactory>();
service = serviceFactory.CreateOrganizationService(context.InitiatingUserId);
serviceContext = new OrganizationServiceContext(service);
_tracing = Execontext.GetExtension<ITracingService>();
_tracing.Trace("inicio do try");
FetchExpression query = new FetchExpression(string.Format(Resources.GetTemplateAtividade, context.PrimaryEntityId));
// Obtain result from the query expression.
Entity new_alvo = (Entity)context.InputParameters["Target"];
var alvoGUID = ((EntityReference)new_alvo["xpto_alvo"]).Id;
Entity retrieveTemp = service.Retrieve("xpto_alvo", ((EntityReference)new_alvo["xpto_alvo"]).Id, new ColumnSet("xpto_utilizador", "xpto_conta", "xpto_contacto", "xpto_alvoid", "xpto_name", "createdon", "xpto_estado", "xpto_resultadoimportacao", "xpto_objetivoassociadoid", "xpto_alvo"));
OptionSetValue tipoAtividade = (OptionSetValue)retrieveTemp.Attributes["xpto_tipoatividade"];
switch (tipoAtividade.Value)
{
case 0:
_tracing.Trace("entrou no case 0 - compromisso");
break;
case 1:
_tracing.Trace("entrou no case 1 - phonecall");
break;
case 2:
_tracing.Trace("entrou no case 2 - task");
break;
default:
break;
}
//serviceContext.SaveChanges(); _tracing.Trace("savechanges");
}
catch (Exception ex)
{
string msgErro;
if (ex.InnerException != null)
{
msgErro = ex.InnerException.Message;
}
else
{
msgErro = ex.Message;
}
throw new InvalidPluginExecutionException(string.Format("Erro ao decorrer objetivo: {0}", msgErro));
}
}
}
Thank's.
The option set value you are trying to access "xpto_tipoatividade" isn't included in the list of columns to fetch in the retrieve request. Also always check if the attribute exists in the returned entity attribute collection and safe cast it or use an extension method to get a default value.
var retrieveTemp = service.Retrieve("xpto_alvo",
((EntityReference) new_alvo["xpto_alvo"]).Id,
new ColumnSet(
"xpto_tipoatividade", //<-- add xpto_tipoatividade to the list of attributes to fetch
"xpto_utilizador",
"xpto_conta",
"xpto_contacto",
"xpto_alvoid",
"xpto_name",
"createdon",
"xpto_estado",
"xpto_resultadoimportacao",
"xpto_objetivoassociadoid",
"xpto_alvo"));
var tipoAtividade = retrieveTemp.GetAttributeValue<OptionSetValue>("xpto_tipoatividade");
if (tipoAtividade == null)
{
_tracing.Trace("tipoAtividade is null, returning");
return;
}
switch (tipoAtividade.Value)
{
....
}
I have a foreach loop that loops trought a list of objects. The meaning of it is to set a NavigateUrl to a Hyperlink. My code looks like this:
foreach (var con in contacts)
{
if (con.ContactTypeID == 1)
{
FacebookIcon.NavigateUrl = "http://facebook.com/" + con.ContactURL;
}
}
I wonder if their is some better way to do it. I will have about 10 other ContactTypeID and I rather don't write nine more if else..
You could use LINQ:
var facebookURL = contacts.Where(c => c.ContactTypeID == 1)
.Select(c => c.url)
.FirstOrDefault();
if(facebookURL != null)
FacebookIcon.NavigateUrl = "http://facebook.com/" + facebookURL;
Edit: Actually you could benefit of LINQ's deferred execution to reuse the same for every type of contact-type:
var contactType = 1; // facebook
var url = contacts.Where(c => c.ContactTypeID == contactType)
.Select(c => c.url);
if (url.Any())
FacebookIcon.NavigateUrl = "http://facebook.com/" + url.First();
contactType = 2; // google
if (url.Any())
GoogleIcon.NavigateUrl = "http://Google.com/" + url.First();
Edit 2: Here's another approach using a Dictionary mapping all types with their URLs which should be more efficient in case you have millions of types ;-) (#MAfifi):
var urlTypeMapping = contacts.GroupBy(c => c.ContactTypeID)
.ToDictionary(grp => grp.Key, grp => grp.Select(c => c.url));
foreach (var type in urlTypeMapping)
{
var typeUrl = type.Value.FirstOrDefault();
if (typeUrl != null)
{
switch (type.Key)
{
case 1:
FacebookIcon.NavigateUrl = "http://facebook.com/" + typeUrl;
break;
case 2:
GoogleIcon.NavigateUrl = "http://Google.com/" + typeUrl;
break;
default:
break; //or throw new Exception("Invalid type!");
}
}
}
You could use LINQ in order to do what you want.
var x = contacts.FirstOrDefault (c => c.ContactTypeID == 1);
if( x != null )
{
FacebookIcon.NavigateUrl = String.Format ("http://facebook.com/{0}", x.ContactURL);
}
You can use switch
switch (caseSwitch)
{
case 1:
FacebookIcon.NavigateUrl = "http://facebook.com/" + con.ContactURL;
break;
case 2:
//
break;
default:
//
break;
}
you can use linq.
var con = contacts.FirsOrDefault(c => c.ContactTypeID.Equals(1));
if (con == null)
{
return;
}
con.NavigateUrl = "http://facebook.com/" + con.ContactURL;
Or if you have more id's
List<int> ids = new List<int> {1,2,5,7};
contacts.Where(c => ids.Containt(c.ContactTypeID)).ToList().ForEach(item => item.NavigateUrl = "http://facebook.com/" + item.ContactURL);
If you use Linq You should use First or FirstOrDefault
var url = contacts.FirstOrDefault(c => c.ContactTypeID == 1).NavigateUrl;
Use a switch:
foreach (var con in contacts)
{
switch (con.ContactTypeID)
{
case 1:
FacebookIcon.NavigateUrl = "http://facebook.com/" + con.ContactURL;
break;
case 2:
. . .
break;
. . .
}
}
Perhapse a condensed LINQ:
contacts.ForEach(c => { if (c.ContactTypeID == 1) FacebookIcon.NavigateUrl = "http://facebook.com/" + con.ContactURL; });
If you want to do "it" for each ContactTypeID == 1.
I assume that each contact is not necessarily Facebook and you need to dynamically set different attributes based on what the contact is?
Your best bet is a Dictionary<int, Action> or similar, where you just do something like,
var setCorrectUrl = new Dictionary<int, Action<Contact>>
{
// Appropriate entries in here, e.g. (syntax not quite right)
{
1,
(contact) => FacebookIcon.NavigateUrl = contact.ContactURL;
}
}
foreach (var con in contacts)
{
setCorrectUrl[con.ContactTypeID](con);
}
Well, I would do some refactoring of the code.
Imagine he would have 10 other types to implement :)
The solutions provided above are workable but not very elegant in terms of extensibility.
So, here is my solution:
1) Implement a base class with the common contact properties
public abstract class BaseContact
{
public string Name { get; set; }
public abstract string Url { get; set; }
}
2) Implement the concrete types
public class FbContact : BaseContact
{
private string _baseUrl = "http://facebook.com/{0}";
private string _url = string.Empty;
public override string Url
{
get { return _url; }
set { _url = string.Format(_baseUrl, value); }
}
}
public class LinkedInContact : BaseContact
{
private string _baseUrl = "http://linkedin.com/{0}";
private string _url = string.Empty;
public override string Url
{
get { return _url; }
set { _url = string.Format(_baseUrl, value); }
}
}
3) This is just a helper class for setting the navigation url
public static class NavigationCreator
{
public static void SetUrl(BaseContact contact, HyperLink link)
{
link.NavigateUrl = contact.Url;
}
}
4) Some test code to visualize the result
List<BaseContact> items = new List<BaseContact>();
for (int i = 0; i < 5; i++)
{
BaseContact item;
if (i % 2 == 0) item = new FbContact(); else item = new LinkedInContact();
item.Url = "My name " + i;
items.Add(item);
}
foreach (var contact in items)
{
HyperLink link = new HyperLink();
NavigationCreator.SetUrl(contact, link);
Console.WriteLine(link.NavigateUrl);
}
Console.Read();
I'm doing an C# app where I use
if ((message.Contains("test")))
{
Console.WriteLine("yes");
} else if ((message.Contains("test2"))) {
Console.WriteLine("yes for test2");
}
There would be any way to change to switch() the if() statements?
Correct final syntax for [Mr. C]s answer.
With the release of VS2017RC and its C#7 support it works this way:
switch(message)
{
case string a when a.Contains("test2"): return "no";
case string b when b.Contains("test"): return "yes";
}
You should take care of the case ordering as the first match will be picked. That's why "test2" is placed prior to test.
Nope, switch statement requires compile time constants. The statement message.Contains("test") can evaluate true or false depending on the message so it is not a constant thus cannot be used as a 'case' for switch statement.
If you just want to use switch/case, you can do something like this, pseudo-code:
string message = "test of mine";
string[] keys = new string[] {"test2", "test" };
string sKeyResult = keys.FirstOrDefault<string>(s=>message.Contains(s));
switch (sKeyResult)
{
case "test":
Console.WriteLine("yes for test");
break;
case "test2":
Console.WriteLine("yes for test2");
break;
}
But if the quantity of keys is a big, you can just replace it with dictionary, like this:
static Dictionary<string, string> dict = new Dictionary<string, string>();
static void Main(string[] args)
{
string message = "test of mine";
// this happens only once, during initialization, this is just sample code
dict.Add("test", "yes");
dict.Add("test2", "yes2");
string sKeyResult = dict.Keys.FirstOrDefault<string>(s=>message.Contains(s));
Console.WriteLine(dict[sKeyResult]); //or `TryGetValue`...
}
This will work in C# 8 using a switch expresion
var message = "Some test message";
message = message switch
{
string a when a.Contains("test") => "yes",
string b when b.Contains("test2") => "yes for test2",
_ => "nothing to say"
};
For further references
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/switch-expression
Simple yet efficient with c#
string sri = "Naveen";
switch (sri)
{
case var s when sri.Contains("ee"):
Console.WriteLine("oops! worked...");
break;
case var s when sri.Contains("same"):
Console.WriteLine("oops! Not found...");
break;
}
string message = "This is test1";
string[] switchStrings = { "TEST1", "TEST2" };
switch (switchStrings.FirstOrDefault<string>(s => message.ToUpper().Contains(s)))
{
case "TEST1":
//Do work
break;
case "TEST2":
//Do work
break;
default:
//Do work
break;
}
You can do the check at first and then use the switch as you like.
For example:
string str = "parameter"; // test1..test2..test3....
if (!message.Contains(str)) return ;
Then
switch(str)
{
case "test1" : {} break;
case "test2" : {} break;
default : {} break;
}
Faced with this issue when determining an environment, I came up with the following one-liner:
string ActiveEnvironment = localEnv.Contains("LIVE") ? "LIVE" : (localEnv.Contains("TEST") ? "TEST" : (localEnv.Contains("LOCAL") ? "LOCAL" : null));
That way, if it can't find anything in the provided string that matches the "switch" conditions, it gives up and returns null. This could easily be amended to return a different value.
It's not strictly a switch, more a cascading if statement but it's neat and it worked.
Some custom swtich can be created like this. Allows multiple case execution as well
public class ContainsSwitch
{
List<ContainsSwitch> actionList = new List<ContainsSwitch>();
public string Value { get; set; }
public Action Action { get; set; }
public bool SingleCaseExecution { get; set; }
public void Perform( string target)
{
foreach (ContainsSwitch act in actionList)
{
if (target.Contains(act.Value))
{
act.Action();
if(SingleCaseExecution)
break;
}
}
}
public void AddCase(string value, Action act)
{
actionList.Add(new ContainsSwitch() { Action = act, Value = value });
}
}
Call like this
string m = "abc";
ContainsSwitch switchAction = new ContainsSwitch();
switchAction.SingleCaseExecution = true;
switchAction.AddCase("a", delegate() { Console.WriteLine("matched a"); });
switchAction.AddCase("d", delegate() { Console.WriteLine("matched d"); });
switchAction.AddCase("a", delegate() { Console.WriteLine("matched a"); });
switchAction.Perform(m);
Stegmenn nalied it for me, but I had one change for when you have an IEnumerable instead of a string = message like in his example.
private static string GetRoles(IEnumerable<External.Role> roles)
{
string[] switchStrings = { "Staff", "Board Member" };
switch (switchStrings.FirstOrDefault<string>(s => roles.Select(t => t.RoleName).Contains(s)))
{
case "Staff":
roleNameValues += "Staff,";
break;
case "Board Member":
roleNameValues += "Director,";
break;
default:
break;
}
}
This will work in C# 7. As of this writing, it has yet to be released. But if I understand this correctly, this code will work.
switch(message)
{
case Contains("test"):
Console.WriteLine("yes");
break;
case Contains("test2"):
Console.WriteLine("yes for test2");
break;
default:
Console.WriteLine("No matches found!");
}
Source: https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/
switch(message)
{
case "test":
Console.WriteLine("yes");
break;
default:
if (Contains("test2")) {
Console.WriteLine("yes for test2");
}
break;
}