Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Ochowie
Nov 9, 2007

EssOEss posted:

The way I think about it is that .NET Core is a set of interfaces/APIs that are exposed by various products called CoreFX (often used with the DNX runtime; which... I think... is the same as CoreCLR) and the Base Class Library (often used with the .NET Framework runtime). To "run something with .NET Core" makes no sense to me - it is not a piece of software, though it is implemented by various pieces of software.

Just my two cents; I am not comfortable enough with the topic to be able to help you out any more or to really commit to this interpretation!

I guess then my question would be, what's the difference between executing something using the dotnet run command vs. through DNX. I assumed that the dotnet version always invokes CoreCLR while DNX is more of an abstraction that could use different versions of the CLR in the background. The interesting thing is, I checked which runtime DNX was using (via DNVM) and it was previously using Mono. After I changed it to use CoreCLR my hello world application still ran correctly. So it leaves me even more confused about why it would run using DNX but not using the dotnet command.

Adbot
ADBOT LOVES YOU

Inverness
Feb 4, 2009

Fully configurable personal assistant.
Ah, yes, I hadn't thought of it that way. Thanks.

Gul Banana
Nov 28, 2003

it's a bug in the newer "dotnet" CLI frontend. the underlying problem is described here: https://github.com/dotnet/cli/issues/291#issuecomment-159746824

Mr Shiny Pants
Nov 12, 2012
There should have never been two runtimes......

I can't make heads or tails of it and it seems like there is a lot of confusion about what works and what doesn't.

raminasi
Jan 25, 2005

a last drink with no ice
I have a WPF problem with what I suspect is a simple solution I can't see. I have a TreeView. I want to add a context menu to each item in the TreeView, which I figured out how to do. I want opening the context menu on an item to select that item in the TreeView, which I managed by hooking this handler up to each item:
C# code:
public void TreeViewItem_RightMouseDown(object sender, MouseEventArgs e)
{
    var item = sender as TreeViewItem;
    if (item != null && item.DataContext is LibraryComponent)
    {
        item.IsSelected = true;
    }
}
The problem is that I want some of the commands in the context menu to be enabled or disabled based on which item is selected in the TreeView (which is done via the CommandParameter), but when the selection is changed, the command's CanExecuteChanged is fired before the CommandParameter actually gets updated by the binding engine, so the argument to CanExecute is the previous selection, not the current one. I want selection changed -> CommandParameter updates -> CanExecute fires but I'm getting selection changed -> CanExecute fires -> CommandParameter updates. How can I do what I want?

Inverness
Feb 4, 2009

Fully configurable personal assistant.

GrumpyDoctor posted:

I have a WPF problem with what I suspect is a simple solution I can't see. I have a TreeView. I want to add a context menu to each item in the TreeView, which I figured out how to do. I want opening the context menu on an item to select that item in the TreeView, which I managed by hooking this handler up to each item:
C# code:
public void TreeViewItem_RightMouseDown(object sender, MouseEventArgs e)
{
    var item = sender as TreeViewItem;
    if (item != null && item.DataContext is LibraryComponent)
    {
        item.IsSelected = true;
    }
}
The problem is that I want some of the commands in the context menu to be enabled or disabled based on which item is selected in the TreeView (which is done via the CommandParameter), but when the selection is changed, the command's CanExecuteChanged is fired before the CommandParameter actually gets updated by the binding engine, so the argument to CanExecute is the previous selection, not the current one. I want selection changed -> CommandParameter updates -> CanExecute fires but I'm getting selection changed -> CanExecute fires -> CommandParameter updates. How can I do what I want?
I had a similar issue in a case where each item in a custom property editor control needed to have its context menu customized based on a schema. To do this I gave each item view model its own list of command view models rather than trying to adjust a single context menu instance to fit whatever object is currently selected (this is also because there is no selection concept in this case).

The style I used for the items in the tree.
code:
    <Style x:Key="EditorJTokenViewModelStyle"
           TargetType="{x:Type jecc:PropertyTreeItem}"
           BasedOn="{StaticResource {x:Type jecc:PropertyTreeItem}}">
        <Setter Property="Header" Value="{Binding Name}"/>
        <Setter Property="Content" Value="{Binding Editor}"/>
        <Setter Property="IsExpanded" Value="{Binding IsExpanded}"/>
        <Setter Property="ParentItem">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource ReferenceConverter}">
                    <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type jecc:PropertyTree}}"/>
                    <Binding Path="Parent"/>
                </MultiBinding>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <DataTrigger Binding="{Binding HasMenuCommands}" Value="True">
                <Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu ItemsSource="{Binding MenuCommands}">
                            <ContextMenu.ItemContainerStyle>
                                <Style TargetType="MenuItem">
                                    <Setter Property="Header" Value="{Binding Name}"/>
                                    <Setter Property="Command" Value="{Binding Command}"/>
                                </Style>
                            </ContextMenu.ItemContainerStyle>
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
View model:
C# code:
            MenuCommands.Add(new JTokenCommand("Insert", new DelegateCommand(ExecuteInsert)));
            MenuCommands.Add(new JTokenCommand("Duplicate", new DelegateCommand(ExecuteDuplicate)));
            if (Schema == null || !required)
                MenuCommands.Add(new JTokenCommand("Delete", new DelegateCommand(ExecuteDelete)));

            // Add default types
            JSchemaType types = _schema == null ? SchemaUtility.AnyType : (_schema.Type ?? SchemaUtility.AnyType);

            Action<JSchemaType> addOption = t =>
            {
                if ((types & t) != 0)
                    MenuCommands.Add(new JTokenCommand("Set Type: " + t.ToString(), new DelegateCommand(() => OnSetTypeClick(t))));
            };

            addOption(JSchemaType.String);
            addOption(JSchemaType.Number);
            addOption(JSchemaType.Integer);
            addOption(JSchemaType.Boolean);
            addOption(JSchemaType.Object);
            addOption(JSchemaType.Array);
            addOption(JSchemaType.Null);
Changing it to use IsEnabled instead of excluding the item entirely would be trivial.

Edit: The hacky way I just thought of to do what you want with little change would be to have CanExecute() use the Dispatcher to invoke a method that will invoke RaiseCanExecuteChanged() (or a similar method for your case) on the command at the next opportunity. You'd need to guard for recursion.

I'd want to see how the order of operations here could be changed or fixed somehow, but this is all I can think of off of the top of my head.

Inverness fucked around with this message at 20:52 on Dec 17, 2015

chippy
Aug 16, 2006

OK I DON'T GET IT
Anyone know why a form created with Ajax.BeginForm() might be POSTing twice to the controller when submit is clicked? I've been trying to debug this for ages and it's starting to make me really angry.

e: Googling just seems to turn up suggestions that it's due to accidentally including minified and regular version of the unobtrusive ajax scripts, which I was initially, but I've fixed this now and I'm still seeing the problem.

chippy fucked around with this message at 10:48 on Dec 18, 2015

Mr Shiny Pants
Nov 12, 2012

chippy posted:

Anyone know why a form created with Ajax.BeginForm() might be POSTing twice to the controller when submit is clicked? I've been trying to debug this for ages and it's starting to make me really angry.

e: Googling just seems to turn up suggestions that it's due to accidentally including minified and regular version of the unobtrusive ajax scripts, which I was initially, but I've fixed this now and I'm still seeing the problem.

You sure it is not getting cached anywhere? In Chrome you can purge the cache while debugging.

chippy
Aug 16, 2006

OK I DON'T GET IT
Found it. There was another partial view in the page that was also loading the scripts, don't know why I didn't spot it in the generated HTML.

I've got another question - storing things like connection strings and reCaptcha keys in web.config has always felt kind of insecure to me, but seems to be the recommended approach. Is it considered safe because you need access to the server to view web.config? Or is there some way of securing web.config that I don't know about?

EssOEss
Oct 23, 2006
128-bit approved
It is considered safe because the web server will not let users view that file, yes. Occasionally, if you let marketing people in on the fact, they try to propose some bullshit fake encryption to make it sound more secure and to sell another feature to the customer, but overall nobody has an issue with it in my experience.

ADO.NET does have some feature to encrypt the connection strings in web.config but I have never used it or encountered any situation where it is used, so can't comment on what that does and how useful it is.

Dr. Poz
Sep 8, 2003

Dr. Poz just diagnosed you with a serious case of being a pussy. Now get back out there and hit them till you can't remember your kid's name.

Pillbug

chippy posted:

Anyone know why a form created with Ajax.BeginForm() might be POSTing twice to the controller when submit is clicked? I've been trying to debug this for ages and it's starting to make me really angry.

e: Googling just seems to turn up suggestions that it's due to accidentally including minified and regular version of the unobtrusive ajax scripts, which I was initially, but I've fixed this now and I'm still seeing the problem.

Have you cleared your cache? I mean really got in there and cleared your cache?

chippy
Aug 16, 2006

OK I DON'T GET IT

chippy posted:

Found it. There was another partial view in the page that was also loading the scripts, don't know why I didn't spot it in the generated HTML.

I've got another question - storing things like connection strings and reCaptcha keys in web.config has always felt kind of insecure to me, but seems to be the recommended approach. Is it considered safe because you need access to the server to view web.config? Or is there some way of securing web.config that I don't know about?

Thanks. I only ask because I'm currently doing a website for a paranoid maniac with some very specific requirements regarding security, and it's bound to come up at some point.

chippy
Aug 16, 2006

OK I DON'T GET IT
So here's a weird one: throughout my web.config I have various warnings, the squiggly underlines are under one character only, a whitespace character in a lot of places, and the actual warning text seems completely unrelated to anything in the web.config:



The warnings related to the 3 squiggles you see there are:

"The simpleType 'Infinite_or_int' has already been declared"
"The simpleType 'Infinite' has already been declared"
"The simpleType 'small_boolean_Type' has already been declared"

This is a very standard, simple MVC app in Visual Studio 2015. I've tried cleaning and rebuilding, restarting VS, and I've validated the XML in the document.

Anyone know wtf is going on here?

Calidus
Oct 31, 2011

Stand back I'm going to try science!
Years ago I made a lovely drupal website on an aws micro instance, I don't know enough php do what I want and I don't really want to learn php. Are there any .net CMS that are easy to interact with and expand? I have a couple MVC sites that developed and deployed to IIS. Umbraco seems pretty nice.

EssOEss
Oct 23, 2006
128-bit approved
As someone who has worked for a .NET CMS maker, all .NET CMSes are poo poo. You're better off using Wordpress.

Mr Shiny Pants
Nov 12, 2012

EssOEss posted:

As someone who has worked for a .NET CMS maker, all .NET CMSes are poo poo. You're better off using Wordpress.

I am also coming around to this. Also your users will love for it even though it is a leaky piece of poo poo.

It works really really well.

Uziel
Jun 28, 2004

Ask me about losing 200lbs, and becoming the Viking God of W&W.
I need to get off my butt and get the personal project that I've needed to make started. For it, I need to use Google authentication. Is there an updated guide for doing so? This one is for MVC5.
http://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on

wwb
Aug 17, 2004

EssOEss posted:

As someone who has worked for a .NET CMS maker, all .NET CMSes are poo poo. You're better off using Wordpress.

This.

I've made more .NET CMS apps than any sane person should because there is nothing out there. These days we let the hippies use wordpress as the front end and feed them stuff via web APIs when we have data that matters.

Tax Oddity
Apr 8, 2007

The love cannon has a very short range, about 2 feet, so you're inevitably out of range. I have to close the distance.

wwb posted:

This.

I've made more .NET CMS apps than any sane person should because there is nothing out there. These days we let the hippies use wordpress as the front end and feed them stuff via web APIs when we have data that matters.

I was planning on trying out Umbraco for a project I'm about to start, but now I'm not so sure anymore. What's wrong with it compared to Wordpress or any other, non-.NET cms?

EssOEss
Oct 23, 2006
128-bit approved
This new NuGet stuff is really making me see the advantages of copy-pasting code between projects. What the hell does "XXX is not compatible with .NETPlatform,Version=v5.0." even mean? There does not exist any concept of ".NET Platform" in my universe. Is it what was called .NET Core? Well, even ".NET Core" plays no role in my project - I target two specific environments (.NET 4.6 and UWP), not the .NET Core API surface. I don't even know what overlap some .NET Core API surface might have with my target and I absolutely don't care.

I will describe my scenario here in case it makes sense to someone else. It's very simple: I have a NuGet package for a portable library targeting .NET 4.6 and UWP. The NuGet package contains a folder for both .NET 4.6 and UWP, with the assembly in this folder.

code:
<file src="..\..\Core\bin\release\X.*" target="lib\net46" />
<file src="..\..\Core\bin\release\X.*" target="lib\uap10.0" />
This works fine so far and can be installed into any .NET 4.6 or UWP project. However, today I tried to install it into a portable library project, targeting .NET 4.6 and UWP and got the above-mentioned error message. What the gently caress? I don't know and the only official documentation on nuget.org I can find seems to assume I am a NuGet platform developer, so while the words are in English, the sentences do not translate.

Edit: Now, I *think* that it means "Use lib\dotnet because magic", merely since I saw this advice nicely bolded in the blog post by ljw but that's just a guess from me, really. It seems to fix things but without having seen the blog post referenced in this thread, I would never have thought to try this. I also wonder if it might subtly break some other scenarios? What about interactions with dependencies? It's so inconsistent and full of magic that I have no way to know without just randomly experimenting.

Edit 2: Nope, it's still hosed. For whatever reason, it worked in 2 projects (maybe something was cached?) but now in a 3rd it is not picking up the appropriate assembly references. My NuGet package actually contains both portable and non-portable assemblies and at the moment I am trying to install it into a UWP project and I am expecting it to pick up lib\dotnet (portable) and lib\uap10.0 (nonportable) but it's only picking up the assemblies in the latter directory. This issue also reproduces with a blank UWP app project.

So that's a wasted day! Any suggestions on how I can both support installing into portable libraries (works with lib\dotnet) and still maintain the ability to offer platform-specific code (does not work with lib\dotnet but works with just lib\platform)? Even Lucian's blog post talks about packages targeting specific platforms but it's not only packages that I want to target with, I also want to target specific assemblies in the package to specific platforms!

Edit 3: Oh, what if I combine the both approaches? Success! So I need to put the portable library in lib\dotnet, lib\net46 and lib\uap10.0. This is what I mean by only being able to find solutions via experimenting. I have no idea what the logic behind this is, all I know that it works and I have no idea if maybe the next NuGet update will break it.

EssOEss fucked around with this message at 13:27 on Dec 21, 2015

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost
I got a question about cookie containers when using HttpClient.

I'm doing a little rewrite of my SA Forum Library. In order to log in, I need to post a form to Account.php, the same as the website does, so I can get the authentication cookies. This works the first time a user submits their login info; the cookie container has three cookies on the response, which I can store and use again. But if they try logging in again, while I do get the same successful response, the cookie container is empty! I checked with fiddler, and the response DOES have cookies with the password in it.But for whatever reason, the cookie container does not have any in it.

At first I thought I needed to do the actual logout flow, so I implemented that as well, so now when you "logout" it not only removes the cookie files from the isolated storage but calls SA and removes them there too... but it still fails. If you try and log in again, the cookie container will be empty. The only way to log in again is to remove and reinstall the app.

I assume I'm missing something very basic. Here is the code for what I'm doing. Any ideas?

ljw1004
Jan 18, 2005

rum

EssOEss posted:

Edit 3: Oh, what if I combine the both approaches? Success! So I need to put the portable library in lib\dotnet, lib\net46 and lib\uap10.0. This is what I mean by only being able to find solutions via experimenting. I have no idea what the logic behind this is, all I know that it works and I have no idea if maybe the next NuGet update will break it.

I feel+share your pain. What you've discovered is the correct intended supported way of doing things.


Here are some notes:

quote:

The NuGet package contains a folder for both .NET 4.6 and UWP, with the assembly in this folder. This works fine so far and can be installed into any .NET 4.6 or UWP project. However, today I tried to install it into a portable library project, targeting .NET 4.6 and UWP and got the above-mentioned error message. What the gently caress?

The deal is that .NET46 platform has API surface area "A", while UWP platform has API surface area "B", and your PCL has API surface area "A intersect B".

The fact that you wrote your NuGet package with one DLL that stays within "A", and potentially a different DLL that stays within "B", isn't enough for NuGet to know that it has any DLL in hand that can stay within "A intersect B". That's why it refused.


quote:

My NuGet package actually contains both portable and non-portable assemblies and at the moment I am trying to install it into a UWP project and I am expecting it to pick up lib\dotnet (portable) and lib\uap10.0 (nonportable) but it's only picking up the assemblies in the latter directory

There's some NuGet behavior that in my mind is really confusing. If you're writing an app or a regular class library, then it prefers the lib folder that matches that platform, e.g. a UWP class library will prefer "lib\uap" over "lib\dotnet". If you're writing a .NET46/UWP/ASP.NET5 PCL then it will prefer "lib\dotnet" over anything else. If you're writing any other kind of PCL then it will prefer "lib\portable-xyz". Maybe you ran into this?


quote:

Oh, what if I combine the both approaches? Success! So I need to put the portable library in lib\dotnet, lib\net46 and lib\uap10.0

That's right. It's weird isn't it how you have to put the exact same file into so many different places to work around the confusing rules. I also got bitten because NuGet used to have a rule that it would pick up files in "lib\*.dll" if there was no subdirectory that provided a better match, and I wrote my packages this way to avoid duplication, but then they removed this ability so now you have to have lots more duplication.

Myself I'm currently working a bit on C++ native packages in NuGet for UWP. I've tried to piece this together by looking at the structure of "win2d". I managed to put OpenCV into NuGet packages in a format consumable by UWP apps:
http://blogs.msdn.com/b/lucian/archive/2015/12/04/opencv-first-version-up-on-nuget.aspx

ljw1004
Jan 18, 2005

rum

Drastic Actions posted:

I got a question about cookie containers when using HttpClient.

I'd start by attempting the exact same code in a desktop app and seeing if you get the correct behavior. That's because HttpClient was completely rewritten from scratch for UWP. I know there are some differences around authentication. Maybe also around cookies.

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

ljw1004 posted:

I'd start by attempting the exact same code in a desktop app and seeing if you get the correct behavior. That's because HttpClient was completely rewritten from scratch for UWP. I know there are some differences around authentication. Maybe also around cookies.

I wrote a Test console and UWP showing what's going on. And I think I figured out what happened after doing some more googling. System.Net.Http.HttpClient is a wrapper for Windows.Web.Http.HttpClient.

If you run the console project and log in, you'll get five cookies on the return response: Some random id, the session hash, an ad hash, a user id and password. In the UWP app, the same code will get you three cookies, without the user id and password. Now, that's weird, because the user id and password is what's used to auth you to the forums. I was serializing and saving the wrong cookies! So how in the hell did auth work before? Well, there is ANOTHER cookie manager which DOES have those missing cookies, and they would be sent with every subsequent request without me setting them myself (I made sure of that using fiddler).This explains why the only way to actually "log out" is to delete the app. Because I was never deleting the authenticated cookies to begin with.

You can find all of the cookies by creating a HttpBaseProtocolFilter, which has a cookie manager. This can get you all cookies stored (as long as you know the domain URI), and there I can delete all SA cookies (including the user id and password ones). Apparently this is on a per-app basis. When I made a new login request, I got the three session hash cookies and the user id and password cookies were reset.

I'm seriously going :psyduck: here. Why did it not give me those two cookies in the cookie container, and hide them from me? They are not marked special in the request as far as I can tell. Why does it show some cookies in the cookie container, and not others? Well, at least I can actually log users out now :v:.

EssOEss
Oct 23, 2006
128-bit approved

ljw1004 posted:

There's some NuGet behavior that in my mind is really confusing. If you're writing an app or a regular class library, then it prefers the lib folder that matches that platform, e.g. a UWP class library will prefer "lib\uap" over "lib\dotnet". If you're writing a .NET46/UWP/ASP.NET5 PCL then it will prefer "lib\dotnet" over anything else. If you're writing any other kind of PCL then it will prefer "lib\portable-xyz". Maybe you ran into this?

Yeah, that does indeed seem to be the case.

ljw1004 posted:

Myself I'm currently working a bit on C++ native packages in NuGet for UWP. I've tried to piece this together by looking at the structure of "win2d".

Hah, that's exactly the package I used as my first example on how things work back in September. I don't know what I would have done without win2d! Reverse engineer NuGet code, I suppose. Oh wait, I actually did have to do that, too.

I think I will try to do a summary writeup of my NuGet knowledge in some public website (Stack Overflow, I guess), given that your blog post is the only sensible source of documentation in existence so far. More info out there will help the next guy get through the muck faster, for sure.

EssOEss fucked around with this message at 08:06 on Dec 22, 2015

EssOEss
Oct 23, 2006
128-bit approved
I solved a long-time mystery that had been bothering me. gently caress whoever designed that API.

AdaptiveMediaSource at least seems quite sensible.

EssOEss fucked around with this message at 14:37 on Dec 22, 2015

chippy
Aug 16, 2006

OK I DON'T GET IT
So, as I mentioned a few days ago I'm doing a website for someone with some quite specific security requirements. Specifically, as well as hashing passwords, he also wants email addresses hashed, and full names encrypted (all using his own hand-rolled algorithms, naturally). No personal details stored in plaintext, basically.

I don't know a huge amount about the built-in ASP.NET Identity stuff, so I'm currently doing some reading to try and work out if it's going to be possible to massage it into supporting this stuff. Is anyone else able to quickly tell me if it's going to be, or if I should give up and think about implementing all this poo poo manually (please god no)?

chippy fucked around with this message at 18:08 on Dec 22, 2015

Finster Dexter
Oct 20, 2014

Beyond is Finster's mad vision of Earth transformed.

chippy posted:

So, as I mentioned a few days ago I'm doing a website for someone with some quite specific security requirements. Specifically, as well as hashing passwords, he also wants email addresses hashed, and full names encrypted (all using his own hand-rolled algorithms, naturally). No personal details stored in plaintext, basically.

I don't know a huge amount about the built-in ASP.NET Identity stuff, so I'm currently doing some reading to try and work out if it's going to be possible to massage it into supporting this stuff. Is anyone else able to quickly tell me if it's going to be, or if I should give up and think about implementing all this poo poo manually (please god no)?

I don't think hashing that stuff is going to be all that hard to do in ASP.NEt Identity. Just write a custom UserStore that implements the interfaces you need and have some wrapper code around your persistent storage layer, etc. etc.

The part that makes me leary is when people "roll their own" encryption. Unless they REALLY know what they're doing, and I mean REALLY... i.e. have written papers on breaking encryption algorithms, I'm going to strongly recommend against using their own encryption/hashing algorithms.

chippy
Aug 16, 2006

OK I DON'T GET IT

Finster Dexter posted:

I don't think hashing that stuff is going to be all that hard to do in ASP.NEt Identity. Just write a custom UserStore that implements the interfaces you need and have some wrapper code around your persistent storage layer, etc. etc.

The part that makes me leary is when people "roll their own" encryption. Unless they REALLY know what they're doing, and I mean REALLY... i.e. have written papers on breaking encryption algorithms, I'm going to strongly recommend against using their own encryption/hashing algorithms.

Thanks, I thought a custom UserStore was probably going to be the way to go.

I am absolutely, 100% with you regarding the encryption stuff, and I tried to steer him away from that but he's pretty obstinate on the issue. The be fair I was only really concerned about his password hashing but I had a look at his code and it's really just wrapping the .NET libraries so I think it's fine. The encryption is only being used for stuff that normal people wouldn't bother encrypting anyway, so I can't be arsed to argue with him on that.

amotea
Mar 23, 2008
Grimey Drawer
Can we please get a friendlier covariance/contravariance system for generics? It's getting more and more annoying with new features like async/await, Rx etc.

This is just an example of unnecessary casting, and it'd be worse if I couldn't use interfaces:

code:
public Task<IImmutableList<IFoo>> GetFoos() {
    if (true)
        return Task.FromResult((IImmutableList<IFoo>)ImmutableList.Create<IFoo>(new[] {new Foo()}));

    return retrieveFoos();
}
I get the feeling everyone knows it's annoying but no-one says anything because at StackOverflow they'll be very happy to tell you that the system is perfect as it is because it prevents you from mixing Monkeys with Elephants in a list of Animals god forbid.

There are lots of annoying cases and I don't have the time to write them all down but I wonder if anyone feels the same way? Maybe I should propose a change at GitHub, but I probably don't stand a chance.

brap
Aug 23, 2004

Grimey Drawer
I'm not sure you're understanding C#'s limitations around array covariance correctly.

Say we have some classes.
code:
public class Foo { }
public class Bar : Foo { }
public class Baz : Foo { }
What C# prevents you from doing is

code:
List<Foo> foos = new List<Bar>();
It has no problem with

code:
List<Foo> foos = new List<Foo>();
foos.Add(new Bar());
foos.Add(new Baz());

raminasi
Jan 25, 2005

a last drink with no ice
Yeah I'm not sure why you think that cast is unnecessary; I wouldn't want the compiler magically turning Task<ImmutableList<IFoo>> into Task<IImmutableList<IFoo>>,

Sedro
Dec 31, 2008
It seems reasonable to me. Task<T> and ImmutableList<T> are both (conceptually) covariant so Task<ImmutableList<Foo>> should implicitly convert to Task<IImmutableList<IFoo>>.

Gul Banana
Nov 28, 2003

at the very least it should be able to infer the cast from the return type of the method

you've got an expression which can be contextually typed as Task<IImmutableList<IFoo>>, and there's an overload of FromResult which produces that, as long as you have an inner contextual type of IImmutableList<IFoo>, and then the actual inward-out expression type implements that very interface.. this is all doable stuff

it's not exactly trivial to implement, but similar languages have got it working (scala comes to mind)

ATM Machine
Aug 20, 2007

I paid $5 for this
So I've a weird problem come up concerning MVC routes. Basically I've got a phantom route floating around that's active and will return a 500 indicating that there's a route registered somewhere, but no controller exists for this route anymore, and won't display a server error on debug, so it's not hitting an error handler. If I create a controller for that route and breakpoint it, it won't be hit, and no exceptions will be thrown anywhere.

It's not an issue as the route is only known about in dev, but I know I've run across this issue before. The routes are defined with attributes, and are within an area. I'm thinking it's some weird MVC thing with [RouteArea("...")] in combination with [Route("...")], but with no way to find out where it's lingering I've no way of solving the issue if it happens for another route later on.

However, if I add a trailing slash to that route, the controller will be called, and it'll behave as it should. Remove the route and it'll return a 404, remove the trailing slash and it'll 500 as if it's still hitting a controller somewhere.

I've done clean rebuilds, deleted the obj folder, cleared the routetable on startup, nothing has worked to get rid of it. At this point I'm wondering if anyone else has had this happen, or if it's just me.

ljw1004
Jan 18, 2005

rum

amotea posted:

Can we please get a friendlier covariance/contravariance system for generics? It's getting more and more annoying with new features like async/await, Rx etc.

There are lots of annoying cases and I don't have the time to write them all down but I wonder if anyone feels the same way? Maybe I should propose a change at GitHub, but I probably don't stand a chance.

Your example of Task<Foo> cast to Task<IFoo> is a reasonable and good request. Indeed Bart de Smet, one of the two creators of RX, wrote exactly the same here: https://github.com/dotnet/roslyn/issues/7169#issuecomment-161446072

The thing is that the CLR only supports co/contravariance for interfaces, not for types. When we implemented async/await we discussed whether we should invent a new interface "ITask<T>" for async methods to return. On the PRO side, this interface could be covariant and wouldn't have synchronous members like .Result or .Wait. On the CON side, it'd be weird as heck to have a vast set of library methods that work with "Task", and then a whole bunch of other things that work with "ITask". We thought the CONs narrowly edged out the PRO.

I'd like to see a change where async methods are allowed to return any user-defined type, not just "Task". This would let you return an ITask if you wanted. It'd also let you return a value-type Task if you wanted to avoid heap allocation. The first prototype I implemented of async/await allowed arbitrary return types exactly like this. However we couldn't figure out how to combine it in full generality with type inference and so scrapped it.

I have a proposal on the boards to remedy this, to let you return arbitrary used-defined types from async methods. I hope it will get into C#7.
https://github.com/dotnet/roslyn/issues/7169



More generally, you asked for a "friendlier co/contravariance". There is another proposal to allow covariance in return types:
https://github.com/dotnet/roslyn/issues/357



But as to whether we could make them truly friendly, and relax the CLR rules so it now allowed co/contravariance for types and not just interfaces? Sorry, I don't think this will ever happen. It'd be nice sure. But it'd be a truly large amount of work in the CLR, and the benefits seem proportionately small.

amotea
Mar 23, 2008
Grimey Drawer
Thank you for this nice reply to my angry developer style post. I'll definitely have a look at the links you posted when Christmas is over. :)

Begall
Jul 28, 2008
So I've tried to pick up C# to play around with, and the first thing I did was try to create an example web service. I did so by creating a new web site project in VS 2015 Community, and then adding a Web Service (ASMX) item to it, which then runs on IIS Express. Once I do this, I'm able to access the base URL e.g. http://localhost:50793/WebService1.asmx, and even click through onto the Hello World placeholder method or any other method I define e.g. http://localhost:50793/WebService1.asmx?op=HelloWorld.

But when I try to actually invoke the web service i.e. with a POST call to http://localhost:50793/WebService1.asmx/HelloWorld, I get a 404 error returned. The IIS log looks like this:

code:
#Software: Microsoft Internet Information Services 10.0
#Version: 1.0
#Date: 2015-12-29 14:55:13
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken
2015-12-29 14:55:13 ::1 GET /WebService1.asmx - 50793 - ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/47.0.2526.106+Safari/537.36 - 200 0 0 6598
2015-12-29 14:55:13 ::1 GET /favicon.ico - 50793 - ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/47.0.2526.106+Safari/537.36 [url]http://localhost:50793/WebService1.asmx[/url] 200 0 0 2
2015-12-29 14:55:13 ::1 GET /__browserLink/requestData/06e295226c6a40d5b659f6f0c8c6588e version=2 50793 - ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/47.0.2526.106+Safari/537.36 [url]http://localhost:50793/WebService1.asmx[/url] 200 0 0 37
2015-12-29 14:55:14 ::1 GET /WebService1.asmx op=HelloWorld 50793 - ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/47.0.2526.106+Safari/537.36 [url]http://localhost:50793/WebService1.asmx[/url] 200 0 0 15
2015-12-29 14:55:14 ::1 GET /__browserLink/requestData/8eb8f3ce524e495e9d238f5b05df2e73 version=2 50793 - ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/47.0.2526.106+Safari/537.36 [url]http://localhost:50793/WebService1.asmx?op=HelloWorld[/url] 200 0 0 4
2015-12-29 14:55:15 ::1 POST /WebService1.asmx/HelloWorld - 50793 - ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/47.0.2526.106+Safari/537.36 [url]http://localhost:50793/WebService1.asmx?op=HelloWorld[/url] 404 0 0 61
2015-12-29 14:55:36 ::1 POST /WebService1.asmx/HelloWorld - 50793 - ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/47.0.2526.106+Safari/537.36 [url]http://localhost:50793/WebService1.asmx?op=HelloWorld[/url] 404 0 0 3
I followed the tutorial here, although the above example I cut it back to just creating a default (WebService1) and trying to call the placeholder method without any further success. At this stage I'm not sure if the problem is the code, IIS or a setting in VS. Any ideas?

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
This is kind of lovely since it's dodging your question entirely, but my recommendation is to avoid web services if you're just starting out with C#. They are basically legacy now and there's no real reason to start a new project with one these days. If you're trying to make something web accessible, then I'd recommend looking into ASP.NET MVC and Web API. The tutorials over at http://www.asp.net/web-api are decent enough to get started.

Adbot
ADBOT LOVES YOU

raminasi
Jan 25, 2005

a last drink with no ice
I'm having a weird AutoMapper problem. Mapper.AssertConfigurationIsValid() succeeds, but all my actual mappings are failing with "Missing type map configuration or unsupported mapping." As an example: I'm mapping a Source.GlazingMaterial to a Destination.GlazingMaterial, but the mapper, in a child mapping, then tries to map the source object itself to an Int32 field, which obviously fails. I don't know which one, because neither type even has any Int32 fields. Something like this is happening with every type - the mapper tries to map the source object itself to a field on the destination object (which may not even exist). Calling Mapper.Reset() before establishing my mappings doesn't fix the problem. Is there any way to ask AutoMapper wtf it thinks it's doing?

e: When the exception is thrown, AutoMapperMappingException.Context.MemberName is empty. That seems...wrong.

raminasi fucked around with this message at 21:52 on Dec 29, 2015

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply