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
Che Delilas
Nov 23, 2009
FREE TIBET WEED
I realize this is :can:, but does anyone have any strong opinions on commenting style for ASP.NET MVC Controller Action header comments specifically?

For example, I have an action:

C# code:
[HttpGet]
public ActionResult Products()
{
   return View(dbContext.Products.ToList());
}
What information should I be adding in the header comments? I know the standard advice is to talk about why things are being done this way, but "displays products because people want to see products" is akin to "assigns the number 5 to the integer variable called myNumber."

Please don't fight with each other over this. :shobon: I'm less interested in the "right way" as I am just learning what other people do in these situations.

Che Delilas fucked around with this message at 00:38 on Nov 29, 2014

Adbot
ADBOT LOVES YOU

Che Delilas
Nov 23, 2009
FREE TIBET WEED

bpower posted:

http://msdn.microsoft.com/en-us/library/system.web.mvc.html.linkextensions_methods(v=vs.118).aspx

As a learning tool thats bloody awful. Where do you guys go to learn about the small things? I seem to just bounce around the web looking for examples.

Stackoverflow is usually pretty good, though they close "best practices" or opinion questions; they're not interested in discussion. Codeproject can have some decent tutorials. Don't expect them to be up-to-date on everything, but they can be a good overview and starting point. Usually googling your specific issue or question will get you something from one or both of those sites first thing.

Che Delilas
Nov 23, 2009
FREE TIBET WEED
Thanks guys, got some good viewpoints.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Bognar posted:

And, really, you mustn't.

Yeah I mean, that's the obvious "function header comment just to have one" type of comment. I couldn't think of anything novel to put there, especially since it's for a Controller class and not a library I'm going to distribute or something. Good to know I don't really need to bother in cases like that.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

bpower posted:

Im building a mvc .net site that will hold sensitive information. Is the latest User Identity stuff you get out of the box good enough as it is?

http://stackoverflow.com/questions/20621950/asp-net-identity-default-password-hasher-how-does-it-work-and-is-it-secure
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes%28v=vs.110%29.aspx

There's some reading material for you on how it handles passwords. You or someone in your organization will be better equipped to analyze that against your specific requirements than I am.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

gariig posted:

With all of this unit testing talk if you want a book on it The Art of Unit Testing is excellent and I highly recommend it.

I've been meaning to ask this: does this book go into a deep dive of the entire TDD process too, or does is it just concerned with teaching you how to write good unit tests in a vacuum?

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Canine Blues Arooo posted:

Than it will load as a green dot, as it should. But anything that happens after Run() is called is no bueno. I just want to change the picture in a picture box on a button click! This has got to be really simple. What the gently caress do I do!?!?

I'm assuming this is in WinForms? You need to make an event handler to process your button's Click event.

If you're in the design view, the quickest way to do this is just double-click on the button in question, and Visual Studio will automagically create the function stub for you. It'll look something like this:

C# code:
private void button1_Click(object sender, EventArgs e)
{

}
The "button1" part comes from the name of the button. You'll want to call whatever color-changing function you have from within this event handler function, like so:

C# code:
private void button1_Click(object sender, EventArgs e)
{
    changeNtpStatus(1);
}
That's all you should have to do to get it to function the way you want. To actually understand what's going on under the hood (and you should endeavor to), you'll need to go a little deeper, specifically the topics of Events and Event Handlers.

http://msdn.microsoft.com/en-us/library/dd492171.aspx Is a set of basic WinForms tutorials that looks pretty good. #1 has you write button click event handlers the way I told you about, and #2 goes a little deeper into events and shows you where they're attached to the controls that generate said events.

----

Also on a more personal note, stop getting down on yourself for not getting this right away. Windows GUI programming has a lot of extra baggage and complexity attached to it which does a fantastic job of muddying the waters when you're just trying to learn basic programming concepts. It can be difficult to teach yourself because dozens of little things have to be correct, and if you don't know several of them at once, it's hard to know where you're going wrong or what you're missing. Just keep asking questions when you don't understand something (and frankly, get comfortable with not understanding things - the more you learn about programming, the more you realize just how much there is that you don't know.)

Che Delilas
Nov 23, 2009
FREE TIBET WEED
Yeah, you're passing in the form to your createHash function, which reeeealy shouldn't be necessary. Can you show us where you're calling createHash?

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Canine Blues Arooo posted:

I realize I cannot actually create a new form object here (in the Hash class) and expect it to change the existing form's state, but I think this at least clearly illustrates what I want to accomplish.

Added stuff in bold. This is correct, you can't do that. But you are also doing it in your Reporting class:
code:
internal class Reporting
{
    private main form = new main();
    //Snip
    reportID += hash.createHash(form);
}
Like you said, you can't create that second form and expect it to change anything on the calling form.

----

Beyond that, as forgall mentioned you really, really shouldn't be changing the state of your UI outside of your form. WinForms is bad about letting you separate display logic from other logic, but at the very least, your form class should be manipulating the color of the picture box based on the results of the other classes, not letting those classes do it.

Something like this:

C# code:
public partial class main : Form
{
  //Snip
  private void createReport_MouseClick(object sender, MouseEventArgs e)
        {
            Reporting report = new Reporting();
            
            //Indicate reporting has begun
            changeNtpStatus(YELLOW);
            
            try 
            {
               report.run();
            }
            catch (Exception ex)  //Failure
            {
                 //Log ex.Message or whatever

                changeNtpStatus(RED); //Indicate Failure
                return;
            }
            
            //Indicate Success
            changeNtpStatus(GREEN);
        }
//Snip
}
Then remove everything having to do with changing controls or otherwise manipulating the UI from your Reporting and Hash classes. It does not belong there.

Probably a good idea to explicitly try/catch/rethrow the exception within your Reporting.GenerateReport() method too, but it should bubble up either way.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

EssOEss posted:

If you are using a library that is not async-aware then no, it is not possible to make it meaningful in an async scenario. I think the approach you use is OK in this case, assuming that you actually do need it to happen in the background.

At some point you (meaning any developer) will need to be able to achieve concurrency with their lowest-level functions though, right? I mean, the be-all and end-all of async isn't "use the magic methods in MS-provided libraries or gently caress off." Right? I'm not being snide here, I'm still trying to get a handle on async and its ilk.

Like, in bobua's case, his lowest-level method would look like this:

C# code:
public Task SaveMyFile(string fileName)
{
    await Task.Run( () => MyIImageObject.Save(fileName) );  //Send the misbehaving, non-async-aware method off to the thread pool
}
And then he can await up the rest of the call graph as far as it goes. Am I doing this right? I mean, I know that Task.Run will shunt the work off to a pooled thread, which is not the same as releasing execution to the caller while the I/O operation completes and therefore is not ~~True Asynchrony~~ but if a library or method doesn't behave itself in this fashion, it's up to us to tell it to go sit in the corner until it's done. Right? At least the pooled threads avoid most of the overhead associated with creating a new thread.

I'd really appreciate some words on this from someone who has some real experience with async, because this is one of those sticking points that's preventing everything from really clicking in my head.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

ljw1004 posted:

Okay, here's the definitive answer from the .NET team:

:words:

That's really, hugely, fantastically helpful to me, thank you.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Bognar posted:

You would still be able to handle 1000 concurrent requests in this situation since the method awaiting Task.Run is suspended, so another thread can handle another request. You still haven't gained anything by using Task.Run, but you haven't cut your performance in half either (assuming you're using a synchronous method).

Does the main thread of an application come from the thread pool too?

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Bognar posted:

EDIT: Unless by "main thread" in a server scenario, you mean the thread handling the initial request and not the thread used by Task.Run. In that case, yes, that thread is coming from a thread pool (though not necessarily the ThreadPool class) to avoid the expensive build-up and teardown of threads.

Yes, this is what I meant with my question. You said this:

quote:

You would still be able to handle 1000 concurrent requests in this situation since the method awaiting Task.Run is suspended
and I was trying to get a picture in my brain of what would be happening in this scenario. Since the method awaiting Task.Run would be run on a pooled thread, suspending it while waiting for the Task.Run operation to complete would free up a bit of the pool, as you said.

I wasn't disbelieving you, by the way, I'm just trying to get a solid handle on this, and it's difficult when the very nature of the subject is so twisty.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

bpower posted:

Ok there's nothing inherently wrong with the UoW pattern or the repository pattern, but a lot of people, you included, have pointed out its a needless abstraction of EF.

Right, basically isn't the DbContext a Repository and a Unit of Work already?

Che Delilas
Nov 23, 2009
FREE TIBET WEED

RICHUNCLEPENNYBAGS posted:

Yeah, instead, just an extra opportunity to gently caress up naming it.

Hey, ~/Catalog/Porducts/105 is a perfectly legitimate route and won't make people think less of your business at all!

Che Delilas
Nov 23, 2009
FREE TIBET WEED

RICHUNCLEPENNYBAGS posted:

If configuring it doesn't count as "controlling" it then I don't think we're in agreement about what "control" means.

The problem is that, inevitably, you're going to end up wanting to do more stuff that requires talking directly to EF (like, say, doing some Include statements) and eventually it's not really much an abstraction at all (it's half talking to EF and half to the wrapper and your wrapper gradually accumulates the same list of methods as DbContext). I kind of regret doing this even though it does make testing a bit easier.

The whole "testable" thing really bugs me as a reason to go through all these double-abstraction-layer gymnastics. I have an MVC project where I have a service (the generic, business-logic-goes-here form of the word, not a web service or something) that gets the DbContext passed to it through its constructor. The service does a thing with the database. I want to unit test the functionality of the service methods without needing that database.

My DbContext looks like this:

C# code:
class MyDbContext : DbContext
{
    public virtual IDbSet<Boat> Boats {get; set;}
    public virtual IDbSet<Plane> Planes {get; set;}

    //...etc
}
To unit test my service (which again, takes a MyDbContext as a parameter in its constructor so it can talk to the database), I do this:

C# code:

[TestMethod]
public void Service_Does_A_Thing()
{
  var testboats = new List<Boat> { /* create some dummy boats here */ }.AsQueryable();
  var testplanes = new List<Plane> { /* create some dummy boats here */ }.AsQueryable();

  //Create the mock sets (using Moq)
  var boatSetMock = new Mock<IDbSet<Boat>>();
  boatSetMock.Setup(m => m.Provider).Returns(testboats.Provider);
  boatSetMock.Setup(m => m.Expression).Returns(testboats.Expression);
  boatSetMock.Setup(m => m.ElementType).Returns(testboats.ElementType);
  boatSetMock.Setup(m => m.GetEnumerator()).Returns(testboats.GetEnumerator());

  boatSetMock.Setup(m => m.Add(It.IsAny<Boat>())).Callback((Boat b) => testboats.Add(b));
  boatSetMock.Setup(m => m.Remove(It.IsAny<Boat>())).Callback((Boat b) => testboats.Remove(b));
  
  //Do the same thing for the Planes mock set
  ....

  //Create the mock DbContext
  var dbContextMock = new Mock<MyDbContext>();
  dbContextMock.Setup(m => m.Boats).Returns(boatSetMock.Object);
  dbContextMock.Setup(m => m.Planes).Returns(planeSetMock.Object);

  //Mocks are done, test the actual service
  var svcUnderTest = new MyService(dbContextMock.Object);

  var result = svcUnderTest.DoAThing();

  Assert.IsTrue(result.ThingDidSuccessfully, "Thing not did successfully!");
}
So what I'm basically doing is mocking out the internals of MyDbContext (the IDbSets) instead of mocking out an abstraction of MyDbContext itself, which moves the ugliness into my unit testing code instead of spraying it all over my production code.

I'm really, really not an expert at any of this; if someone notices that this code will do something horrifying, please speak up. The tests appear to work doing things this way, and operate only on the test data I've given them, but they could be touching things they aren't supposed to (one specific concern I have is if mocking a concrete DbContext class, as in new Mock<MyDbContext>(); still expects a database to be there, even if all of its IDbSets are mocked. This is just me not knowing enough about how EF works under the hood).

Che Delilas
Nov 23, 2009
FREE TIBET WEED

bpower posted:

Is the bolded stuff some internal methods needed to call add and remove? If so, aren't you heavily coupling the test to the implementation? I'm learning about TDD at the moment. There seems be be no consensus on really fundamental issues.

I'm pretty sure that the code you bolded is what is necessary to perform LINQ queries on an IDbSet if you want the IDbSet to point to somewhere other than where the DbContext specifies (in this case I'm pointing to the in-memory testboats List that I created for this test method, instead of a database somewhere).

It still feels hinky, especially since I'm not mocking out every method in the interface. http://msdn.microsoft.com/en-us/library/gg679233%28v=vs.113%29.aspx I really wish there was an obvious approach to this whole repository/uow + unit testing thing, because it really makes me scratch my head.

quote:

My solution is to create a local test version of my db. I fill it with test data in a similar way to the Seed method in EF migration. All my tests assume the db is in exactly its starting state. they can add data and read it back if they want, but they must try to delete that data first and at the end o ensure the tests are atomic. The test db is pretty empty, its has all the lookups , a few users of each type needed in the tests. a few typical entities that can be reused for many tests.

This idea just rubs me the wrong way. There just has to be a decent way to completely short-circuit the need for a database at all for the purposes of unit testing, but without having an otherwise completely redundant abstraction on top of your DbContext.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

bpower posted:

Me too! But I don't know why. If speed was no issue whatsoever whats the difference between creating an in memory mock and having a test db on disk, or more likely several dbs on disk that the relevant tests point at. We both have to maintain test data. EF can keep all dbs structurally in sync.

I mean, the point of unit testing is to test something in isolation. I want to be able to test some complicated algorithm on its own whether I have access to a database or not; I care about the operation of the algorithm and nothing else.

But you make a good point; I mean in what situation, realistically, are we going to have access to our development machine, the source code we're testing, and our unit testing project and code, but not have access to at least some kind of database system that EF can connect to to get dummy data? Any dev box or CI server worth the name is going to have something available to serve that function. Maybe this is one of those cases of everyone (okay, me) getting caught up in the ~perfect theoretical form~ of a thing, when a little bit of concession to reality would make things a lot simpler for the vast majority of cases.

(As an aside, anyone else ever find themselves wishing that Microsoft had called their stupid Access program anything else at all? Every time I have a conversation that involves databases, my brain twitches just a little bit when the inevitable phrase "access to the database" comes up. They could called it anything else that doesn't imply "availability and permission," but nooOOOooo.)

quote:

Why aren't we mocking System.IO.File?

Well, I wouldn't mock this one specifically, because if I had a method that created a file as part of its operation, I would want to make sure that file actually got created. I've had enough minor trouble caused by file permissions issues, thanks very much :v:. But I know that's sort of beside the point you're making.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Oh, you're Lucian Wischik? Your async tips and tricks videos, particularly the first three, really helped me get a handle on Async (at least, they got me past the first hump which was understanding the program flow when async and await are in play). Great stuff.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Bognar posted:

Probably removing all the obscenities.

Don't forget that they have to split off all the spyware functionality into separate modules so we can't confirm it exists. :tinfoil:

Che Delilas
Nov 23, 2009
FREE TIBET WEED

UberJumper posted:

Does anyone have suggestions for how to name unit testing methods? We started a new project and since are testing guy recently left i am taking over his spot temporarily.

Everything i see seems to have insanely long method names.

ShouldDoAThingUnderCondition, basically, which yeah results in long method names. The method names are basically sentences that tell you what you should expect, so that when you run a hundred of them at once and one fails, you can see more or less at a glance exactly how the method under test is failing without going into the test method. In theory, anyway.

ShouldThrowExceptionWhenGivenProductIdDoesNotExist(), for example.

You don't have to do it that way, it's just a descriptive name. It's not like you're going to be calling that function from elsewhere in your program, so it's not polluting your code.

Che Delilas fucked around with this message at 23:00 on Feb 26, 2015

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Inverness posted:

"Xbox, show me something awful."

I don't understand, why does it just keep showing me the Xbone home screen?

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Ithaqua posted:

Doing it right requires a culture change, plain and simple.

In other words, if you're now the "Lead Test Developer" and they want to do unit testing right, from scratch, propose this culture change as a part of your new set of responsibilities (after doing research about what exactly that entails). Don't just start being the one guy who writes unit tests. Propose the change to your entire development process that everyone needs to buy into.

Might not work, but if it does you'll get some great experience and bragging rights out of it.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Dreadrush posted:

If you want to post to an action with a parameter like IEnumerable<Thing>, then MVC's modelbinder will read back form values with name attributes like:
"[0].ThingName"
"[1].ThingName"
"[2].ThingName"

I don't think that's the hangup (I mean, it might be, the question is vague enough that I don't know if he understands the model binder or if he's just having trouble figuring out how to distinguish between the view and the model with his entities).

bpower, I assume your html view has something like @model IEnumerable<Thing> at the top.

The problem is, Thing is (presumably) an entity that you're storing in a database, and there's no place for a "user wants this deleted" field in the Things table because "being deleted" is not part of a Thing, it's just something the user wants to do to the Thing.

What you want is to create a new class to use as your @model, we call this kind of class a ViewModel.

C# code:
public class DeleteThingViewModel
{
  public Thing Thing {get; set;]

  [Display(Name="Delete")]   //This is what you want Html.DisplayNameFor to use
  public bool IsMarkedForDeletion {get; set;]
}
And in your view, instead of @model IEnumerable<Thing>, it would be @model IEnumerable<DeleteThingViewModel>. That way, you still have a list of Things so that you can display them, but you have that extra bit of information in the form of IsMarkedForDeletion for each item so that your controller can process them in the HttpPost action when the user submits the form. And as Dreadrush said, you do need to include the Id or whatever unique identifier a Thing uses, by using a <hidden> tag or @Html.HiddenFor helper.

The only other sticking point here is that when you have a nested complex class like that, the @Html.DisplayNameFor helper won't work as you have it written; you will have to use an index if you want the compiler to figure it out (basically what it's doing under the hood by default as far as I know, it's just not smart enough to deal with the nested class). Like this:

code:
          <thead>
                <tr>
                    <th>@Html.DisplayNameFor(m => m[0].Thing.ThingName)</th>
                    <th>@Html.DisplayNameFor(m => m[0].Thing.ThingType)</th>
                    <th>@Html.DisplayNameFor(m => m[0].Thing.ThingCount)</th>
                    <th>@Html.DisplayNameFor(m => m.IsMarkedForDeletion)</th> 
                </tr>
            </thead>

Che Delilas
Nov 23, 2009
FREE TIBET WEED

fleshweasel posted:

code:
public Thing Thing {get; set;]
This makes me hate C# conventions so much.

It bothers me a little but I don't much like underscores before variable names or putting "My" in front of everything either. Pick your poison.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

RICHUNCLEPENNYBAGS posted:

That isn't a problem. They specifically designed the language to accommodate the "Color Color" problem where the most sensible name for a field is also the class name.

I see a few rules codifying private fields, but no mention of public properties in that style guide (I use camel for private fields so those are never confusing). Properties are Pascal case pretty much anywhere I've ever seen, that's why it's a problem at all.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Oh whoops, conflated you and another poster.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Scaramouche posted:

Turns out when you name a variable the same thing as a class bad things can happen.

Maybe it's my lack of knowledge of VB here, but which variable is named the same as a class? I see the FtpWebResponse class and the 'response' variable name in that code.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

wilderthanmild posted:

Basically, with the tab control's visualization, DataGrids can be a nightmare.

In my experience, DataGrids are more trouble than they're worth in most cases, maybe to the point of them being an obsolete holdover from WinForms. The fact that the ListView control has a built-in GridView style that's much easier to work with and customize supports my theory.

Maybe it's just there to support binding to a DataTable, but again, I think that's the old way of doing things.

wilderthanmild posted:

Using WPF I have a ListBox with its ItemSource bound to an ObservableCollection. I have a DataTemplate inside of that ListBox containing a few Buttons, TextBoxes, Checkboxes, etc. What my users want is to be able to press up or down on the keyboard and end up on the same control in the previous or next item in the listbox.

How could I accomplish this?

Edit: Come to think of it, you may be able to accomplish what you want by using a ListView configured as a GridView, rather than using a ListBox. I THINK that the default behavior of navigating between records in a GridView is to keep the focus on the same column, but I haven't used one recently enough to be sure.

Edit the second: http://www.wpf-tutorial.com/listview-control/listview-with-gridview/ <-- Quick tutorial about it

Che Delilas fucked around with this message at 21:38 on Apr 15, 2015

Che Delilas
Nov 23, 2009
FREE TIBET WEED
Their example code doesn't include a lot of using blocks does it?

Che Delilas
Nov 23, 2009
FREE TIBET WEED

GrumpyDoctor posted:

Another tip I just received: You can use using blocks to automatically call Dispose for you! But you have to make sure the object isn't needed anymore! :pseudo:

"You mean I have to make sure the object isn't needed outside of the scope in which it was instantiated? Teach me more about this crazy language, Programmer-Sempai!"

Che Delilas
Nov 23, 2009
FREE TIBET WEED

MachinTrucChose posted:

Can I get some advice from more experienced Windows devs? I'd like to have a desktop app that can search a specific directory for files, using filename as well as file contents (then I do something with the result the user selects). The target directory is on a network drive, and the files are a mix of text, XML, and Office files.

Lucene.Net (that's a library, not a website URL) is probably your best bet if you want to do custom things (solr is built upon the original Java version of this). Haven't used it myself though, so I can't tell you how arcane it is.

Che Delilas
Nov 23, 2009
FREE TIBET WEED
The company I work for runs an ASP.NET webforms application. It is having performance issues due to how we have grown and the number (and way) it talks to other devices. I have been tasked with attempting to make some of the more painful, I/O-bound calls asynchronous, because we're spending a lot of time waiting for responses from remote services that could be spent servicing other web requests.

I am posting here to ask the veterans to sanity check my assumptions and conclusions after the bit of research I have done.

First, the important fact: This application currently targets .NET Framework 4.0.

What I think I know:

- There is no way to make ASP.NET work with the async/await in framework version 4.0. Not even with the Bcl.Async library.
- Pre-4.5, the task-based asynchronous pattern does not really exist; any "asynchronous" programming is achieved through the use of additional threads.
- The thread pool will not help, since the point is to free up pool threads for web requests, therefore I can't use Tasks.

What I think my options are:

- Convince everyone to retarget the project to framework version 4.5 or higher.
- Attempt to handle threading manually

So, to the vets out there: are my assumptions correct? Do I have any other options than what I've outlined? I frankly don't think it's going to be all that terribly painful to get our code targeted to 4.5. The people who have been at the company a while are not thrilled about the idea though, because the last time they retargeted it was to go from like 2.0 to 4.0, and it was a nightmare.

I really, really don't want to attempt that second option if I don't have to; I'm completely green when it comes to threading, and everything I've read says that it's very difficult to get right. We may have a greybeard or two at the company that can do it, but I know they're busy on more urgent, more important, more customer-facing problems and features than this. Besides that, our codebase is old and rusty enough that I'd really rather do this the "right" way (it's I/O bound work, it's made for the TAP) rather than incur more technical debt.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Funking Giblet posted:

Are any of the async tasks fire and forget? Or can you defer the response via a websocket or something? Using an ESB might help.

For the most part, the tasks are not fire and forget - they are a linear sequence of calls through several layers with potentially a lot of waiting for I/O between some of them. Websockets and ESBs are nothing I've ever worked with, but I'll look into them.

Gul Banana posted:

iirc async model binding for webforms specifically is being introduced in 4.6 - final release July 29
if your issues are on the backend you might not particularly need the binding to be async, though

I don't need the model binding; from what I've read I can wire up webforms pages to use async methods using RegisterAsyncTask in 4.5 and it will accomplish what I want.

Bognar posted:

Re-targeting to 4.5 is essentially painless. You should have probably done this already.

EDIT: Here is a list of breaking changes - https://msdn.microsoft.com/en-us/library/hh367887%28v=vs.110%29.aspx

Yeah, I combed through that link yesterday and so far I've only found one thing in there that our code actually uses (and I don't think it uses it in a way that will break). Good to hear some corroboration.

Thanks for the responses guys, they're a big help.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Mr Shiny Pants posted:

For this I usually use "go to definition (F12)." I don't think it is as powerful as R#'s " go to implementation" though.

When you use the vanilla F12, it takes you to the definition that the context you're working in sees. So if you use a lot of DI and code against interfaces most of the time, F12 is going to take you to the method declaration in the interface, which is probably not what you want.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Mr Shiny Pants posted:

This happens frequently....

And if it doesn't, you aren't learning enough.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Ciaphas posted:

ReSharper, I vaguely remember the dev team I'm helping was working on getting that, I think. I'll have to look at what it is, I've never heard of it, but if it helps me deal with bullshit boilerplate like that Equals stuff (thanks for that by the way) I'm all for it :v:

I hate Resharper every time I type a period and continue typing and it lags JUST long enough for Intellisense to not kick in at all for the remainder of the symbol unless I go back and type the period again.

But I love Resharper every time I ctrl-t.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Ciaphas posted:

I hope no one minds if I try a slightly different tack to try to get this squared in my head.

The code in my post at the top of the page, aside from the elisions in the <Window> tag, does exactly what I want for the purposes of understanding what's up. I can edit the values in the TextBoxes, and see the corresponding entry in the ListBox update as I type, because the back-end SelectedModel is having its properties updated.
  • What would I change to make this program work exactly the same way, without binding directly to the selected model object's properties from the view (i.e. if I was not allowed to bind to SelectedModel.A or SelectedModel.B from the view)? In other words, how would I remove all knowledge of the Model's exact contents from the View? (I'm aware that I'd still, effectively, have to edit an A and B property in the ViewModel, but that's still not the same as directly editing the Model. I just don't know how to do up these proxy properties such that everything else appears to be updated automatically.)
  • Would I even ever want to do this from an MVVM purist point of view or am I totally up the wrong tree? (Normally I don't give a poo poo about being completely purist about anything, but I need to know the rules before I can confidently break them.)
(edit) I'm really sorry for being annoying about this, I know I'm getting more frustrated than this poo poo is frankly worth. :(

(edit again: wait, I just realized, how is the binding in the ListView being notified that its bound values--SelectedModel.A and B--have been changed when Model doesn't implement INPC huglaghlaghgahg im so lost:cry:)

The short answer to your first question is that you create intermediary classes (with INPC on them) for the ViewModel to data bind with the View. These intermediary classes will contain only the data from the Model that the View needs for UI purposes. When INPC fires on any of this stuff, the ViewModel will then call any methods on the Model that need to be called, whether that just be the Setters to update the Model, or something more complex.

Would you ever want to do this? Sure. But I will call your attention to Bognar's post:

Bognar posted:

I think we all have a different idea of what "Model" means. My interpretation of MVVM is:

View: XAML and code-behind (limited use of code-behind, really onlyfor handling specific events)
ViewModel: The in-code representation of your UI, i.e. all data and interaction but no presentation
Model: Every single other part of your application not view-related

All UI related things happen through the View and ViewModel. The Model is, collectively, your services and repositories and caches and whatever the hell else makes your application do actual stuff.

In your example, you've got a very, very simple class with some data that the View needs, and you're calling it the Model. That's okay, most MVVM tutorials and discussion does this for the sake of focusing on the MVVM pattern. But in the real world, your "Model" is not just a bunch of simple data containers; it's all the business rules and logic and database access and web service calls and math that your application does. The View/ViewModel are just the means for your users to interact with all of it. In this world, what you called your Model class would probably be what I called the intermediary class, and the ViewModel would be responsible for instantiating it (probably after calling a bunch of other methods in other classes to get the data it needs to construct that Model object in the first place).

But if all there is to your model is an in-memory collection of POCO objects, there's no real reason not to just slap INPC on your "Model" class and data bind directly. You don't need to add a layer of complexity (intermediate classes) for no reason.

Che Delilas
Nov 23, 2009
FREE TIBET WEED

Ciaphas posted:

Got another one.

XML code:
<!-- datacontext is my VM-->
<!--works the same with default UpdateSourceTrigger, just easier to see-->
<TextBox Text="{Binding MyValue.Value, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="{Binding MyValue.Value}"/>
C# code:
class VM
{
  public VM() { MyValue = new MyValueClass(); }
  public MyValueClass MyValue {get; set;}
}
class MyValueClass
{
  public string Value {get; set;}
}
MyValue's class doesn't implement INPC, and MyValue.Value isn't a dependency property. Despite this, the TextBlock is updating as I type in the TextBox. How is it getting the notification to update?

(ed) Is the compiler just somehow realizing "these two elements are bound to the same drat value, let's just bind them to each other instead" or something?

http://stackoverflow.com/questions/7767218/why-does-the-binding-update-without-implementing-inotifypropertychanged

Short answer: It does bind to something automatically, under specific conditions, and it takes more resources to do it. If want those properties to update, it behooves you to put INPC on them.

Adbot
ADBOT LOVES YOU

Che Delilas
Nov 23, 2009
FREE TIBET WEED

GrumpyDoctor posted:

I'm trying to implement basic validation on some cells in a WPF DataGrid, and I'm having trouble. To start I'm just trying to get the straightforward default red box around a cell if the user enters a non-numeric value in a field that needs to be numeric, but the red box isn't showing up. My reading of How to: Implement Validation with the DataGrid Control seems to be that all I need to do is define the DataGrid column like <DataGridTextColumn Header="Value" Binding="{Binding Value, ValidatesOnDataErrors=True}" />, but it's not working. Googling this is really hard because apparently the problem most people have is that they want to get rid of the red box, not figure out why it's missing.

I know that the setter is failing when the input is wrong - I can see the correct exception being thrown when I have a debugger attached, and when there's invalid cell contents, you can't edit any other cell.

I don't have a specific answer for you, but if you continue to have problems with the DataGrid control, consider using a ListView with its built-in GridView style instead. I'm pretty sure DataGrid is a holdover from the old style of data binding (binding a control directly to an ADO DataTable/DataSet so as to allow users to directly read and update database values :gonk:) and when I was working with WPF/MVVM I had no end of problems getting it to look and behave the way I wanted. I found the listview much easier to work with and customize.

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